行为变化:以 Android 14 或更高版本为目标平台的应用
与早期版本一样,Android 14 包含可能会影响应用的行为更改。以下行为更改仅适用于以 Android 14 或更高版本为目标平台的应用。如果您的应用以 Android 14 或更高版本为目标平台,则应修改应用以正确支持这些行为(如适用)。
如果您的应用以 Android 14 为目标平台,则必须为应用中的每个前台服务指定至少一种前台服务类型。您应该选择代表应用用例的前台服务类型。系统期望具有特定类型的前台服务满足特定用例。
注意:Android 14 为运行状况和远程消息传递用例引入了前台服务类型。该系统还为短期服务、特殊用例和系统豁免保留了新类型。
如果应用中的用例未与任何这些类型相关联,强烈建议您迁移逻辑以使用 WorkManager 或 user-user-initiated data。
Android 14 继续更新 Android 的核心库,以与最新 OpenJDK LTS 版本中的功能保持一致,包括库更新和面向应用和平台开发人员的 Java 17 语言支持。
其中一些更改可能会影响应用兼容性:
IllegalArgumentException
的新情况,因此请确保测试您的应用程序是否存在使用正则表达式的区域。若要在测试时启用或禁用此更改,请使用兼容性框架工具切换 DISALLOW_INVALID_GROUP_REFERENCE
标志.IllegalArgumentException
。若要在测试时启用或禁用此更改,请使用WorkManager切换 ENABLE_STRICT_VALIDATION
标志.对于以 Android 14 为目标平台的应用,Android 会通过以下方式限制应用向内部应用组件发送隐式意图:
这些更改可防止恶意应用拦截供应用内部组件使用的隐式意图。
例如,下面是可以在应用的清单文件中声明的 Intent 过滤器:例如,下面是可以在应用的清单文件中声明的 Intent 过滤器:
<activity
android:name=".AppActivity"
android:exported="false">
<intent-filter>
<action android:name="com.example.action.APP_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
intent-filter>
activity>
如果您的应用尝试使用隐式意图启动此活动,则会引发异常:
// Throws an exception when targeting Android 14.
context.startActivity(new Intent("com.example.action.APP_ACTION"));
要启动非导出活动,您的应用应改用显式 Intent:
// This makes the intent explicit.
Intent explicitIntent =
new Intent("com.example.action.APP_ACTION")
explicitIntent.setPackage(context.getPackageName());
context.startActivity(explicitIntent);
以 Android 14 为目标平台并使用上下文注册接收器的应用和服务需要指定一个标志,以指示是否应将接收器导出到设备上的所有其他应用:RECEIVER_EXPORTED或RECEIVER_NOT_EXPORTED。此要求通过利用 Android 13 中引入的这些接收器的功能来帮助保护应用免受安全漏洞的影响.
仅接收系统广播的接收器的例外情况
如果你的应用仅通过 Context#registerReceiver 方法(如 Context#registerReceiver()为系统广播注册接收器,则在注册接收器时不应指定标志。Context#registerReceiver
如果您的应用以 Android 14 为目标平台并使用动态代码加载 (DCL),则必须将所有动态加载的文件标记为只读。否则,系统将引发异常。我们建议应用尽可能避免动态加载代码,因为这样做会大大增加应用因代码注入或代码篡改而受到损害的风险。
如果必须动态加载代码,请使用以下方法在打开文件后和写入任何内容之前将动态加载的文件(如 DEX、JAR 或 APK 文件)设置为只读:
File jar = new File("DYNAMICALLY_LOADED_FILE.jar");
try (FileOutputStream os = new FileOutputStream(jar)) {
// Set the file to read-only first to prevent race conditions
jar.setReadOnly();
// Then write the actual file content
} catch (IOException e) { ... }
PathClassLoader cl = new PathClassLoader(jar, parentClassLoader);
为了防止为现有的动态加载文件引发异常,我们建议先删除并重新创建这些文件,然后再尝试在应用中再次动态加载这些文件。重新创建文件时,请按照前面的指南在写入时将文件标记为只读。或者,你可以将现有文件重新标记为只读,但在这种情况下,我们强烈建议你先验证文件的完整性(例如,根据受信任的值检查文件的签名),以帮助保护你的应用免受恶意操作的侵害。
对于面向 Android 14 的应用,Android 通过以下方式防止 Zip 路径遍历漏洞:如果 zip 文件条目名称包含“..”或以“/”开头,则 ZipFile(String)) 和 ZipInputStream.getNextEntry() 会引发 ZipException。
应用可以通过调用 dalvik.system.ZipPathValidator.clearCallback() 来选择退出此验证.
对于以 Android 14 为目标平台的应用,系统会进一步限制何时允许应用从后台启动活动:
这些更改扩展了现有的一组限制,通过防止恶意应用滥用 API 从后台启动破坏性活动来保护用户。
Android 14 包含基于与 Android 开发者合作和最新内部测试的受限非 SDK 接口的更新列表。在限制非 SDK 接口之前,我们会尽可能确保公共替代方案可用。
如果您的应用未定位到 Android 14,则其中一些更改可能不会立即对您产生影响。但是,虽然您目前可以使用某些非 SDK 接口(具体取决于应用的目标 API 级别),但使用任何非 SDK 方法或字段始终存在破坏应用的高风险。
如果您不确定您的应用是否使用非 SDK 接口,可以测试您的应用以了解。如果您的应用依赖于非 SDK 接口,则应开始计划迁移到 SDK 替代方案。不过,我们理解某些应用具有使用非 SDK 接口的有效用例。如果您找不到对应用中的功能使用非 SDK 接口的替代方法,则应请求新的公共 API.
要详细了解此版本的 Android 中的更改,请参阅 Android 14 中非 SDK 接口限制的更新。要了解有关非 SDK 接口的更多信息,请参阅对非 SDK 接口的限制.