Android 12 应用兼容性适配指导

一、兼容性调试工具
Android 11开始引入了新的工具,可针对Android新平台中的行为变更进行测试和调试。这些工具是兼容性框架的一部分,该框架使得开发者可通过开发者选项或adb命令单独打开和关闭各项变更。藉此,可在最新android预览版中测试我们的app受到新平台及target api调整的影响,完成app对新平台的兼容适配。

使用adb命令打开或关闭变更,请运行以下命令之一:

adb shell am compat enable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

adb shell am compat disable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

可使用以下命令重置变更为默认状态,移除通过adb或开发者选项设置的覆盖更改:

adb shell am compat reset (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

具体说明及使用方法见:

https://developer.android.google.cn/guide/app-compatibility/test-debug

*注意:每当使用开发者选项或adb命令切换应用变更时,应用都会被杀死,以确保覆盖立即生效。

由于切换变更的开启或关闭可能导致应用崩溃或禁用重要的安全变更,为防止恶意使用兼容性框架,在何时切换变更会存在一些限制。是否可以切换变更,取决于变更的类型,应用是否可调试(app:debuggable)以及设备上运行的版本类型。

下表是限制情况:

二、行为变更
2.1、更安全的组件输出
1)背景

以Android 12为目标平台的应用(target API 级别31),如果包含用 intent filters 修饰的activities,services,broadcast receivers,则必须为这些应用组件显式声明android:exported属性,表明是否支持其它应用调用当前组件。

谷歌官网特性介绍:

https://developer.android.com/about/versions/12/behavior-changes-12#exported

2)兼容性影响

如果您的应用包含使用intent filter但未声明android:exported的Activity,Service,broadcast receiver,开发过程中会提示以下警告消息,具体取决于您使用的Android Studio版本:

Android Studio 2020.3.1 Canary 11或更高版本

清单文件中将出现以下警告:

When using intent filters, please specify android:exported as well

当您尝试编译应用程序时,会生成以下错误消息:

Manifest merger failed : Apps targeting Android 12 and higher are required \

to specify an explicit value for android:exported when the corresponding \

component has an intent filter defined.

旧版Android Studio

如果您尝试安装该应用程序,Logcat将显示以下错误消息:

Installation did not succeed.

The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE

List of apks:

[0] ‘…/build/outputs/apk/debug/app-debug.apk’

Installation failed due to: ‘null’

3)适配指导

以下代码段显示了一个包含intent filter且已针对Android 12正确配置的service示例,其余组件应该按照同样规则进行配置:

2.2、Notification trampolines 限制
1)背景

当用户与通知交互时,某些应用程序会通过启动应用程序组件来响应通知点击,该组件最终会启动用户最终看到并与之交互的Activity。 此应用程序组件称为通知中介。

为了提高应用程序性能和用户体验,面向Android 12的应用程序无法从用作通知中介的服务或广播接收器启动Activity。

2)兼容性影响

如果应用Target API 级别是31或者更高,应用尝试从充当通知中介的服务或广播接收器启动Activity时,系统将阻止该Activity启动,并且在Logcat中显示以下消息:

Indirect notification activity start (trampoline) from PACKAGE_NAME, \

this should be avoided for performance reasons.

3)适配指导

如果您的应用从充当通知中介的服务或广播接收器启动Activity,请完成以下迁移步骤:

1 创建与用户点击通知后看到的Activity相关联的PendingIntent对象

2 将第一步创建的PendingIntent对象用作构建通知的一部分

另外,如何识别一个组件是通知中介,测试方法见:

https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampolines

2.3、ACTION_CLOSE_SYSTEM_DIALOGS 弃用
1)背景

为了在应用程序和系统进行交互时,改善用户控制体验,从Android 12开始弃用ACTION_CLOSE_SYSTEM_DIALOGSintent的操作。

2)兼容性影响

当应用尝试调用包含此操作的intent时,系统会根据应用的目标SDK版本执行以下操作 :

如果应用的targetSdk版本是针对Android 12的,则会抛出SecurityException;

如果应用的targetSdk版本是针对Android 11(API级别为30)或者更低版本的,该intent不会执行,但会在logcat中显示如下信息:

E ActivityTaskManager Permission Denial: \

android.intent.action.CLOSE_SYSTEM_DIALOGS broadcast from \

com.package.name requires

android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, \

dropping broadcast.

3)适配指导

对于使用ACTION_CLOSE_SYSTEM_DIALOGS广播的app应该注意该变更。 platform app可配置以下权限,进行豁免:

Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS

另外,有极少数情景,应用仍然可以在android 12上关闭系统弹框,详情见:

https://developer.android.com/about/versions/12/behavior-changes-all#close-system-dialogs

2.4、Foreground service 启动限制
1)背景

为完善隐私保护,加强安全功能,android 12对后台应用有进一步的限制。除少数特殊情况外,针对Android 12的应用程序,无法在后台运行时启动前台服务。

参考Google官网:

https://developer.android.com/about/versions/12/foreground-services#cases-fgs-background-starts-allowed

2)兼容性影响

如果应用的targetSdk版本是针对Android 12的,应用处于后台,除开特殊情况外,调用startForegroundService,系统将引发IllegalStateException。

以下情况,即使您的应用程序在后台运行,您的应用程序也可以启动前台服务。详情见

https://developer.android.com/about/versions/12/foreground-services#cases-fgs-background-starts-allowed

3)适配指导

如果您的应用受此更改影响,建议您迁移到使用WorkManager。Android 12 beta版发布时,WorkManager将成为启动优先级更高的后台任务的推荐解决方案。

从WorkManager 2.7.0开始,您的应用程序可以调用setExpedited()来声明Worker应该使用expedited job。当在Android 12上运行时,此新API会用于加急任务,并且该API使用Android早期版本上的前台服务以提供向后兼容性。

为了促进开发人员在他们的应用程序中请求加急任务时保持谨慎,并支持耗时任务的运行能力,不建议使用CoroutineWorker.setForeground()和ListenableWorker.setForegroundAsync()方法。特别是,在运行Android 12的设备上,尝试调用ListenableWorker.setForegroundAsync()会导致IllegalStateException。建议开发人员改用setExpedited()替代。

要查看有关WorkManager 2.7.0如何使用加急任务的完整示例,请查看GitHub上的 WorkManagerSample。

Platfom app也可以使用如下权限对此特性规避:

2.5、PendingIntent mutability
1)背景

如果您的应用程序以Android 12为目标平台,则必须指定应用创建的每个PendingIntent对象的可变性。此附加要求可提高应用程序的安全性。

2)兼容性影响

如果您的应用尝试在未设置任何可变性标志的情况下创建PendingIntent对象,则系统将引发IllegalArgumentException,并且在Logcat中显示以下消息:

PACKAGE_NAME: Targeting S+ (version 10000 and above) requires that one of \

FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \

some functionality depends on the PendingIntent being mutable, e.g. if \

it needs to be used with inline replies or bubbles.

3)适配指导
需要声明给定的PendingIntent对象是可变的或不可变的,请分别使用PendingIntent.FLAG_MUTABLE 或者PendingIntent.FLAG_IMMUTABLE标志

该变更详情见官网:

https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability

2.6、PackageManager setInstallerPackageName(…) 权限需求
1)背景

PackageManager中存在一个接口setInstallerPackageName(@NonNull String targetPackage, @Nullable String installerPackageName),用于修改目标应用包的安装渠道。

如果应用程序目标平台是Android 11及以上,当targetPackage的installer package 还未进行设定时,调用此接口,必须要求调用方拥有INSTALL_PACKAGES permission权限。

2)兼容性影响

该情境如果权限不满足,系统会根据应用的目标SDK版本执行以下操作 :

如果应用的targetSdk版本是针对Android 11及以上,则会抛出SecurityException;

如果应用的targetSdk版本是针对Android 10(API级别为29)或者更低版本,则以静默方式失败。

3)适配指导
为保证setInstallerPackageName(…)接口的功能正常,需要在应用程序AndroidManifest.xml文件中配置INSTALL_PACKAGES permission:

*注意,该权限仅支持system app使用。

2.7、GpsStatus API限制
1)背景

GPS是英文Global Positioning System(全球定位系统)的简称。GNSS全球导航卫星系统(Global Navigation Satellite System),它是泛指所有的卫星导航系统,包括全球的、区域的和增强的。Android 7.0 以后官方推荐使用GNSS。

目标平台是Android 12及以上的应用程序,所用到的GpsStatus API必须要用GnssStates API替换。

2)兼容性影响

需要进行替换的public GpsStatus API接口如下,否则系统会引发异常,导致应用程序崩溃。

getGpsStatus(GpsStatus status)

addGpsStatusListener(GpsStatus.Listener listener)

removeGpsStatusListener(GpsStatus.Listenerlistener)

3)适配指导

如果应用的targetSdk版本是针对Android 12及以上,为保证功能的正常,请使用GnssStatus.Callback对GpsStatus.Listener进行替代:

registerGnssStatusCallback(android.location.GnssStatus.Callback)

unregisterGnssStatusCallback(android.location.GnssStatus.Callback)

可根据应用功能需求,选择合适API进行替换,详情请参考:

https://developer.android.com/reference/android/location/LocationManager

调用样例如下:

记得不要遗忘反注册:

2.8、PendingIntent.FLAG_IMMUTABLE与Location API冲突
1)背景

以Android 12为目标平台的应用(target API 级别31),固定不变的PendingIn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值