Android 13 开发者预览版从 2022 年 2 月正式启动,3 月份 Google 已经发布了第 2 个开发者预览版。目前更新的内容主要还是围绕隐私和安全这个主题,我们会持续跟进官方的 发布计划表[1],最终版本预计在今年年底发布。
针对开发者在进行版本适配过程中遇到的问题,我们建立了 GitHub · AndroidPlatformWiki[3]。我们希望站在开发者的视角,全面且深刻地解读每个 Android 版本更新,以此建立起一个体系化的 Android 系统适配手册。具体包括:
根据内容相关度,我们将从 2 个维度解读:
根据故障敏感性分级,我们将系统变更的兼容性划分为 3 个等级:
系统行为变更通常属于以下两种类别之一:
类别 | 变更 | 兼容性 | 摘要 |
|---|---|---|---|
1. 用户体验 | 等待官方更新...... | / | / |
2. 安全和隐私设置 | 附近 Wi-Fi 设备运行时权限(新) | 推荐 ⭐ | 引入了新运行时权限,可使应用扫描附近的 Wi-Fi 感知设备,而无需请求位置信息权限 |
后台访问身体传感器运行时权限(新) | 强制 ❗ | 引入了新的运行时权限,用于更好地管理应用在后台时访问身体传感器的行为 | |
IntentFilter 会屏蔽不匹配的 Intent | 已适配 | 当该 Intent 与接收应用中的 匹配时,系统才会传送该 Intent | |
更安全地动态注册广播接收器 | 强制 ❗ | 应用必须明确指出动态注册的广播接收器是否接收其他应用的广播 | |
3. 性能和电池 | 等待更新... | / | / |
类别 | 变更 | 兼容性 | 描述 |
|---|---|---|---|
4. 用户体验 | 多语言支持改进(新) | 推荐 ⭐ | 引入了一系列新的语言特性优化,用于改善多语言用户体验 |
自适应主题的应用图标(新) | 推荐 ⭐ | 应用图标颜色可以自适应 Launcher 主题色调调整配色。 | |
5. 安全和隐私设置 | 通知运行时权限(新) | 强制 ❗ | 引入了新的运行时权限,用于管理应用发送系统通知的能力 |
可降级权限(新) | 推荐 ⭐ | 应用可以主动撤销用户已授予的运行时权限 | |
照片选择器(新) | 推荐 ⭐ | 用户可以只向应用提供特定选择的图片或视频,而不是直接授予整个媒体库的访问权限 | |
6. 性能和电池 | 前台服务 FGS 管理器(新) | 已适配 | 引入了前台服务 FGS 管理器功能,可以直接关闭服务和应用 |
JobScheduler 预提取作业优化 | 已适配 | 系统会更智能地基于机器学习预测应用下次启动的时间,并根据该估算值执行预提取作业 | |
省电措施改进 | 已适配 | 引入了新的电池省电措施,以便为系统提供更多方法来管理电池续航时间 |
第 1~3 节介绍的是以 Android 13 为目标版本的应用行为变更和新功能更新,我将这部分更新总结为 3 部分:
等待官方更新......
Android 13 系统引入了新的运行时权限 android.permission.NEARBY_WIFI_DEVICES 附近 Wi-Fi 设备权限,用于管理应用与附近 Wi-Fi 感知设备的连接。
<manifest ...>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"/>
<application ...>
...
</application>
</manifest>
在低版本中,应用与附近 Wi-Fi 设备连接需要用户授予 ACCESS_FINE_LOCATION 精确位置权限,这其实是不合理的设计,因为用户很难理解为什么 Wi-Fi 连接会跟位置信息有关。从 Android 13 系统开始,ACCESS_FINE_LOCATION 精确位置权限是可选项,只要应用不会通过 Wi-Fi 推导物理位置信息,就不需要再请求。如果不会,你需要在 Manifest 中显式做出 usesPermissionFlags 声明(这与声明蓝牙设备信息不会用于获取位置信息类似):
<manifest ...>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />
<application ...>
...
</application>
</manifest>
另外,NEARBY_WIFI_DEVICES 权限是 NEARBY_DEVICES 附近设备权限组的一部分。此权限组在 Android 12 中引入,还包含与蓝牙相关的权限。请求该权限组的权限,权限授予对话框会提示用户批准访问附近的设备。可以看出,这次的改动 Google 是希望连接 Wi-Fi 设备的权限授予能够给用户更精准的权限功能描述。

相关资料:附近的 Wi-Fi 设备权限[4]
Android 13 系统引入了新的运行时权限 android.permission.BODY_SENSORS_BACKGROUND 后台身体传感器权限,用于更好地管理应用在后台时访问身体传感器(例如心率、体温和血氧饱和度等)的行为。现在应用在后台使用身体传感器,除了要请求现有的 BODY_SENSORS 权限外,还需要请求 BODY_SENSORS_BACKGROUND 权限(这与 ACCESS_FINE_LOCATION 和 ACCESS_BACKGROUND_LOCATION 的关系类似)。
当您的应用向以 Android 13 或更高版本为目标平台的其他应用的导出组件发送 Intent 时,仅当该 Intent 与接收应用中的 <intent-filter> 元素匹配时,系统才会传送该 intent。
提示: 因为我不理解这个特性的真正含义,所以这里直接复制粘贴了官方文档原话。你理解的话在评论里分享下。
在旧版本中,应用动态注册的 BroadcastReceiver 广播接收器会接收到任何应用发送的广播(除非该接收器使用了应用签名权限保护),这会让动态注册的广播接收器存在安全风险。从 Android 13 系统开始,应用动态注册的广播接收器必须显式指出是否允许其他应用访问,即其他应用是否可以向其发送广播。否则,在动态注册时系统会抛出 SecurityException。
// 这相当于静态注册 android:exported="true"
context.registerReceiver(sharedBroadcastReceiver, intentFilter, RECEIVER_EXPORTED)
// 这相当于静态注册 android:exported="false"
context.registerReceiver(privateBroadcastReceiver, intentFilter, RECEIVER_NOT_EXPORTED)
期待官方更新......
第 4~6 节介绍的是针对所有应用的应用行为变更和新功能更新,我将这部分更新总结为 3 部分:
Android 13 系统引入了一系列新的语言特性优化,用以改进多语言用户的应用体验:


Android 8 系统中引入了自适应图标,可以在不同厂商设备的 Launcher 上显示不同形状的应用图标。如果说 Android 8 的图标是自适应形状的应用图标,那么 Android 13 就是在此基础上再推出了自适应主题的应用图标。用户可以调节 Launcher 中的主题色调,应用图标颜色会自适应调整配色。要支持此功能,应用必须在原有的自适应图标上增加一张单色图标,例如:
res/mipmap-anydpi-v26/ic_launcher.xml
<adaptive-icon >
<background android:drawable="..." />
<foreground android:drawable="..." />
<monochrome android:drawable="@drawable/myicon" />
</adaptive-icon>
在 Manifest 文件中引用该图标,例如:
<application
...
android:icon="@mipmap/ic_launcher"
...>
</application>

Android 13 系统引入了新的运行时权限 —— android.permission.POST_NOTIFICATION 通知权限,用于管理应用发送系统通知的能力。如果用户拒绝授予权限,则应用的所有通知渠道(Channel)都会被屏蔽,这类似于用户在系统设置中手动关闭应用通知后发生的行为。可以看出,这次的改动 Google 是希望加强对应用通知行为的管理,现在每个新安装的应用都会发一大堆通知,造成通知栏总是被一堆不重要的消息占满,用户只能一个个去关闭通知开关。
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
与其他运行时权限请求类似,请求通知权限也应该遵循最小必要原则。建议是在合适的业务流程节点或者用户体验峰值再请求,以便用户明确了解接收通知能带来的好处。例如:

提示: 通过调用 areNotificationsEnabled()[7],可以判断用户是否已打开应用的通知开关。
为了降低新权限的影响,从低版本升级到 Android 13 的设备上已安装的应用,系统会临时授予通知权限,前提是该应用本身是有通知的资格的:应用具有通知渠道,并且用户在低版本时并未关闭该应用的通知开关。
相关资料:
从 Android 13 系统开始,应用可以主动撤销用户已授予的运行时权限,这能够在不再需要权限后更好地保护用户隐私。通过调用 revokeOwnPermissionsOnKill()[10] 可以撤销特定的权限或权限组。另外,撤销前台权限时,其对应的后台权限也会被撤销(例如 BODY_SENSORS & BODY_SENSORS_BACKGROUND)。
Android 13 系统引入了新的 照片选择器[11] 功能,允许用户只向应用提供特定选择的图片或视频,而不是像旧版本那样直接授予整个媒体库的访问权限,这个功能与 IOS 14 “仅允许应用访问部分照片” 是类似的。图片选择器可以更好地保护用户隐私,并且应用不再需要请求媒体库运行时访问权限。
请求:
val maxNumPhotosAndVideos = 10
val intent = Intent(MediaStore.ACTION_PICK_IMAGES)
// 设置获取的图片或视频最大数量
intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNumPhotosAndVideos)
startActivityForResult(intent, PHOTO_PICKER_MULTI_SELECT_REQUEST_CODE)
提示:文件数量上限的最大数字存在平台限制
MediaStore#getPickImagesMaxLimit()。

相关资料:照片选择器[12]
Android 13 系统引入了前台服务 FGS 管理器功能,它会显示当前正在运行前台服务的应用列表,并且每个应用旁边都有一个 “停止” 按钮。当用户点击 “停止” 按钮时,系统不仅会关闭该前台服务,还会停止整个应用。例如:

可以看出,这次改动 Google 是希望提高用户对前台服务的控制性。在旧版本的前台服务并没有直接的停止按钮,只有一些些友好的应用会在前台服务通知中使用可操作性的关闭按钮。
相关资料:[前台服务 (FGS) 任务管理器](https://developer.android.google.cn/about/versions/13/changes/fgs-manager "前台服务 (FGS "前台服务 (FGS) 任务管理器") 任务管理器")
JobScheduler 预提取作业是 Android 9 引入的机制,通过调用 JobInfo.Builder.setPrefetch[13] 能够将该作业标记为 “预提取” 作业,理想情况下,开发者的预期是该作业应该在应用下一次启动前一点运行,以提升用户体验。
在旧版本中,系统只会在有充足的过剩资源时,才会允许预提取作业运行。从 Android 13 开始,系统会更智能地基于机器学习预测应用下次启动的时间,并根据该估算值执行预提取作业。此外,预提取任务也不再允许设置最后执行期限 setOverrideDeadline(long)[14]。
Android 13 系统引入了一些新的电池省电措施,以便为系统提供更多方法来管理电池续航时间。
相关资料:电池资源利用率[15]
目前 Android 13 版本还处于开发者预览阶段,预计年底才会正式发布。
以下变更相对冷门,实用价值较低,本文暂且按住不表:
[1]
发布计划表: https://developer.android.google.cn/about/versions/13/overview
[2]
GitHub · Android-NoteBook: https://github.com/pengxurui/Android-NoteBook
[3]
GitHub · AndroidPlatformWiki: https://github.com/pengxurui/AndroidPlatformWiki
[4]
附近的 Wi-Fi 设备权限: https://developer.android.google.cn/about/versions/13/features/nearby-wifi-devices-permission
[5]
LocaleManager#setApplicationLocales: https://developer.android.google.cn/reference/android/app/LocaleManager#setApplicationLocales
[6]
AppCompatDelegate#setApplicationLocales: https://developer.android.google.cn/reference/androidx/appcompat/app/AppCompatDelegate#setApplicationLocales
[7]
areNotificationsEnabled(): https://developer.android.google.cn/reference/android/app/NotificationManager#areNotificationsEnabled
[8]
通知运行时权限: https://developer.android.google.cn/about/versions/13/changes/notification-permission
[9]
请求应用权限: https://developer.android.google.cn/training/permissions/requesting#handle-denial
[10]
revokeOwnPermissionsOnKill(): https://developer.android.google.cn/reference/android/content/Context#revokeOwnPermissionsonKill
[11]
照片选择器: https://developer.android.google.cn/about/versions/13/features/photopicker
[12]
照片选择器: https://developer.android.google.cn/about/versions/13/features/photopicker
[13]
JobInfo.Builder.setPrefetch: https://developer.android.google.cn/reference/android/app/job/JobInfo.Builder#setPrefetch
[14]
setOverrideDeadline(long): https://developer.android.google.cn/reference/android/app/job/JobInfo.Builder#setOverrideDeadline
[15]
电池资源利用率: https://developer.android.google.cn/about/versions/13/changes/battery#system-notification-long-running-fgs