这几个月有点忙,一年一篇的适配文章来的有点晚了。但其实也还好,因为我们项目也是下半年才适配。我这边也是提前调研踩坑,评估一下工作量。这个时间点也完全跟得上Google Play的审核要求(11月1号),对于国内这边更是超前了。。。废话不多说,开始了。

首先先说一些影响在Android 12上运行应用的行为变更。这部分会直接影响在Android 12上运行的所有应用,所以即使你不适配,也需要重点关注。

应用启动画面

从 Android 12 开始,SplashScreen API 可为所有Android 12或更高版本的设备上运行的应用启用新的应用启动动画。这包括启动时的进入应用动画、显示应用图标的启动画面,以及向应用本身的过渡。

先看一下启动画面示例:

启动画面的元素由Android清单中的XML资源文件定义。每个元素都有浅色模式和深色模式版本。

启动画面的可自定义元素包括应用图标、图标背景和窗口背景:

①应用图标应该是矢量可绘制对象(AVD XML),它可以是静态或动画形式。虽然动画的时长可以不受限制,但我们建议不超过1,000 毫秒。默认情况下,使用启动器图标。

②可以选择添加图标背景;在图标与窗口背景之间需要更高的对比度时图标背景很有用。如果您使用一个自适应图标,当该图标与窗口背景之间的对比度足够高时,就会显示其背景。

③与自适应图标一样,前景的三分之一被遮盖。

④窗口背景由不透明的单色组成。如果窗口背景已设置且为纯色,则未设置相应的属性时默认使用该背景。

其实这个实际上可以不适配。。。比如我的vivo手机其实在开发者模式可以开关这一选项,而且默认是关闭的。对于使用非原生系统的用户来说,算是个感知不到的变化。但最终适配与否还是看产品是否可以接受了。

不过需要注意:默认情况下,SplashScreen 使用主题的windowBackground(如果它是单色)和启动器图标。
所以windowBackground的颜色和logo的颜色如果对比度比较低,实际显示效果会比较糟糕,我觉得这块可以适当处理一下。

这里就不花费篇幅来说明了,有适配需求的可以参考:将现有的启动画面实现迁移到 Android 12 及更高版本

拉伸滚动效果

在搭载 Android 12 及更高版本的设备上,滚动事件的视觉行为发生了变化。

在 Android 11 及更低版本中,滑动到边界是会出现弧形的阴影遮罩。在 Android 12 及更高版本中,发生拖动事件时,视觉元素会拉伸和反弹;发生快速滑动事件时,它们会快速滑动和反弹。

定位权限:大概位置

如果您的应用请求ACCESS_COARSE_LOCATION但未请求ACCESS_FINE_LOCATION,则此变更不会影响您的应用。

如果您的应用请求ACCESS_FINE_LOCATION 运行时权限,您还应请求ACCESS_COARSE_LOCATION权限,以便处理用户授予应用大致位置访问权限的情形。

可能是出于兼容的目的。实际我在我的vivo手机测试发现,只请求ACCESS_FINE_LOCATION权限,也可以正常弹出,并选择位置精度。但是保险起见,实际适配时还是按照官方文档的要求来。

如果用户首次选择了大致位置,二次请求权限时会提示用户是否更改为精确位置。这点可以注意一下。

Activity生命周期

Android 12 更改了在按下“返回”按钮时系统对为其任务根部的启动器activity的默认处理方式。在以前的版本中,系统会在按下“返回”按钮时finish这些 activity。在 Android 12 中,现在系统会将 activity 及其任务移到后台,而不是finish activity。这一新行为与使用HOME按钮行为一致。

注意:系统仅会将新行为应用于为其任务根部的启动器 activity,即使用 ACTION_MAINCATEGORY_LAUNCHER 声明 intent 过滤器的 activity。对于其他 activity,在按下“返回”按钮时,系统会像以前一样finish activity。

对于大多数应用而言,此变更意味着使用“返回”按钮退出应用的用户可以更快地从温状态恢复应用,而不必从冷状态完全重启应用。

建议您针对此变更测试您的应用。如果您的应用目前重写 onBackPressed() 来处理返回导航并finish Activity,请更新您的实现来调用 super.onBackPressed() 而不是finish。调用 super.onBackPressed() 可在适当时将 activity 及其任务移至后台,并可为不同应用中的用户提供更一致的导航体验。

另请注意,通常,我们建议您使用 AndroidX Activity API 提供的自定义返回导航,而不是替换 onBackPressed()。如果没有组件拦截系统按下“返回”按钮,AndroidX Activity API 会自动遵循适当的系统行为。


还有许多的行为变更,以上我只选了几条重要的。其他变更可以参见:Android 12行为变更:所有应用

接下来是以Android 12为目标平台的应用行为变更。首先就需要我们将targetSdkVersion升至31。

自定义通知

Android 12 更改了自定义通知的外观和行为。以前,自定义通知能够使用整个通知区域并定义自己的布局和样式。因此会在不同设备上引发布局兼容性问题,使用户感到困惑。

对于以 Android 12 为目标平台的应用,自定义布局的通知将不再使用完整通知区域;相反,系统会使用标准模板。此模板可确保自定义通知在所有状态下都与其他通知相同,例如,在收起状态下的通知图标和展开功能,以及在展开状态下的通知图标、应用名称和收起功能。此行为与 Notification.DecoratedCustomViewStyle 的行为几乎完全相同。

下面展示了在收起状态和展开状态下呈现的自定义通知:



此变更会影响某些定义了 Notification.Style 子类的应用,或使用 Notification.Builder 中的 setCustomContentView(RemoteViews)setCustomBigContentView(RemoteViews)setContent(RemoteViews)setCustomHeadsUpContentView(RemoteViews) 方法的应用。

具体适配时,需要注意以下几点:

  • 自定义视图的尺寸有变更。一般来说,提供给自定义通知的高度比之前小。在收起状态下,自定义内容的最大高度已从 106dp 减少到 48dp。此外,水平空间也减小了。
  • 对于以 Android 12 为目标平台的应用,所有通知都是可展开的。通常,这意味着,如果您使用的是 setCustomContentView,则还需要使用 setBigCustomContentView,以确保收起状态和展开状态保持一致。
  • 为了确保“浮动通知”(Heads Up)状态看起来符合您的预期,请勿忘记将通知渠道的重要性(setPriority)提升至“高”(在屏幕中弹出)。

更安全的组件导出

如果您的应用以 Android 12 或更高版本为目标平台,且包含使用 intent 过滤器的 activity、服务或广播接收器,您必须为这些应用组件显式声明 android:exported 属性。否则应用无法安装。

所以我们可以在AndroidManifest.xml搜索<intent-filter>,为这些组件显式声明 android:exported 属性。

android:exported 属性表示是否能被其他应用隐式调用。所以如果应用组件包含 LAUNCHER 类别,请将 android:exported 设置为 true。在大多数其他情况下,请将 android:exported 设置为 false。例如:

<service android:name="com.example.app.backgroundService"android:exported="false"><intent-filter><action android:name="com.example.app.START_BACKGROUND" /></intent-filter>
</service>

对于三方sdk,具体根据相应文档要求配置。如果sdk没有此适配,可以参考这篇文章:Android 12 自动适配 exported 深入解析避坑

PendingIntent可变性

如果您的应用程序以Android 12为目标平台,您必须为应用创建的每个 PendingIntent 对象指定可变性。这项额外的要求可提高应用的安全性。因为三方app可以通过劫持PendingIntent,然后改写里面的action、category、data等,造成重定向攻击。

所以适配的具体就是在创建 PendingIntent时,使用 PendingIntent.FLAG_MUTABLEPendingIntent.FLAG_IMMUTABLE 标志。否则运行时会报IllegalArgumentException

java.lang.IllegalArgumentException: com.dailyyoga.inc: Targeting S+ (version 31 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.

我们可以检查代码中使用PendingIntent的地方,比如PendingIntent.getActivity()PendingIntent.getService()
PendingIntent.getBroadcast()方法。指定可变性标志:

PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);

一般情况下,尽可能使用FLAG_IMMUTABLE创建不可变的 ​PendingIntent​ 对象。如果需要创建可变的​PendingIntent​,那么一定注意要使用显式 intent 并设置​ComponentName​。

我们项目中因为使用到了androidx.workgoogle-exo库,它内部在创建 PendingIntent 对象时没有指定可变性,导致有兼容性问题,所以需要升级版本至2.7.02.16.0以上。

应用休眠

Android 11中引入了权限自动重置机制。如果您的应用以 Android 12 为目标平台,并且用户有几个月未与您的应用互动,则系统会自动重置授予的所有权限并将您的应用置于休眠状态。

休眠状态的应用程序具有以下特征:

  • 应用无法从后台运行作业(jobs)或警报(alerts)。
  • 应用无法接收推送通知,包括通过Firebase Cloud Messaging发送的高优先级消息。
  • 应用程序的缓存文件都将被删除。

当用户下一次与您的应用程序交互时(包括与小组件),您的应用程序将退出休眠,它可以再次创建作业、提醒和通知。

但是,系统不会为您的应用程序执行以下操作:

  • 重新授予你的应用的运行时权限。用户必须重新授予您的应用程序这些权限。
  • 不会恢复作业、提醒和通知。你需要重新计划在应用程序进入休眠状态之前计划的任何作业、警报和通知。

此行为类似于用户手动从系统设置中强制停止您的应用程序。要更轻松地支持此工作流程,请使用WorkManager。您还可以在ACTION_BOOT_COMPLETED广播接收器中添加重新计划逻辑,当您的应用退出休眠状态并在设备启动后被调用。

对于系统级应用,会免于休眠。如果您的应用程序中的核心用例会受到休眠的影响,您可以向用户请求免除应用程序休眠。具体详见官方文档,这里就不过多介绍了。

前台服务启动限制

针对Android 12或更高版本的应用在后台运行时无法启动前台服务,除了几个特殊情况外。如果一个应用程序试图在后台运行时启动前台服务,而前台服务不满足其中一种异常情况,系统将引发ForegroundServiceStartNotAllowedException.

你可以执行以下ADB命令,检查您的应用程序是否执行后台启动:

adb shell device_config put activity_manager \default_fgs_starts_restriction_notification_enabled true

一旦发现后台运行时启动前台服务,就会在通知栏推送一条提醒。

谷歌建议的适配方法就是使用WorkManager,应用在后台运行时,使用 WorkManager来计划和启动加急任务(expedited job) 。从WorkManager2.7.0开始,可以调用setExpedited()来声明Worker使用加急任务。

通知 trampoline 限制

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

也就是说,如果你点击了通知,启动了一个广播或者服务,然后在这个广播或服务中调用了startActivity()启动activity。此时系统会阻止该 activity 启动,并在 Logcat 中显示以下消息:

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

我们可以执行下面的命令识别哪些应用组件充当通知 trampoline:

adb shell dumpsys activity service \com.android.systemui/.dump.SystemUIAuxiliaryDumpService

执行后,点击你的通知,如果是通知 trampoline。Log会输出的包含文本“NotifInteractionLog”的日志。此部分包含识别因点按通知而启动的组件所需的信息。

具体适配方法就是使用PendingIntent直接启动目标Activity。

蓝牙权限

如果您的应用程序面向Android 12或更高版本,使用蓝牙功能时请在应用程序的清单文件中声明以下权限:

  • BLUETOOTH_SCAN:允许蓝牙设备扫描。
  • BLUETOOTH_CONNECT:允许蓝牙设备连接。
  • BLUETOOTH_ADVERTISE:允许当前蓝牙设备可以被其他蓝牙设备发现。

如果不申请新的权限,扫描时会报如下错误:

 java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for android.content.AttributionSource@8825e139: GattService registerScanner

对于以前的与蓝牙相关的权限声明,设置android:maxSdkVersion到30。此应用兼容性步骤可帮助系统仅授予您的应用在运行Android 12 的设备上安装时所需的蓝牙权限。

<manifest><!-- Request legacy Bluetooth permissions on older devices. --><uses-permission android:name="android.permission.BLUETOOTH"android:maxSdkVersion="30" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"android:maxSdkVersion="30" /><uses-permission android:name="android.permission.BLUETOOTH_SCAN" /><uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /><!-- 只有当您的应用程序使用蓝牙扫描结果来获取物理位置时才需要 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />...
</manifest>

如果您的应用程序使用蓝牙扫描结果来获取物理位置,请声明ACCESS_FINE_LOCATION。以前版本中(6.0 ~ 11)是必须申请定位权限,才可以进行蓝牙扫描。

在Android 12上,如果你的应用程序不使用蓝牙扫描结果来获取物理位置。可以添加android:usesPermissionFlags属性到您的BLUETOOTH_SCAN权限声明,并将该属性的值设置为neverForLocation.

<manifest><uses-permission android:name="android.permission.BLUETOOTH_SCAN"android:usesPermissionFlags="neverForLocation" /><!--可以删除定位权限 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />...
</manifest>

其他

  • 默认toast样式发生变化,文字上限为两行,且在文字旁边会显示应用图标。

  • 为了保护私有应用数据,Android 12 变更了 adb backup 命令的默认行为。对于以 Android 12或更高版本为目标平台的应用,用户运行 adb backup 命令时,从设备导出的任何其他系统数据都不包含应用数据。
    如果您的测试或开发工作流程依赖于使用 adb backup 的应用数据,现在您可以选择通过在应用的清单文件中将 android:debuggable 设置为 true 来导出应用数据。

有关Android 12的适配内容主要就这么多,更多的变更还是需要我们去阅读官方文档。链接我也贴到了文末。

关于Android的适配,我从Android 6.0写到了12,其中也包含早期4.4,5.0的个别特性适配。这些内容都在我的Android 适配专栏里,希望可以帮到你。

最后,期待你的收藏点赞,给作者一个支持。好让我继续坚持每年为大家带来我的实际适配心得,感谢!

参考

  • 行为变更:以 Android 12 为目标平台的应用
  • OPPO - Android 12 应用兼容性适配指导

Android 12 变更及适配攻略相关推荐

  1. Android 11 变更及适配攻略

    终于开始了Android 11的适配工作.记录一下,供需要的人参考. 1. 准备工作 老规矩,首先将我们项目中的 targetSdkVersion 改为 30.或者使用兼容性调试工具,后面我会说到. ...

  2. Android Q之提前适配攻略(一)(图标适配)

    转自:https://blog.csdn.net/qq_37199105/article/details/89632104 前言: Android Q在2019年的3月份发布了beta1版本,这算是近 ...

  3. Android Q适配攻略(一)(图标适配)

    Android Q之提前适配攻略(一)(图标适配) Android Q之提前适配攻略(二)(后台定位适配) Android Q之提前适配攻略(三)(唯一标识符更改) Android Q之提前适配攻略( ...

  4. Android Q适配攻略(四)(后台Activity启动限制)

    Android Q之提前适配攻略(一)(图标适配) Android Q之提前适配攻略(二)(后台定位适配) Android Q之提前适配攻略(三)(唯一标识符更改) Android Q之提前适配攻略( ...

  5. Android Q适配攻略(二)(后台定位适配)

    Android Q之提前适配攻略(一)(图标适配) Android Q之提前适配攻略(二)(后台定位适配) Android Q之提前适配攻略(三)(唯一标识符更改) Android Q之提前适配攻略( ...

  6. Android 屏幕适配攻略(六)设置通知样图标与启动图标适配

    Android 屏幕适配攻略(六)设置通知样图标与启动图标适配 1 Android中资源文件中的图片加载分析 Android中对屏幕的像素适配处理分类 屏幕密度 对应的标签 对应的像素 120dip ...

  7. Android 动态创建控件并设置控件的大小之Android屏幕适配攻略(五)

    Android 屏幕适配攻略(五)动态创建控件并设置控件的大小 题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. 重要消息 flutter中网络请求dio使用分析 视频 ...

  8. Android 屏幕适配攻略(四)获取手机屏幕的相关信息 与动态设置控件的大小

    Android 屏幕适配攻略(四)获取手机屏幕的相关信息 与动态设置控件的大小 1 动态获取手机屏幕的 屏幕密度与对应像素比例 例如在 320 * 480 尺寸为 3.2 英寸的手机 ,对应的像素密度 ...

  9. Android 屏幕适配攻略(三)单位dp与sp

    Android 屏幕适配攻略(三)单位dp与sp 1 一般手机默认使用情况下 在安卓中,一般情况下,也就是正常使用情况下 屏幕密度 对应的标签 对应的像素 sp 120dip ldpi 1dp= 0. ...

最新文章

  1. Java 8 Stream原理解析
  2. 今天 CSDN 编辑器的一个惊人的变化
  3. Android/Java 获取一个byte[]的真实编码,用于解决乱码问题
  4. Shell脚本实现生成SSL自签署证书
  5. 简易TCP客户端和服务端的实现
  6. php+防御+xss,PHP防御XSS攻击
  7. bzoj 1597 土地购买
  8. STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时
  9. vc6.0添加注释快捷键
  10. java中复制图片_如何在Java中实现复制图片
  11. 通过hadoop + hive搭建离线式的分析系统之快速搭建一览
  12. TapTap 发布游戏
  13. 微信消息记录导出到电脑
  14. 手游运营数据分析指标百科全说
  15. matlab设置固定的窗宽窗位,如何设定窗宽窗位,附正常人体组织CT值
  16. 联想计算机无线网络设置密码,联想(Lenovo)无线路由器怎么设置
  17. 盘点行业APP运营推广渠道有哪些
  18. adnroid 系统OTA升级
  19. 我的网名为什么是ma6174????
  20. excel几个表合成一张_如何将几个excel文件合并_多个excel表合并成一个的方法

热门文章

  1. Android国际化,阿语RTL适配总结
  2. 轻松上手Manjaro之Manjaro简介
  3. 福建农商银行计算机类笔试题目,2014年福建农商银行考试计算机模拟题
  4. 可以去看阿哲演唱会咯~
  5. 苹果加入造车潮,自动驾驶离我们还远吗?
  6. 浙江大学计算机云南分数线,985大学在云南录取分数排名,想上清北、浙大、南大至少这个成绩...
  7. Milimeter-Wave UAV Communications(41-50)
  8. 顶会查找论文的网址和检索方法
  9. lt;转gt;凯文#183;凯利斯坦福演讲-预言未来20年科技潮流
  10. The role of Roles