作者: 彭旭锐
Android 13 开发者预览版从 2022 年 2 月正式启动,3 月份 Google 已经发布了第 2 个开发者预览版。目前更新的内容主要还是围绕隐私和安全这个主题,我们会持续跟进官方的 发布计划表,最终版本预计在今年年底发布。
针对开发者在进行版本适配过程中遇到的问题,我们建立了 GitHub · AndroidPlatformWiki。我们希望站在开发者的视角,全面且深刻地解读每个 Android 版本更新,以此建立起一个体系化的 Android 系统适配手册。具体包括:
根据内容相关度,我们将从 2 个维度解读:
基于时间线: 现阶段官方每年会发布一个新的版本,因此有必要以一个 Android 版本为单位,解读该版本涉及的新功能与行为变更。这样可以帮助开发同学了解新版本的更新内容,例如我们会通过一个文档解读 Android 13 版本的更新内容与适配自查表;
基于内容线: 通常一个系统功能模块会历经多个系统版本更新才会趋于稳定,因此有必要以一个功能为单位,解读该功能的主要能力以及不同版本的变更和差异。这样可以帮助开发同学了解该功能在不同版本上的差异,例如我们会通过一个文档单独解读系统通知。
根据故障敏感性分级,我们将系统变更的兼容性划分为 3 个等级:
强制适配 ❗: 所有应用必须适配,否则会出现编译不通过、功能不可用或者用户体验受损等问题;
推荐适配 ⭐: 不强制要求适配,但适配的应用将获得更出色的用户体验或更安全的隐私保护等收益;
已适配: 应用不需要任何改动就已经兼容。
系统行为变更通常属于以下两种类别之一:
面对所有应用的行为变更: 运行在该系统版本上的所有应用都会影响,而无论应用的 targetSDKVersion 为何。通常应该先针对这些变更进行适配和测试,这有助于用户在新版本系统上运行你的应用时,用户体验不会受损;
以特定 targetSDKVersion 为目标版本的行为变更: 只有 targetSDKVersion 高于或等于系统版本的应用会影响,通常是影响较大或适配工作量较大的变更,我们可以理解为一个 Google 留给开发者的适配缓冲。
第 1~3 节介绍的是以 Android 13 为目标版本的应用行为变更和新功能更新,我将这部分更新总结为 3 部分:
等待官方更新…
Android 13 系统引入了新的运行时权限 android.permission.NEARBY_WIFI_DEVICES
附近 Wi-Fi 设备权限,用于管理应用与附近 Wi-Fi 感知设备的连接。
...
在低版本中,应用与附近 Wi-Fi 设备连接需要用户授予 ACCESS_FINE_LOCATION 精确位置权限,这其实是不合理的设计,因为用户很难理解为什么 Wi-Fi 连接会跟位置信息有关。从 Android 13 系统开始,ACCESS_FINE_LOCATION 精确位置权限是可选项,只要应用不会通过 Wi-Fi 推导物理位置信息,就不需要再请求。如果不会,你需要在 Manifest 中显式做出 usesPermissionFlags
声明(这与声明蓝牙设备信息不会用于获取位置信息类似):
...
另外,NEARBY_WIFI_DEVICES 权限是 NEARBY_DEVICES 附近设备权限组的一部分。此权限组在 Android 12 中引入,还包含与蓝牙相关的权限。请求该权限组的权限,权限授予对话框会提示用户批准访问附近的设备。可以看出,这次的改动 Google 是希望连接 Wi-Fi 设备的权限授予能够给用户更精准的权限功能描述。
Android 13 系统引入了新的运行时权限 android.permission.BODY_SENSORS_BACKGROUND
后台身体传感器权限,用于更好地管理应用在后台时访问身体传感器(例如心率、体温和血氧饱和度等)的行为。现在应用在后台使用身体传感器,除了要请求现有的 BODY_SENSORS 权限外,还需要请求 BODY_SENSORS_BACKGROUND 权限(这与 ACCESS_FINE_LOCATION 和 ACCESS_BACKGROUND_LOCATION 的关系类似)。
当您的应用向以 Android 13 或更高版本为目标平台的其他应用的导出组件发送 Intent 时,仅当该 Intent 与接收应用中的
元素匹配时,系统才会传送该 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 13 开始,系统开始支持应用级别的语言偏好设置,可以在系统设置中针对每个应用设置,也可以在运行时使用以下 API 设置:
平台 API:LocaleManager#setApplicationLocales
兼容库 API:AppCompatDelegate#setApplicationLocales
改进日语文本换行: 从 Android 13 系统开始,可以通过为 TextView 设置 android:lineBreakWordStyle=“phrase” 来改进日语文本的换行效果。TextView 会按照 Bunsetsu(最小自然语素单元)或短语,而不是单个字符来进行文本换行。例如,下图是启用了短语样式的日语文本换行(下方)和未启用短语样式的日语文本换行(上方)。
Android 8 系统中引入了自适应图标,可以在不同厂商设备的 Launcher 上显示不同形状的应用图标。如果说 Android 8 的图标是自适应形状的应用图标,那么 Android 13 就是在此基础上再推出了自适应主题的应用图标。用户可以调节 Launcher 中的主题色调,应用图标颜色会自适应调整配色。要支持此功能,应用必须在原有的自适应图标上增加一张单色图标,例如:
res/mipmap-anydpi-v26/ic_launcher.xml
在 Manifest 文件中引用该图标,例如:
Android 13 系统引入了新的运行时权限 —— android.permission.POST_NOTIFICATION
通知权限,用于管理应用发送系统通知的能力。如果用户拒绝授予权限,则应用的所有通知渠道(Channel)都会被屏蔽,这类似于用户在系统设置中手动关闭应用通知后发生的行为。可以看出,这次的改动 Google 是希望加强对应用通知行为的管理,现在每个新安装的应用都会发一大堆通知,造成通知栏总是被一堆不重要的消息占满,用户只能一个个去关闭通知开关。
...
与其他运行时权限请求类似,请求通知权限也应该遵循最小必要原则。建议是在合适的业务流程节点或者用户体验峰值再请求,以便用户明确了解接收通知能带来的好处。例如:
提示: 通过调用 areNotificationsEnabled()[7],可以判断用户是否已打开应用的通知开关。
为了降低新权限的影响,从低版本升级到 Android 13 的设备上已安装的应用,系统会临时授予通知权限,前提是该应用本身是有通知的资格的:应用具有通知渠道,并且用户在低版本时并未关闭该应用的通知开关。
相关资料:
从 Android 13 系统开始,应用可以主动撤销用户已授予的运行时权限,这能够在不再需要权限后更好地保护用户隐私。通过调用 revokeOwnPermissionsOnKill() 可以撤销特定的权限或权限组。另外,撤销前台权限时,其对应的后台权限也会被撤销(例如 BODY_SENSORS & BODY_SENSORS_BACKGROUND)。
Android 13 系统引入了新的 照片选择器功能,允许用户只向应用提供特定选择的图片或视频,而不是像旧版本那样直接授予整个媒体库的访问权限,这个功能与 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()
。
相关资料:照片选择器
Android 13 系统引入了前台服务 FGS 管理器功能,它会显示当前正在运行前台服务的应用列表,并且每个应用旁边都有一个 “停止” 按钮。当用户点击 “停止” 按钮时,系统不仅会关闭该前台服务,还会停止整个应用。例如:
可以看出,这次改动 Google 是希望提高用户对前台服务的控制性。在旧版本的前台服务并没有直接的停止按钮,只有一些些友好的应用会在前台服务通知中使用可操作性的关闭按钮。
相关资料:[前台服务 (FGS) 任务管理器](https://developer.android.google.cn/about/versions/13/changes/fgs-manager “前台服务 (FGS “前台服务 (FGS) 任务管理器”) 任务管理器”)
JobScheduler 预提取作业是 Android 9 引入的机制,通过调用JobInfo.Builder.setPrefetch 能够将该作业标记为 “预提取” 作业,理想情况下,开发者的预期是该作业应该在应用下一次启动前一点运行,以提升用户体验。
在旧版本中,系统只会在有充足的过剩资源时,才会允许预提取作业运行。从 Android 13 开始,系统会更智能地基于机器学习预测应用下次启动的时间,并根据该估算值执行预提取作业。此外,预提取任务也不再允许设置最后执行期限 setOverrideDeadline(long)。
Android 13 系统引入了一些新的电池省电措施,以便为系统提供更多方法来管理电池续航时间。
相关资料:电池资源利用率
目前 Android 13 版本还处于开发者预览阶段,预计年底才会正式发布。关注我,带你了解更多,我们下次见。
以下变更相对冷门,实用价值较低,本文暂且按住不表: