Android 13 Adaptation Guide

Yes, you read that right, we will take you to Android 13 now .

Google I/O in 2022 released the device support list of Android 13 beta 2 and Android 13 Beta 1 domestic manufacturers, although according to convention, Android 13 should be released at the end of the year, but I believe that some developers have already received the platform's Android 13 Therefore, this article also combines Oppo's Android 13 Application Compatibility Adaptation Guide and some official documents to do a finishing test.

image-20220520154519270

At present, the main compatibility problem of Android 13 is still in privacy permissions, so this part of the adaptation guide is also focused on this part. The more extensive coverage here should be the photo album and notification permissions .

Album permissions

You may have seen this animation. This is the system picture selector provided on Android 13. You Intent(MediaStore.ACTION_PICK_IMAGES);can , support video, audio, picture classification, support multiple selection and single selection , and the official also stated that this feature not only It will only appear in Android 13, and Google will also put it in the Play Store and push it to Android 11 and Android 12 devices.

be848ec02aaa407dba67cee57a4347ea

We test by adjusting the TargetSDK setting PreViewand then running it on Tiramisu's emulator, mainly to test the different situations of TargetSDK when it is lower than "Tiramisu" and equal to "Tiramisu".

image-20220520154926287

As shown below:

  • Figure 1 shows the situation of TargetSDK running on the Andorid 13 simulator when TargetSDK is lower than 13. At this time, the relevant information of the local gallery can be accessed normally ;

  • 图 2 是使用了 "Tiramisu" 下,通过官方提供的 Intent(MediaStore.ACTION_PICK_IMAGES); 打开的系统相册选择组件,也没问题

  • 图 3 和 图 4 是使用了 "Tiramisu",使用以前代码运行后的相册读取情况,没做处理,可以看到此时读取不到相关信息;

  • 图 5 是 通过申请新的android.permission.READ_MEDIA_IMAGES 权限,就可以用以前的代码继续访问到以前的相册信息,因为对于目标版本为 Android 13 的情况,现在 READ_EXTERNAL_STORAGE权限被细化了,开发者需要使用READ_MEDIA_IMAGEREAD_MEDIA_VIDEOREAD_MEDIA_AUDIO 来替代适配;

  • 图 6 在申请完权限之后,就可以正常读取相册等信息;

Screenshot_20220518_152137

总结: 所以如果是 TargetSDK 在 Android 13 以下,不需要处理,如果在 Android 13 以及以上 ,需要增加申请权限

    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
复制代码

通知

在 Android R 上设置里开始支持在设置里对应用的通知权限进行管理,但是应用自身是无法修改应用级别的通知权限,所以 App 无法知道自身有没有发送通知的权限

所以在 Android 13 里增加了通知的运行时权限,其中 Android 13 (33) 的通知会根据正在运行的应用程序的目标 API 级别进行不同的处理,不过不管应用程序的目标API级别如何,Android 13 都会提示用户授予应用程序发送通知的权限

例如下图,是 targetSdk 30 运行在 Android 13 模拟器上,依然会弹出让用户是否允许推送

image-20220520160354680

  • 选择“允许”,应用就可以通过任何渠道发送通知,并发布与前台服务相关的通知;
  • 选择不允许选项,应用将无法发送通知,除了几个特定规则之外,所有通知渠道都会被屏蔽,这类似于用户在系统设置中手动关闭应用的所有通知后发生的行为
  • 如果用户不选择,比如划开对话框,或者直接返回,则应用只能在系统有临时授权的情况下发送通知(应用必须已经具有通知渠道,并且用户未在搭载 12L 或更低版本的设备上明确停用应用的通知)

当然,系统也会根据应用程序的目标 API 级别处理通知访问:

  • 对新安装的应用,程序的目标API不同表现为:
    • 以 Android 13 为 TargetSDK(33) ,应用程序需要在 Manifest 中声明 android.permission.POST_NOTIFICATION 权限,此权限的级别为“dangerous”,因此 App 需要向用户显示运行时提示才能被授予权限(也就是代码里调用权限申请,在设置里打开不行),未被授予权限的App 的通知将被系统自动删除;
    • 如果应用以 12L(API 级别 32)或更低版本为目标平台;当应用程序创建其第一个通知渠道时,系统将显示权限对话框;

如果是现有应用更新,程序的目标 API 级别为:

  • 以 Android 13 (33)为目标平台,系统临时授予应用发送通知的权限,直到应用中的 activity 首次启动(也就是更新之后第一次启动应用),这要求应用必须有一个现有的通知通道,且其通知不得被用户明确禁用;
  • 如果应用以 12L (32)或更低版本为目标平台,系统临时授予应用发送通知的权限,直到用户在权限对话框中明确选择一个选项;

最后测试和总结一下:

  • 如果是 TargetSDK 在 Android 12L (32) 以下,只要用户同意才能发送通知,一般是在应用启动的时候,比如用户点击了不允许,就无法发出通知,需要等到下次 App 再启动,才会再次询问,或者去设置通知中心打开

  • 如果是 TargetSDK 在 Android 13 (33) 以上,就一定需要手动添加 android.permission.POST_NOTIFICATIONS 和代码调用申请,不然可能设置中心都无法打开;

    image-20220520174116399

附近的WIFI设备权限

由于 Android 之前可以通过跟踪附近的 Wi-Fi AP 和蓝牙设备来推断设备的位置,所以这次谷歌决定禁止应用程序访问蓝牙Wi-Fi扫描结果,除非这类应用需要声明 ACCESS_FINE_LOCATION 权限。

在 Android 13 中,Google 将 Wi-Fi 扫描与位置相关内容分离, Android 13 为管理设备与周围 Wi-Fi 热点连接的应用添加 NEARBY_WIFI_DEVICES 运行时权限 (属于 NEARBY_DEVICES权限组),从而在不需要 ACCESS_FINE_LOCATION 权限的情况下,也可以让应用访问附近的 Wi-Fi 设备。

此前,对于仅需要连接 Wi-Fi 设备,但实际上并不需要了解设备位置的应用来说,以 Android 13 (33)为目标平台的应用现在可以通过 “neverForLocation” 属性来完善申请 NEARBY_WIFI_DEVICES 权限。

只要你的应用不会通过 Wi-Fi API 来推导物理位置,那么当你以 Android 13 或更高版本为目标平台并使用 Wi-Fi API 时,就可以请求 NEARBY_WIFI_DEVICES 而不是 ACCESS_FINE_LOCATION

这项新权限会影响几个不同的 Wi-Fi 用例,包括以下用例:

  • 查找或连接到附近的设备,如打印机或媒体投射设备,类似场景可以使用以下方式:
    • 通过带外方式(例如通过 BLE)接收 AP 信息;
    • 使用仅限本地使用的热点,通过 Wi-Fi 感知和连接功能发现并连接到设备;
    • 通过 Wi-Fi 直连发现和连接到设备;
  • 发起与已知 SSID(例如汽车或智能家居设备)的连接。
  • 开启仅限本地使用的热点。
  • 连接到附近的 Wi-Fi 感知设备。

所以开发需要区分不同api对应的权限;

  • 需要新权限(NEARBY_WIFI_DEVICES)的 API:

    • WifiManager:startLocalOnlyHotspot()
    • WifiAwareManager:attach()
    • WifiAwareSession:publish()、subscribe()
    • WifiP2pManager:addLocalService()、connect()、createGroup()、discoverPeers()、discoverServices()、requestDeviceInfo()、requestGroupInfo()、requestPeers()
    • WifiRttManager:startRanging()
  • 仍需要位置信息权限(ACCESS_FINE_LOCATION )的API:

    • WifiManager:getScanResults()、startScan()

由于 NEARBY_WIFI_DEVICES 权限仅适用于 Android 13 或更高版本, 如果是 Android12L(32) 以及以下的 App 应保留对 ACCESS_FINE_LOCATION 的所有声明:

<manifest ...>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="32" />
    <application ...>
        ...
    </application>
</manifest>
复制代码

以 Android 13(33) 为目标平台时,如果应用不会通过 Wi-Fi API 推导物理位置,请在清单文件中将 usesPermissionFlags 属性设为 neverForLocation。

<manifest ...>
    <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
                     android:usesPermissionFlags="neverForLocation" />
    <application ...>
        ...
    </application>
</manifest>
复制代码

所以总结:以 Android 13(33) 为目标平台的应用程序,访问附近的 WI-FI 设备。除特例API需要申请ACCESS_FINE_LOCATION外,其他需要申请 android.permission.NEARBY_WIFI_DEVICES 运行时权限

在后台使用身体传感器需要新的权限

Android 13 中引入了 “在使用时” 访问身体传感器(例如心率、体温和血氧饱和度)的概念,此访问模式与 Android 10(API 级别 29)系统为位置信息引入的模式非常相似。

如果你的 App 以 Android 13(33) 为目标平台,并且在后台运行时需要访问身体传感器信息,那么除了现有的 BODY_SENSORS 权限外,还必须声明新的 BODY_SENSORS_BACKGROUND 权限

注意:这是受到“硬性限制”的权限,除非设备的安装程序针对你的应用将该权限列入了许可名单,否则你的应用将无法获得此权限,如需了解详情,请参阅有关受限权限的指南。

Intent 过滤器会屏蔽不匹配的 intent

当 App 以 Android 13(33) 或更高版本为 Target 的其他应用的导出组件发送 intent 时,仅当该 intent 与接收应用中的 <intent-filter> 元素匹配时,系统才会传送该 intent,换言之系统会屏蔽所有不匹配的 intent,但以下情况除外:

  • 发送给其他应用的未声明任何 intent 过滤器的组件的 intent;
  • 发送给你应用中的其他组件的 intent;
  • 由系统发送的 intent;
  • 由具有根级特权的用户发送的 intent;

更安全地导出上下文注册的接收器

为了帮助提高运行时接收器的安全性,Android 13 允许你指定 App 中的特定广播接收器是否应被导出以及是否对设备上的其他应用可见,此变更是 Android 12 更安全的组件 的延续;

以 Android 13(33) 或更高版本为目标平台的应用,必须为每个广播接收器指定 RECEIVER_EXPORTEDRECEIVER_NOT_EXPORTED,否则当 App 尝试注册广播接收器时,系统会抛出 SecurityException

// This broadcast receiver should be able to receive broadcasts from other apps.
// This option causes the same behavior as setting the broadcast receiver's
// "exported" attribute to true in your app's manifest.
context.registerReceiver(sharedBroadcastReceiver, intentFilter,
    RECEIVER_EXPORTED);
// For app safety reasons, this private broadcast receiver should **NOT**
// be able to receive broadcasts from other apps.
context.registerReceiver(privateBroadcastReceiver, intentFilter,
    RECEIVER_NOT_EXPORTED);
复制代码

应用自撤销权限

在 Android 13中,谷歌添加了一个新的API,允许开发者降级权限。

应用程序可以触发撤销授予调用 API 的包的一个或多个运行时权限,不需要访问特定运行时权限控制 API 的应用程序可以自行撤销这些权限,这样用户就可以确保这些应用程序不会在不知情的情况下使用这些API。

如需撤消特定运行时权限,请将该权限的名称传入 revokeOwnPermissionOnKill() 方法,如需同时撤消一组运行时权限,请将这组权限的名称传入 revokeOwnPermissionsOnKill()

撤消是异步发生的,会终止与应用的 UID 相关联的所有进程。

系统只有在安全的情况下才会触发撤消操作,也就是当有应用组件仍在前台运行,或者有另一个应用正在访问你应用的组件(如 content provider)时不会发生撤消。

如果你想立即撤消权限,可以调用 exit()。但是进行 exit() 调用可能会导致当前正在访问 App 的其他应用出现崩溃。

剪贴板擦除

Android 之前一直提供了一个剪贴板服务,所有 App 都可以使用它来放置和检索文本。

尽管从技术上讲,任何应用都可以清除全局剪贴板中的主内容(只要它们是前台应用或 Android 10+ 上的默认输入法),但 Android 本身不会自动清除剪贴板。

这意味着任何留在全局剪贴板中的剪贴板内容,都可以在以后被应用程序读取,尽管 Android 的剪贴板访问有 toast 消息可能会提醒用户。

Android 13 增加了剪贴板自动清除功能,此功能在默认情况下处于禁用状态,在经过设定的时间后,将自动从全局剪贴板中清除主剪辑, 默认情况下经过3600000毫秒(60分钟)后,剪贴板将被清除。

每次执行复制/读取(写入剪贴板 setPrimaryClip,读 getPrimaryClip )时,会重置一个消息 timeout(60min),之后会自动清除剪贴板内存中的内容,即60min内,如果一直没有写入剪贴板的操作,剪贴板的内容会被自动清除。

前台服务 (FGS) 任务管理器

Android 13 的新前台服务( Foreground Services:FGS)任务管理器显示当前运行前台服务的应用程序列表,此列表称为活动应用程序,可以通过下拉通知抽屉并点击启示来访问,这时候每个应用程序旁边都会有一个“停止”按钮。

注意:当用户点击应用旁边的停止按钮时,系统会停止整个应用,而不仅仅是正在运行的前台服务。

image.png

注意:如果系统检测到你的应用长时间运行某项前台服务(在 24 小时的时间段内至少运行 20 小时),便会发送通知邀请用户与 FGS 任务管理器进行互动,详见:developer.android.google.cn/about/versi…

使用 JobScheduler 改进预提取处理

Using JobScheduler, applications can use JobInfo.Builder.setPrefetch() to mark specific jobs as "prefetch", which means that ideally these jobs should run a little earlier before the next application startup to improve the user experience.

In the past, JobScheduler only used this signal to give prefetch jobs a chance to use free or redundant data, in Android 13 the system will now try to determine when the app will next launch, and run prefetch jobs based on that estimate, apps should try to use "Prefetch" to do whatever they want to be done before the next app launch.

battery resource utilization

The Battery to provide the system with several ways to better manage device battery life:

  • Updated rules for when the system puts your app into the "Restricted" App Standby bucket .
  • There are new restrictions on what your app can do when a user puts your app in a "limited" state due to its high background battery usage .
  • Added system notifications to warn users about high battery usage and long-running foreground services .

Summarize

Changes that need to be addressed until TargetSDK 33:

  • Album permissions
  • Nearby WIFI Device Permissions
  • Using body sensors in the background requires new permissions
  • Intent filters block non-matching intents
  • Safer export of context-registered receivers
  • Apply self-revoking permissions
  • clipboard erase

Changes affecting all apps:

  • Notification permission
  • Foreground Service (FGS) Task Manager
  • Improve prefetch processing with JobScheduler
  • battery resource utilization

Guess you like

Origin juejin.im/post/7099762078977622053