Android 14 平台包含一些行为变更,这些变更可能会影响您的应用。以下行为变更将影响在 Android 14 上运行的所有应用,无论采用哪种 targetSdkVersion
都不例外。您应该测试您的应用,然后根据需要进行修改,以适当地支持这些变更。
此外,请务必查看仅影响以 Android 14 为目标平台的应用的行为变更列表。
核心功能
默认拒绝设定精确的闹钟
精确的闹钟适用于用户指定的通知,或是在确切时间需要执行的操作。从 Android 14 开始,系统不再向以 Android 13 及更高版本为目标平台的大多数新安装应用预先授予 SCHEDULE_EXACT_ALARM
权限,该权限默认处于拒绝状态。
详细了解安排精确闹钟的权限变化。
当应用进入缓存时,上下文注册的广播将加入队列
在 Android 14 中,当应用处于缓存状态时,系统可以将上下文注册的广播放入队列中。这与 Android 12(API 级别 31)为异步 binder 事务引入的队列行为类似。在清单中声明的广播不会加入队列,并且应用会从缓存状态中移除以进行广播传递。
当应用离开缓存状态(例如返回前台)时,系统会传递所有已加入队列的广播。某些广播的多个实例 可能会合并为一个广播。取决于其他因素,如系统 运行状况,则可能会从缓存状态中移除应用,以及之前排队 广播。
应用只能终止自己的后台进程
从 Android 14 开始,当您的应用调用 killBackgroundProcesses()
时,该 API 只能终止您自己应用的后台进程。
如果您传入另一个应用的软件包名称,此方法对该应用的后台进程没有影响,并且 Logcat 中会显示以下消息:
Invalid packageName: com.example.anotherapp
您的应用不应使用 killBackgroundProcesses()
API,也不得以其他方式尝试影响其他应用的进程生命周期,即使在旧版操作系统上也是如此。Android 旨在让缓存应用在后台运行,并在系统需要内存时自动终止它们。如果您的应用会不必要地终止其他应用,则由于之后需要完全重启这些应用,因此可能会降低系统性能并增加耗电量,这比恢复现有缓存应用所消耗的资源要多得多。
第一个请求 MTU 的 GATT 客户端的 MTU 设置为 517
从 Android 14 开始,Android 蓝牙堆栈会更严格地遵循蓝牙核心规范 5.2 版,当第一个 GATT 客户端使用 BluetoothGatt#requestMtu(int)
API 请求 MTU 时,会请求将 BLE ATT MTU 设置为 517 个字节,并忽略针对该 ACL 连接的所有后续 MTU 请求。
如需解决此变更并提高应用的稳健性,请考虑以下选项:
- 您的外围设备应使用可由外围设备适应的合理值来响应 Android 设备的 MTU 请求。最终商定的值将为 Android 请求的值和远程提供的值(例如
min(517, remoteMtu)
)中的最小值- 实现此修复可能需要更新外围设备的固件
- 或者,根据外围设备的已知受支持值与接收到的 MTU 变化之间的最小值限制 GATT 特征写入
- 温馨提示:您应该在支持的标头大小的基础上减少 5 个字节
- 例如:
arrayMaxLength = min(SUPPORTED_MTU, GATT_MAX_ATTR_LEN(517)) - 5
应用被放入受限待机模式存储分区的新原因
Android 14 引入了将应用放入“受限待机”分桶的新原因。由于 onStartJob
、onStopJob
或 onBind
方法超时,应用的作业会多次触发 ANR 错误。(如需了解对 onStartJob
和 onStopJob
的更改,请参阅 JobScheduler 增强回调和网络行为。)
如需跟踪应用是否已进入“受限待机”分桶,我们建议您在作业执行时使用 API UsageStatsManager.getAppStandbyBucket()
进行日志记录,或者在应用启动时使用 UsageStatsManager.queryEventsForSelf()
进行日志记录。
mlock 限制为 64 KB
在 Android 14(API 级别 34)及更高版本中,平台将可使用 mlock()
锁定的最大内存减少为每个进程 64 KB。在以前的版本中,每个进程的大小上限为 64 MB。此限制可促进跨应用和系统更好地管理内存。为了提高各设备之间的一致性,Android 14 针对兼容设备上的新 mlock()
限制添加了新的 CTS 测试。
系统强制执行缓存应用资源使用
从设计上讲,当应用的进程移至后台且没有任何其他应用进程组件在运行时,应用进程将处于缓存状态。此类应用进程可能会因系统内存压力而终止。在此状态下,Activity
实例在调用并返回 onStop()
方法后执行的任何工作均不可靠,强烈建议不要这样做。
Android 14 对此设计引入了一致性和强制执行要求。在应用进程进入缓存状态后不久,系统会禁止后台工作,直到进程组件重新进入生命周期的活跃状态。
使用框架支持的典型生命周期 API(例如服务、JobScheduler
和 Jetpack WorkManager)的应用应该不受这些变化的影响。
用户体验
关于不可关闭通知用户体验方式的变更
如果您的应用向用户显示不可关闭的前台通知,请注意:Android 14 已更改此行为,允许用户关闭此类通知。
这项变更适用于阻止用户关闭前台的应用
将 Notification.FLAG_ONGOING_EVENT
设置为
Notification.Builder#setOngoing(true)
或
NotificationCompat.Builder#setOngoing(true)
。FLAG_ONGOING_EVENT
的行为已发生变化,使用户实际上能够关闭此类通知。
在以下情况下,此类通知仍不可关闭:
- 当手机处于锁定状态时
- 如果用户选择全部清除通知操作(有助于防止意外关闭)
此外,这一新行为不适用于以下用例中的通知:
CallStyle
条通知- 企业设备政策控制器 (DPC) 和支持软件包
- 媒体通知
- 默认的搜索选择器软件包
数据安全信息更显眼
为了加强用户隐私保护,Android 14 增加了系统显示您在 Play 管理中心表单中声明的信息的位置数量。目前,用户可以在 Google Play 中的应用详情的数据安全部分查看此信息。
我们建议您查看应用的位置数据分享政策,并花一点时间对应用的 Google Play“数据安全”部分进行任何适用的更新。
如需了解详情,请参阅有关如何在 Android 14 上以更显眼的方式显示数据安全信息的指南。
无障碍
非线性字体放大至 200%
从 Android 14 开始,系统支持字体放大高达 200%,为弱视用户提供了符合网络内容无障碍指南 (WCAG) 的其他无障碍功能选项。
如果您已使用放大像素 (sp) 单位来定义文本大小,这项更改可能不会对您的应用产生太大影响。不过,您应在启用最大字号 (200%) 的情况下执行界面测试,确保应用能够在不影响易用性的情况下适应较大的字号。
安全
最低可安装的目标 API 级别
从 Android 14 开始,targetSdkVersion
低于 23 的应用无法安装。要求应用满足这些最低目标 API 级别要求有助于提高用户的安全性和隐私性。
恶意软件通常会以较旧的 API 级别为目标平台,以绕过在较新版本 Android 中引入的安全和隐私保护机制。例如,有些恶意软件应用使用 targetSdkVersion
22,以避免受到 Android 6.0 Marshmallow(API 级别 23)在 2015 年引入的运行时权限模型的约束。这项 Android 14 变更使恶意软件更难以规避安全和隐私权方面的改进限制。尝试安装以较低 API 级别为目标平台的应用将导致安装失败,并且 Logcat 中会显示以下消息:
INSTALL_FAILED_DEPRECATED_SDK_VERSION: App package must target at least SDK version 23, but found 7
在升级到 Android 14 的设备上,targetSdkVersion
低于 23 的所有应用都将继续保持安装状态。
如果您需要测试以旧版 API 级别为目标平台的应用,请使用以下 ADB 命令:
adb install --bypass-low-target-sdk-block FILENAME.apk
媒体所有者软件包名称可能会隐去
The media store supports queries for the OWNER_PACKAGE_NAME
column, which
indicates the app that stored a particular media file. Starting in Android
14, this value is redacted unless at least one of the following conditions is
true:
- The app that stored the media file has a package name that is always visible to other apps.
The app that queries the media store requests the
QUERY_ALL_PACKAGES
permission.
Learn more about how Android filters package visibility for privacy purposes.