前言
系统行为变更通常属于以下两种类别之一:
- 面对所有应用的行为变更: 运行在该系统版本上的所有应用都会影响,而无论应用的targetSDKVersion为何。通常应该先针对这些变更进行适配和测试,这有助于用户在新版本系统上运行你的应用时,用户体验不会受损。
- 以特定targetSDKVersion为目标版本的行为变更: 只有targetSDKVersion高于或等于系统版本的应用会受影响,通常是影响较大或适配工作量较大的变更,我们可以理解为 Google留给开发者的适配缓冲。
影响所有App的行为变更
1.应用启动画面
从Android 12 系统开始,所有应用的冷启动和温启动期间,系统会使用新的 SplashScreen API 来启动应用启动动画。
(1)应用图标:应该是矢量可绘制对象,它可以是静态或动画形式。虽然动画的时长可以不受限制,但建议不超过1000毫秒。默认情况下,使用启动器图标。
(2)图标背景:可选,在图标与窗口背景之间需要更高的对比度时图标背景很有用。
(3)前景遮罩:可选,前景的三分之一被遮盖。
(4)窗口背景:由不透明单色组成。如果窗口背景已设置且为纯色,则未设置相应的属性时默认使用该背景。
在SplashScreen API之前,我们通常是利用 SplashActivity 的背景图 android:windowBackground
来实现应用启动转场效果,这个大家都很熟悉了。如果你不做任何适配,那么根据你配置的 windowBackground 资源值,在 Android 12 上会有不同的效果:
- windowBackground 采用
@color/单色
,则系统会使用该单色和应用的启动图标来构成启动效果,这可能与预期效果不符。 - windowBackground 采用
@drawable/图片
,则系统会继续使用该图片来构成启动效果,这个体验与低版本系统一致。
因此,如果你的应用采用的是 windowBackground 为图片资源的方式,那么你不适配也没有问题。需要升级启动效果的话,推荐参考一下资料: - 启动画面 — — Android官方文档
- Jetpack新成员SplashScreen:打造全新的App启动画面 — — TechMerger
2.麦克风和摄像头切换开关
从Android 12开始,用户可以通过状态栏下拉菜单中两个新增的切换开关选项,一键启用/停用摄像头和麦克风使用权限。
这里的「使用权限」针对的是设备上的所有App,是全局的,不要和Android 6.0的「运行时权限」混淆。
如果用户主动关闭了摄像头或麦克风的使用权限,那么当下次App再需要启动摄像头或麦克风时,系统就会提醒用户,
相关硬件的使用权限已关闭,并申请重新开启。
3.activity生命周期改进
Android 12修改了 Android Task根 Activity在处理”返回键“时的默认行为。在旧版本中,返回键会执行 finish activity,而从 Android 12开始会将 Task 任务栈切换到后台。此后,用户返回应用将执行温启动,应用的温启动简单的多,系统的工作只是将activity 恢复到前台。
影响目标API级别为Android 12 的App的行为变更
1.更安全的组件导出
以Android 12为目标平台的App,如果其包含的四大组件中使用到了 intent 过滤器(intent-filter),则必须显示声明 android:exported
属性,否则App将无法在 Android 12 及更高系统版本的设备上安装。
适配方案
1.如果是自身项目使用到了,则按要求显示声明即可
2.如果是依赖的第三方库使用到了,两种解决方法:
- Android Studio Project 在打包时会合并多个Module的
AndroidManifest.xml
文件的,基于这种情况,可以通过编写 Gradle 脚本,在打包过程中检索合并后的AndroidManifest.xml
文件中,所有使用到了Intent过滤器但没有声明 exported属性的组件,动态为其加上 exported 属性。脚本地址 - 在主工程中xml拷贝相关component声明,并覆盖exported设置,例如:
android:exported="true"
tools:replace="android:exported"
2.PendingIntent可变性
以 Android 12为目标平台的App,在构建PendingIntent时,需要指定Flag为FLAG_IMMUTABLE
(建议)或FLAG_MUTABLE
二者之一,否则App将崩溃。
3.前台服务启动限制
Android 12 对应用从后台启动前台服务的行为做出限制,除了后台启动限制的豁免 等少数情况外,如果应用尝试在后台运行时启动前台服务,系统会抛出ForegroundServiceStartNotAllowedException
异常。
应用可以使用WorkManager
的加急工作来执行后台任务。
4.精确的闹钟权限
Android 12系统引入了新的权限 android.permission.SCHEDULE_EXACT_ALARM
,设置AlarmManager 精准闹钟的应用必须在 Manifest
中请求 SCHEDULE_EXACT_ALARM
权限。
新增了一个新的API — — canScheduleExactAlarms()
,用于检查应用的精准闹钟权限状态。
5.通知 trampoline 限制
通知 trampoline(蹦床)是指利用广播接收器或服务间接启动目标 Activity
(用户与通知交互后,应用先启动服务或广播接收器作为中介,再去启动 Activity )。Android 12系统对通知 trampoline 做出限制,当应用尝试从通知 trampoline启动 activity,系统会拦截该启动行为。
如果你的应用使用了通知 trampoline,那么你需要切换为常规的 PendingInternt
方式。
6.大致位置
Android系统支持两个精度级别的位置信息,并且分别对应一个权限。虽然有两个精度级别的权限,但是因为它们处于同一权限组中,所以应用只要请求授予其中一个权限,另一个权限就自动授予了。
- 粗略位置: 精确到2平方公里的位置值,请求
ACCESS_COARSE_LOCATION
权限可以获得。 - 精确位置: 精确到50米以内的位置值,请求
ACCESS_FINE_LOCATION
权限可以获得。
从Android 12 开始,用户可以只授予应用模糊位置 ACCESS_COARSE_LOCATION
权限,即使应用请求的是精确位置 ACCESS_FINE_LOCATION
权限。
7.应用休眠
Android 11引入了应用休眠机智,如果用户有几个月没有与应用交互,那么系统会将应用置于休眠/冬眠状态,Android 12扩展了应用休眠机智:
- Android 11:重置已授予的运行时敏感权限;
- Android 12:重置已授予的运行时敏感权限;无法从后台运行任务;无法接受推送通知;应用缓存文件会被删除。
8.自定义通知
从 Android 12开始,系统规范了自定义通知的外观和行为,自定义通知的内容区域缩小为自定义通知模板内的一块区域,不再完整覆盖通知区域。下图为统一的自定义通知模板:
由于所有通知都是可展开的,所以需要调用 setCustomBigContentView()
设置展开后布局,确保展开和收起状态一致。