紧急适配!Android 联系人权限重构,READ_CONTACTS 全面废弃
你的 App 还在用READ_CONTACTS读取用户的整个通讯录从 Android 17 开始这条路要走不通了。Google 推出了全新的 Contact Picker用户只分享自己选择的联系人而不是交出整本通讯录。这不是一个小改动。它意味着 Android 持续多年的联系人权限模型被彻底重构——从「要么全给要么不给」变成了「用户说了算给多少由我决定」。老模型到底有什么问题READ_CONTACTS的问题很直接它是全量权限。一个社交 App 可能只需要读取几个朋友的手机号来发送邀请但READ_CONTACTS一授权App 就能读取通讯录里的所有联系人——姓名、电话、邮箱、公司、生日、备注一个不漏。更要命的是这个权限一旦授予就是持久的。App 可以在后台反复读取用户根本不知道自己的通讯录数据已经被扒走了多少次。这个模型在功能手机时代可能没问题但在隐私意识日益增强的今天它已经不合时宜了。iOS 很早就做了联系人选择器Android 一直没有标准化的方案。直到 Android 17。Contact Picker 怎么工作新方案的核心思路App 不再直接访问通讯录而是让系统弹出一个标准的联系人选择界面由用户自己挑选要分享的联系人。整个流程是这样的App 发起请求→ 系统弹出联系人选择器 → 用户搜索并选择联系人 → 系统返回临时 URI → App 通过 URI 读取选中的数据。关键点在于按需请求字段。App 可以声明自己只需要邮箱、或者只需要电话号码而不是整条联系人记录。系统只会返回请求的字段多余的数据用户看不到App 也拿不到。Session URI 临时访问。返回的不是永久的联系人 ID而是一个有时效的 Session URI。App 必须在有限时间内读取数据之后 URI 就会失效。没有持久化的通讯录访问权限。跨配置文件支持。选择器能展示来自工作配置、克隆空间、私密空间等多个配置文件的联系人用户不需要切换账号。代码怎么写实现起来并不复杂。核心是用ACTION_PICK_CONTACTSIntent 配合几个 Extra 参数。发起选择器的关键参数• xxSELECTION_LIMIT限制用户最多能选几个联系人• xxDATA_FIELDS声明需要哪些字段邮箱、电话等• xxDATA_FIELDS设置过滤逻辑是否要求联系人同时拥有所有请求字段选择器返回结果后通过ContentResolver查询 Session URI 即可获取联系人数据。这里有个设计亮点系统返回的是一个聚合 URI一次查询就能拿到所有选中联系人的数据而不需要逐条查询减少了系统开销。迁移成本有多大好消息是几乎零成本。如果你的 App 之前用的是ACTION_PICKIntent 来选择联系人在 Android 17 上系统会自动升级到新的 Contact Picker不需要改代码。但如果你想用上多选、字段过滤等高级功能就需要主动迁移到ACTION_PICK_CONTACTS。建议的迁移策略第一步把READ_CONTACTS权限从你的AndroidManifest.xml中移除如果你只是用来做联系人选择的话。第二步将 Intent action 替换为ACTION_PICK_CONTACTS并添加所需的 Extra 参数。第三步处理返回的 Session URI。注意要及时持久化你需要的数据因为 URI 会过期。开发者需要注意的坑Session URI 有时效。这是最容易踩的坑。返回的 URI 不是永久有效的如果你的 App 在用户选择后过了很久才去读取可能会读不到数据。最佳实践是在onActivityResult中立即查询并保存。数据最小化原则。不要请求你不需要的字段。一方面这是 Google 推荐的做法另一方面用户在选择器界面能看到 App 请求了哪些数据——请求过多会降低用户信任。向后兼容。Contact Picker 是 Android 17 的功能低版本设备上不可用。你需要做版本判断在低版本上 fallback 到旧的READ_CONTACTS方案。这意味着什么Contact Picker 不是一个孤立的功能更新。它是 Android 隐私策略的又一次升级和 Photo Picker照片选择器、Storage Access Framework存储访问框架一脉相承——把数据的控制权从 App 交还给用户。之前是App 要权限 → 用户授权 → App 随便用。现在是App 说需求 → 用户自己选 → 给多少 App 拿多少。这个趋势不可逆。作为开发者越早适配越主动。写在最后联系人数据是用户最敏感的隐私之一。Android 17 的 Contact Picker 用一种简洁优雅的方式解决了「全量授权」的老问题——App 能拿到需要的数据用户不用交出整本通讯录。如果你的 App 还在用READ_CONTACTS是时候考虑迁移了。你的 App 是怎么处理联系人权限的评论区聊聊你的方案[#Android开发](javascript: [#Android17](javascript: [#隐私安全](javascript: [#ContactPicker](javascript: