Android 13 应用适配指南3,安卓13新功能和API
3.1.1.3 豁免
系统会针对特定类型的应用提供几种级别的豁免,下面几部分将介绍这些豁免。
豁免针对的是应用而不是进程。如果系统豁免了应用中的一个进程,则该应用中的所有其他进程也会被豁免。注意
:即使是设备上预装的应用,也必须至少满足下面一个部分中的条件才能获得豁免。
a. 完全不会显示在 FGS 任务管理器中
以下应用可以运行前台服务,而完全不会显示在任务管理器中:
- 系统级应用
- 安全应用,即具有ROLE_EMERGENCY 角色的应用
- 处于演示模式的设备上的应用
b. 免于被用户停止当以下类型的应用运行前台服务时,它们会显示在 FGS 任务管理器中,但应用名称旁边没有可以供用户按的停止按钮:
- 设备所有者应用
- 资料所有者应用
- 常驻应用
- 具有ROLE_DIALER 角色的应用
3.1.1.4 测试
如需测试应用在用户停止应用的过程中和之后的行为是否符合预期,请在终端窗口中运行以下 adb 命令:
adb shell cmd activity stop-app PACKAGE_NAME
3.1.2 使用 JobScheduler 改进预提取作业处理
利用 JobScheduler,应用可使用JobInfo.Builder.setPrefetch()将特定作业标记为“预提取”作业,这意味着,理想情况下这些作业应该在应用下一次启动前提前一点运行,以提升用户体验。过去,JobScheduler 仅使用该信号让预提取作业有机会使用免费或多余的数据。
在 Android 13 中,系统现在会尝试确定应用下次启动的时间,并根据该估算值运行预提取作业。应用应尝试使用预提取作业来完成他们想要在下次应用启动前完成的任何工作。
3.1.2.1 代码示例
JobScheduler mJobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder mBuilder = new JobInfo.Builder(mJobId++, new ComponentName(this,MyJobService.class));
mBuilder.setPrefetch(true) //赋值为true
mJobScheduler.schedule(mBuilder.build());
3.1.3 电池资源利用率
Android 13 引入了以下省电措施:
- 更新了有关系统何时将您的应用放入“受限”应用待机模式存储分区的规则。
- 对于您的应用在以下情况下可以执行的操作制定了新限制:用户因您应用的后台电池用量过高而将其置于“受限”状态。
- 新增了系统通知,用于就后台电池用量过高和长时间运行的前台服务向用户发出警告。
3.1.3.1 关于应用何时会进入“受限”应用待机模式存储分区的规则更新
除非您的应用符合豁免条件,否则当您的应用出现以下任何行为时,系统就会将其放入受限存储分区:
- 用户有 8 天没有与您的应用互动。如果用户与另一个绑定到您应用的服务的应用互动,系统也会将您的应用视为“使用过”。
注意
:设备处于关闭状态的时间不会计入互动限制。
- 您的应用在 24 小时内调用了过多的广播或绑定。
- 您的应用在 24 小时内消耗了大量的设备电池电量。对于低 RAM 设备,此阈值可能会有所不同。
在衡量应用对设备电池续航时间的影响时,系统会考虑应用在几个不同方面执行的操作,包括:
- 作业(包括加急作业)
- 广播接收器
- 后台服务
- 系统是否已缓存应用的进程
用户互动可让您的应用退出“受限”存储分区:
当用户与您的应用互动时(包括通过以下几种方式互动),系统会将应用从受限存储分区中移出,并放入另一个应用待机模式存储分区:
- 用户点按您的应用发送的通知。
注意
:如果用户在不点按通知的情况下滑开通知,系统不会
将该操作视为与您的应用“互动”。
- 用户在属于您应用的 widget 中执行操作。
- 用户通过按媒体按钮影响您应用的前台服务。
- 用户在与 Android Automotive OS 互动时连接到您的应用(您的应用在此过程中使用了前台服务或CONNECTION_TYPE_PROJECTION)。
- 您的应用在画中画 (PiP) 模式下可见。
- 您的应用是屏幕上当前运行的应用之一。(主要适用于大屏设备。)
3.1.3.2 关于受限后台电池用量的新限制
注意
:只有在您的应用以 Android 13 为目标平台时,此变更才会生效。
使用现有 Android 版本的用户能够调整应用在后台运行时可以执行的工作量。系统设置中的电池用量页面上会显示以下选项:
- 无限制:允许后台工作,这可能会消耗更多电量。
- 优化(默认):根据用户与应用互动的方式,优化应用执行后台工作的能力。
- 受限:更注重延长设备的电池续航时间,而不是实现应用的全面功能。对于应用可以在后台执行的操作施加了更多限制。
注意
:如果用户在将您的应用置于“受限”状态之后启动了该应用,系统会暂时将该应用视为处于“优化”状态。当用户停止与您的应用互动并开始与另一个应用互动时,系统会将您的应用重新置于“受限”状态。
自 Android 9(API 级别 28)起,处于“受限”状态的应用具有以下限制:
- 无法启动前台服务
- 现有的前台服务会从前台移除
- 不会触发闹钟
- 不会执行作业
当您的应用以 Android 13 为目标平台时,除非应用因其他原因启动,否则系统不会传送以下任何广播:
- BOOT_COMPLETED
- LOCKED_BOOT_COMPLETED
3.1.3.3 与后台电池用量过高相关的系统通知
Android 13 引入了一个新的系统通知,当您的应用在 24 小时内消耗了大量设备电池电量时,就会显示该通知。这个新通知会针对搭载 Android 13 的设备上的所有应用显示,无论应用采用何种目标 SDK 版本都不例外。注意
:如果系统在应用显示与前台服务相关的通知时检测到应用的电池用量较高,系统会等到用户关闭通知,或前台服务完成,并且仅在您的应用继续消耗大量设备电池电量时才会显示该通知。
在衡量应用对设备电池续航时间的影响时,系统会考虑应用在几个不同方面执行的操作,包括:
- 前台服务,即使是有可见通知的服务
- 工作任务,包括加急工作
- 广播接收器
- 后台服务
- 应用的缓存
如果针对您的应用显示了此通知,则至少在 24 小时后,才会再次在同一设备上显示该通知。
3.1.3.4 与长时间运行的前台服务相关的系统通知
如果系统检测到您的应用长时间运行某项前台服务(在 24 小时的时间段内至少运行 20 小时),便会发送通知邀请用户与前台服务 (FGS) 任务管理器互动。该通知包含以下内容:
APP is running in the background for a long time. Tap to review.
注意
:如果系统针对您的应用显示了此通知,则至少在 30 天后才会再次显示类似通知。如果前台服务的类型为FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK或
FOREGROUND_SERVICE_TYPE_LOCATION
,系统将不会显示此通知。
此外,如果您的应用在 24 小时内运行超过 4 小时的前台服务属于FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK或
FOREGROUND_SERVICE_TYPE_LOCATION
类型,则系统不会针对您的应用启动的任何前台服务发送长时间运行通知。
3.1.3.5 豁免
存在以下情况的应用不会受到 Android 13 中引入的任何省电措施的影响:
- 系统应用和系统绑定应用
- 配套设备应用
- 处于演示模式的设备上运行的应用
- 设备所有者应用
- 资料所有者应用
- 常驻应用
- VPN 应用
- 具有ROLE_DIALER 角色的应用
- 用户在系统设置中明确指定提供“无限制”功能的应用
在以下情况下,您的应用可以免于进入“受限”应用待机模式存储分区,并可以绕过“8 天无活动”触发器:
- 具有活跃的 widget
- 至少被授予下列其中一种权限: SCHEDULE_EXACT_ALARM
- ACCESS_BACKGROUND_LOCATION
在以下情况下,您的应用可以不受 Android 13 中引入的大多数省电措施的影响,但系统仍然会发送针对长时间运行的前台服务的通知:
- 具有进行中的活跃MediaSession
- 被授予ACCESS_FINE_LOCATION 权限
3.1.3.6 测试
以下几个部分将介绍几种测试 Android 13 中引入的省电措施会对应用产生何种影响的方式。
禁止在后台使用
如需禁止您的应用在后台运行,请在终端窗口中运行以下命令:
adb shell cmd appops set PACKAGE_NAME RUN_ANY_IN_BACKGROUND deny
将应用放入受限存储分区
如需强制系统将您的应用放入受限存储分区,请在终端窗口中运行以下命令:
adb shell am set-standby-bucket PACKAGE_NAME restricted
3.2 行为变更:以Android 13为目标平台的应用
3.2.1 通知运行时权限
Android 13 中引入了新的运行时权限,用于从应用发送非豁免通知:POST_NOTIFICATIONS。此更改有助于用户专注于最重要的通知。
强烈建议您尽快以 Android 13 为目标平台,以获享此功能提供的额外控制和灵活性。如果您继续以 12L(API 级别 32)或更低版本为目标平台,您将失去在应用功能环境中请求权限
的机会。
应用的影响总结如下:
Target SDK | 应用 | 权限弹窗 | 临时授权 |
Android 13 pre | 新安装 | 创建第一个通知渠道时 | 无 |
现有 | 首次启动Activity | 一直有效,直到权限弹窗中明确选择 | |
Android 13 | 新安装 | 应用自行控制 | 无 |
现有 | 应用自行控制 | 首次启动Activity为止 |
3.2.1.1 使用新权限
如需向应用请求新的通知权限,请将应用更新为以 Android 13 为目标平台,并完成与请求其他运行时权限类似的流程,如以下几个部分所述。需要在应用的清单文件中声明的权限会显示在以下代码段中:
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <application ...>
...
</application>
</manifest>
3.2.1.2 应用功能取决于用户在权限对话框中所做的选择
在此对话框中,用户可执行以下操作:
- 选择允许苹果cms生成双端app
- 选择不允许
- 滑开对话框,不按任何一个按钮
注意
:如果用户点按不允许
,即使仅点按一次,系统也不会再次提示用户,除非他们卸载并重新安装您的应用。
下面几个部分介绍了根据用户操作的不同,应用会有哪些不同的行为表现。
a. 用户选择“允许”如果用户选择允许选项,您的应用可以执行以下操作:
- 发送通知。可以使用所有通知渠道。
- 发送与前台服务相关的通知。这些通知会显示在抽屉式通知栏中。
b. 用户选择“不允许”如果用户选择不允许选项,您的应用将无法发送通知。除了几个特定角色之外,所有通知渠道都会被屏蔽。这类似于用户在系统设置中手动关闭应用的所有通知后发生的行为。
c. 用户滑开对话框
如果用户滑开对话框(即他们既没有选择允许,也没有选择不允许),会发生以下行为:
- 如果您的应用符合获得临时通知授权的条件,系统会保留临时授权。
- 如果您的应用没有临时授权,则将无法发送通知。
3.2.1.3 对新安装的应用的影响
如果用户在搭载 Android 13 的设备上安装您的应用,应用的通知默认处于关闭状态。在您请求新的权限且用户向您的应用授予该权限之前,您的应用都将无法发送通知。
权限对话框的显示时间取决于应用的目标 SDK 版本:
- 如果您的应用以 Android 13 或更高版本为目标平台,应用将可以完全自行控制权限对话框的显示时间。您可以借此机会向用户说明应用需要此权限的原因,进而鼓励他们授予该权限。
- 如果您的应用以 12L(API 级别 32)或更低版本为目标平台,系统会在您创建第一个通知渠道时显示权限对话框。这通常是在应用启动时。
3.2.1.4 对现有应用更新的影响
注意
:请考虑下面这种情形,即应用安装在搭载 12L 或更低版本的旧设备上,用户在该设备上允许接收通知,但想淘汰该设备。用户现在使用的是搭载 Android 13 的新设备,并通过备份和恢复功能恢复了应用。
在这种情况下,系统会将您的应用视为“现有应用”,因此该应用会获得发送通知的临时权限。
为最大限度地减少与新通知权限相关的中断,系统会自动向系统升级到 Android 13 之前用户设备上已安装的所有符合条件的应用临时授予新通知权限。此临时授权的持续时间取决于应用的目标 SDK 版本:
- 如果应用以 Android 13 或更高版本为目标平台,则临时授权将持续到应用首次启动 activity 为止。
您的应用可以完全自行控制权限对话框的显示时间。您可以借此机会向用户说明应用需要此权限的原因,进而鼓励他们授予该权限。
- 如果您的应用以 12L 或更低版本为目标平台,则临时授权将一直有效,直到用户在通知权限运行时对话框中明确选择一个选项。也就是说,如果用户在未做出选择的情况下关闭了权限提示,系统会保留应用的临时授权。
3.2.1.5 获得临时授权的资格要求
您的应用要获得临时授权必须满足以下条件:应用必须已具有通知渠道,并且用户未在搭载 12L 或更低版本的设备上明确停用应用的通知。
如果用户在搭载 12L 或更低版本的设备上停用了应用的通知,当设备升级到 Android 13 或更高版本后,该停用会继续有效。
3.2.1.6 豁免
与媒体会话有关的通知不受此行为变更的影响。
3.2.1.7 最佳做法
本部分将介绍几种在应用中最有效地使用新通知权限的方式。
a. 更新应用的目标 SDK 版本
为了让应用更灵活地显示权限对话框,请将应用更新为以 Android 13 为目标平台。
b. 等待一段时间再显示通知权限提示
等到用户熟悉您的应用之后,再请求他们授予任何权限。
新用户可能想要探索您的应用,并切身体会每项通知请求可以带来的好处。您可以通过用户操作触发权限提示。下面列举了几个适合显示通知权限提示的时机:
- 用户点按“提醒铃铛”按钮时。
- 用户选择关注他人的社交媒体帐号时。
- 用户提交外卖订单时。
下图显示了请求通知权限的建议工作流程。或者,您也可以设置一个请求以在应用启动时显示,但仅在应用第 3 次或第 4 次启动后才显示。
c. 在上下文中请求权限
在应用内请求通知权限时,请在正确的上下文中请求,以便用户明确了解通知的用途以及应该选择接收通知的原因。例如,电子邮件应用可能包含为每封新邮件发送通知的选项,或仅为用户是唯一收件人的邮件发送通知的选项。
借此机会明确向用户表明您的意图,有助于鼓励用户向您的应用授予通知权限。
d. 检查您的应用能否发送通知
用户必须为您的应用启用通知,您的应用才能发送通知。要确认用户是否已启用通知,请调用areNotificationsEnabled()。
e. 以负责任的方式使用权限
获得发送通知的许可后,请负责任地使用该权限。用户可以查看您的应用每天发送的通知数量,并且可以随时撤消该权限。
3.2.2 针对附近 Wi-Fi 设备的新运行时权限
Android 13 引入了NEARBY_WIFI_DEVICES
运行时权限,该权限属于NEARBY_DEVICES权限组,适用于会管理设备与附近 Wi-Fi 接入点连接情况的应用。借助此权限,您可以更轻松地说明应用为何访问附近的 Wi-Fi 设备;在以前的 Android 版本中,这类应用需要声明ACCESS_FINE_LOCATION权限。
如果您的应用以 Android 13 为目标平台并调用多个不同的 Wi-Fi API,则必须从用户处获得这项新权限。
如果您的应用尝试在未获得适当权限的情况下调用 Wi-Fi API,则会发生SecurityException。
3.2.2.1 受影响的用例
这项新权限会影响几个不同的 Wi-Fi 用例,包括以下用例:
- 查找或连接到附近的设备,如打印机或媒体投射设备。通过该工作流,您的应用可以完成以下类型的任务: 通过带外方式(例如通过 BLE)接收 AP 信息。
- 使用仅限本地使用的热点,通过 Wi-Fi 感知和连接功能发现并连接到设备。
- 通过 Wi-Fi 直连发现和连接到设备。
- 发起与已知 SSID(例如汽车或智能家居设备)的连接。
- 开启仅限本地使用的热点。
- 连接到附近的 Wi-Fi 感知设备。
3.2.2.2 该权限属于“附近的设备”权限组
NEARBY_WIFI_DEVICES权限是
附近的设备
权限组的一部分。此权限组在 Android 12(API 级别 31)中添加,还包含与蓝牙和超宽带相关的权限。如果您的应用请求此权限组中的多项权限,用户会看到一个运行时对话框,其中会请求用户批准您的应用访问附近的设备。在系统设置中,用户必须以组的形式启用和停用附近的设备权限;例如,针对给定应用,用户无法既停用其 Wi-Fi 访问权限,但又保持启用其蓝牙使用权限。
3.2.2.3 坚定地声明您的应用不会推导物理位置
在以 Android 13 为目标平台时,请考虑您的应用是否会通过 Wi-Fi API 推导物理位置;如果不会,则应坚定声明此情况。如需做出此声明,请在应用的清单文件usesPermissionFlags属性设为neverForLocation,如以下代码段所示。此过程类似于您声明绝不会将蓝牙设备信息用于获取位置信息时的过程:
<manifest ...>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> <application ...>
...
</application>
</manifest>
3.2.2.4 保持后向兼容性
由于NEARBY_WIFI_DEVICES权限仅适用于 Android 13 或更高版本,因此您应保留对ACCESS_FINE_LOCATION的所有声明,以便在您的应用中提供向后兼容性。不过,只要您坚定声明应用不会使用 Wi-Fi API 推导物理位置信息,就可以将此权限的最高 SDK 版本设为32,如下以下代码段所示:
<manifest ...>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="32" /> <application ...>
...
</application>
</manifest>
3.2.2.5 某些 API 仍需要位置信息权限
有几个 Wi-Fi API 仍然需要ACCESS_FINE_LOCATION权限才能获取位置信息,就像它们在 12L 及更低版本上的一样。示例包括WifiManager类中的以下方法:
- app打包
- getScanResults()
- startScan()
3.2.2.6 检查需要新权限的 API
如果您的应用以 Android 13 或更高版本为目标平台,您必须声明NEARBY_WIFI_DEVICES权限才能调用以下任何 Wi-Fi API:
- WifiManager startLocalOnlyHotspot()
- WifiAwareManager attach()
- WifiAwareSession publish()
- subscribe()
- WifiP2pManager addLocalService()
- connect()
- createGroup()
- discoverPeers()
- discoverServices()
- requestDeviceInfo()
- requestGroupInfo()
- requestPeers()
- WifiRttManager startRanging()
3.2.3 在后台使用身体传感器需要新的权限
Android 13 中引入了“在使用时”访问身体传感器(例如心率、体温和血氧饱和度)的概念。此访问模式与Android 10(API 级别 29)系统为位置信息引入的模式非常相似。
如果您的应用以 Android 13 为目标平台,并且在后台运行时需要访问身体传感器信息,那么除了现有的BODY_SENSORS权限外,您还必须声明新的BODY_SENSORS_BACKGROUND权限。注意
:这是受到“硬性限制”的权限,除非设备的安装程序针对您的应用将该权限列入了许可名单,否则您的应用将无法获得此权限。如需了解详情,请参阅有关受限权限的指南。
3.2.4 intent 过滤器会屏蔽不匹配的 intent
当您的应用向以 Android 13 或更高版本为目标平台的其他应用的导出组件发送 intent 时,仅当该 intent 与接收应用中的<intent-filter>元素匹配时,系统才会传送该 intent。换言之,系统会屏蔽所有不匹配的 intent,但以下情况除外:
- 发送给其他应用的未声明任何 intent 过滤器的组件的 intent。
- 发送给您应用中的其他组件的 intent。
- 由系统发送的 intent。
- 由具有根级特权的用户发送的 intent。
3.2.5 更安全地导出上下文注册的接收器
为了帮助提高运行时接收器的安全性,Android 13 允许您指定您应用中的特定广播接收器是否应被导出以及是否对设备上的其他应用可见。如果导出广播接收器,其他应用将可以向您的应用发送不受保护的广播。此导出配置在以 Android 13 或更高版本为目标平台的应用中可用,有助于防止一个主要的应用漏洞来源。
在以前的 Android 版本中,设备上的任何应用都可以向动态注册的接收器发送不受保护的广播,除非该接收器受签名权限的保护。
要实现此安全增强措施,请执行以下操作:
a. 启用DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED兼容性框架更改。
b. 在应用的每个广播接收器中,明确指明其他应用是否可以向其发送广播,如以下代码段所示:
// 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);
注意
:如果启用了DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED
兼容性框架更改,则必须
为每个广播接收器指定RECEIVER_EXPORTED或
RECEIVER_NOT_EXPORTED。否则,当您尝试注册广播接收器时,系统会抛出
SecurityException
。
为了帮助检测这种情况,Android Studio 将会采用一个 lint 规则,而即将发布的ContextCompat将会检查接收器配置是否正确。
编辑:yimen,如若转载,请注明出处:https://www.yimenapp.com/kb-yimen/12710/
部分内容来自网络投稿,如有侵权联系立删