本文同步自微信公众号 "Android技术圈"
你的 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_CONTACTS Intent 配合几个 Extra 参数。

发起选择器的关键参数:
EXTRA_PICK_CONTACTS_SELECTION_LIMIT:限制用户最多能选几个联系人EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS:声明需要哪些字段(邮箱、电话等)EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS:设置过滤逻辑,是否要求联系人同时拥有所有请求字段
选择器返回结果后,通过 ContentResolver 查询 Session URI 即可获取联系人数据。这里有个设计亮点:系统返回的是一个聚合 URI,一次查询就能拿到所有选中联系人的数据,而不需要逐条查询,减少了系统开销。
迁移成本有多大
好消息是:几乎零成本。
如果你的 App 之前用的是 ACTION_PICK Intent 来选择联系人,在 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 是怎么处理联系人权限的?评论区聊聊你的方案!