1. 前言
Android更新版本太快了,每次大版本升级,都需要关注与早期版本哪些不同点,之前的API是否过时了,是否有新特性,老的API是否还可以兼容等, Android 12 包含一些行为变更,这些变更可能会影响您的应用。以下行为变更仅影响以 Android 12 或更高版本为目标平台的应用。如果您的应用以 Android 12 为目标平台,您应该修改自己的应用以适当地支持这些行为(如果适用),本篇文章中是在工作中适配的时候记录的不同点,供参考~
2. 行为变更
2.1 组件安全
如果您的应用运行在 Android 12 或更高版本为目标平台,且包含使用 intent 过滤器的 activity、服务或广播接收器,您必须为这些应用组件显式声明 android:exported 属性。
警告:如果 activity、服务或广播接收器使用 intent 过滤器,并且未显式声明 android:exported
的值,您的应用将无法在搭载 Android 12 或更高版本的设备上进行安装。
如果在Android12上面,你没有显示申明此属性,则在编译的时候,报如下错误:
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.
清单文件中在在IDE环境下会显示以下 lint 警告:
When using intent filters, please specify android:exported as well
细节一点的说明:
1. 对于应用组件包含 Home Launcher 类别的组件,如下:
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
则一定要设置android:exported 设置为 true
比如在Android12之前AndroidManifest.xml声明的Activity组件
<activity android:name="DefaultActivity"
android:screenOrientation="locked"
android:excludeFromRecents="true">
<intent-filter android:priority="1">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" /> ---带此属性
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.SETUP_WIZARD" />
</intent-filter>
</activity>
<activity
android:name=".DeskClock"
android:label="@string/app_label"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" /> ---带此属性
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
12之前编译是没有问题的,但是在12之后就会报错,这种必须android:exported 设置为 true
2. 如果普通的Activity Service组件,如果没有任何 intent-filter过滤条件,如果不想被外部应用调用的话,则 android:exported 设置为 false 如下
<service android:name="com.example.app.backgroundService"
android:exported="false"> ----Android12上 必须要加上这句话
</service>
3. 对于在12上的组件信息,如果带有intent-filter过滤条件,在Android12平台上,系统会默认你这个组件android:exported="true", 但是你必须要显示的申明出来,否则就报错,如果你认为这个组件不被外部应用调用的话,你就可以设置为android:exported="false"
说了这么多,总结一句话:在Android12上面,每个组件必须显示地申明android:exported的值
2.2 PendingIntent
如果您的应用以 Android 12 为目标平台,您必须为应用创建的每个PendingIntent
对象指定可变性,这项额外的要求可提高应用的安全性。不然会报如下错误:
java.lang.IllegalArgumentException: Targeting S+ (version 31 and above)
requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
在使用PendingIntent的地方加上 PendingIntent.FLAG_IMMUTABLE 或者 PendingIntent.FLAG_MUTABLE 属性,左为Android12 右边为Android11 两者差异
2.3 Toast消息框重新设计
在 Android 12 中,消息框视图已经过重新设计。现在,消息框上限为两行文本,并且必须在文本旁边显示应用图标。如下图:
2.4 自定义通知
Android 12 更改了完全自定义通知的外观和行为。以前,自定义通知能够使用整个通知区域并提供自己的布局和样式。由此产生的反模式可能会令用户困惑,或在不同设备上引发布局兼容性问题。 对于以 Android 12 为目标平台的应用,包含自定义内容视图的通知将不再使用完整通知区域;相反,系统会应用标准模板。
下图显示了标准模板中的自定义通知
以下示例展示了在收起状态和展开状态下呈现的自定义通知:
另外,所有通知现在都变成了可展开的,如果你之前设置自定义内容视图时使用的是 setCustomContentView方法,那你现在则还需要另外再使用setBigCustomContentView方法来设置展开状态的样式,以确保通知在收起状态和展开状态的样式能统一。