紧急适配!Android 联系人权限重构,READ_CONTACTS 全面废弃

本文同步自微信公众号 "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 是怎么处理联系人权限的?评论区聊聊你的方案!

相关推荐
墨天梦1 小时前
B16_Material主题与可访问交互
android·kotlin·交互
弯_弯1 小时前
企业知识库 RAG 落地:从 Demo 到生产,四条工程链路与参数级自查
android·java·javascript
晚风叙码3 小时前
MySQL 表的约束详解:从空属性到外键
android·数据库·mysql·adb
alexhilton13 小时前
模块化Jetpack Compose架构
android·kotlin·android jetpack
厮年断弦15 小时前
AI 辅助开发实录:一周做完一个 Android 本地音乐播放器,这些坑替你踩了
android
hai_android15 小时前
InputStage 责任链核心执行流程
android·android studio·android jetpack
mmsx18 小时前
Android 测绘计算工程化:七四参数、高程拟合与单位系统
android·kotlin
我是场20 小时前
我的NPI项目之-Touch的EE特性
android·arm开发
天空之城--20 小时前
Android一周动态:AI编程、Compose与车载生态新信号
android·flutter
恋猫de小郭21 小时前
Dart 4.0 要彻底移除 dart:mirrors,Augmentations 应该要来了
android·前端·flutter