Android 14 适配指引
随着移动操作系统的不断进化,Google Play 对应用的 targetSdkVersion 也有新的要求。
自2024年8月31日起,新应用和应用更新必须以 Android 14(API 级别 34)或更高版本为目标平台,才能提交到 Google Play。
另外如果需要更多时间来更新应用,可申请延期至2024年11月1日。如有需要,请关注 Google Play Console 的延期表单,一般可在应用管理页的 Inbox 中找到。
更多详情,请参见 Google Play 应用在目标 API 级别方面需满足的要求。
本文旨在为希望将其项目 targetSdkVersion 升级到 34 的开发者提供 API 级别 34 的变更与影响面,同时还有对影响点的排查方法以及修改方案,将帮助您确保您的应用在 Android 14 上获得良好的体验。
为避免编译报错的问题,需将 compileSdkVersion 和 targetSdkVersion 都升级到 34。
Android 14 行为变更影响点排查
下面列出了可能会影响游戏开发者的功能和行为变更,如需关注 Android 14 的所有变更,请查阅:https://developer.android.com/about/versions/14/summary
对隐式和待处理 intent 的限制
对于 targetSdkVersion=34 的应用,隐式 intent 的行为在 Android 14 上有以下限制:
- 隐式 intent 只能传送到导出的组件。应用必须使用显式 intent 传送到未导出的组件,或将该组件标记为已导出。
- 如果应用通过未指定 component 或 package 的 intent 创建 可变
PendingIntent,系统会抛出异常。
排查方法
业务可以通过 解包 APK 产物,查看 AndroidManifest 中是否包含同时符合以下条件的组件声明:
- Android 组件声明包含属性
android:exported="false" - Android 组件声明中包含自定义
action的intent-filter
如有同时符合上述条件的组件声明,则有可能存在隐式 intent 启动组件的行为,届时请联系 [diemliang(梁世宇)] 做进一步排查。
示例代码:
<service android:name="com.example.ExampleService"
android:exported="false">
<intent-filter>
<action android:name="com.example.EXAMPLE_ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
运行时注册的广播接收器 必须指定导出标志
广播接收器通常用于监听设备状态变更如网络状态切换、手机电量变化等,是一个特别常用的功能。
对于 targetSdkVersion=34 的应用,在运行时通过 Context 注册的 BroadcastReceiver 必须在参数中指定其导出属性,否则会抛出异常。
排查方法
业务可以通过 解包 APK 产物,搜索 smali 文件中是否包含以下关键代码:
Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;
如有,则表示该处逻辑涉及使用 Context 注册 BroadcastReceiver,届时请联系 [diemliang(梁世宇)] 并提供 smali 文件做进一步排查。
使用 Unity 2020 以及更早版本的业务,请参见 Unity。
压缩路径验证
对于 targetSdkVersion=34 的应用,如果 zip 文件条目名称包含 “..” 或以 “/” 开头,则 ZipFile(String) 和 ZipInputStream.getNextEntry() 会抛出 ZipException。
此举是为了防止 Zip 路径遍历漏洞。
排查方法
业务可以通过 解包 APK 产物,搜索 smali 文件中是否包含以下关键代码:
Ljava/util/zip/ZipFile;-><init>(Ljava/lang/String;)V
Ljava/util/zip/ZipInputStream;->getNextEntry()Ljava/util/zip/ZipEntry;
如有,则表示业务涉及使用 ZipFile, ZipInputStream,需要排查使用此接口的功能在 Android 14 运行是否正常。
使用上述接口进行解压的压缩包中,压缩文件的路径如果包含 ".." 或以 "/" 开头,建议修改压缩包的结构以及解压方式。届时请联系 [diemliang(梁世宇)] 做进一步排查。
每个 MediaProjection Capture Session 需要征得用户同意
对于 targetSdkVersion=34 的应用,您的应用必须在每次 Capture Session 之前征求用户同意。单次 Capture Session 只能是 MediaProjection#createVirtualDisplay 的单次调用,且每个 MediaProjection 实例只能使用一次。
该 API 为屏幕录制相关接口,常见于录制玩家精彩操作。
排查方法
业务可以通过 解包 APK 产物,搜索 smali 文件中是否包含以下关键代码:
Landroid/media/projection/MediaProjection;->createVirtualDisplay(
Landroid/media/projection/MediaProjectionManager;->createScreenCaptureIntent()
如有,则表示业务涉及使用 MediaProjection,需要排查使用此接口的功能在 Android 14 运行是否正常,重点关注单次运行内多次进入使用此接口的功能的场景是否正常。届时请联系 [diemliang(梁世宇)] 做进一步排查。
前台服务必须定义类型
在游戏中打开 Google 登录或 WebView 等内容时,游戏进程会进入后台状态并可能会被系统关闭。为了避免此问题,您可为游戏设置前台服务的权限。
对于使用前台服务的 targetSdkVersion=34 应用,应用必须为每项前台服务指定至少一个前台服务类型。您应该选择一个能够代表应用用例的前台服务类型。系统需要特定类型的前台服务满足特定用例。
您也需在 Google Play Console 的 应用内容 > 前台服务权限 内提交前台服务声明。例如,如果您的应用使用了 WebView 的功能,在页面选择 其他,然后添加简单说明以及应用在游戏中打开 WebView 的视频 URL。

有关可选择的前台服务类型,请参见 前台服务类型是必需的。
排查方法
业务可以通过 解包 APK 产物,搜索 smali 文件中是否包含以下关键代码,确定是否有使用前台服务:
->startForeground(ILandroid/app/Notification;)V
->startForeground(ILandroid/app/Notification;I)V
如有,则需要在 AndroidManifest.xml 中查看对应的 Service 定义,是否包含 android:foregroundServiceType 属性且类型合理。届时请联系 [diemliang(梁世宇)] 做进一步排查。
示例代码:
<!-- AndroidManifest.xml -->
<manifest ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 添加对应的 特定权限,此处示例为 mediaPlayback 所对应的权限:FOREGROUND_SERVICE_MEDIA_PLAYBACK -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<application ...>
<!-- 在 service 中定义 foregroundServiceType -->
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
移除前台服务权限方法
- Unity
- Unreal Engine
在 <ProjectDir>/Assets/Plugins/Android/AndroidManifest.xml 中的 <manifest> 节点下增加 xmlns:tools 和 <uses-permission> 声明:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.intlgame.demo">
...
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove" />
在 <ProjectDir>/Source/<ProjectName><ProjectName>_UPL_Android.xml 中的 <root> 节点下增加 xmlns:tools 和 <uses-permission> 声明:
<root xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<addElements tag="manifest">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" tools:node="remove" />
</addElements>
tools:node="remove" 语句将使该权限被移除。
开发环境适配修改点
- Unity
- Unreal Engine
Unity 2020 以及更老的版本,UnityPlayerActivity#onCreate 会使用到不指定导出标记的 registerReceiver 方法,这会导致 Unity 2020 以及更老的版本在尝试升级 targetSdkVersion 到 34 后,在 Android 14 上无法正常运行。
建议将 Unity 升级至修复了该问题的 LTS 版本或以上:
- 2021.3.33f1
- 2022.3.13f1
- 2023.1.20f1
- 2023.3.0a11
更多详情,请参见在 Unity Issue Tracker 中提出的这封 错误报告。

将游戏设置为针对 Android API 级别 34,在 Unreal Engine 升级 targetSdkVersion:
- 在你的 Unreal Engine 项目中,找到 Config 文件夹,然后打开
DefaultEngine.ini文件; - 在
DefaultEngine.ini文件中,你需要添加或修改以下行来设置targetSdkVersion:
TargetSDKVersion=34
SDKAPILevelOverride=android-34
- 修改完成后,保存并关闭
DefaultEngine.ini文件。
升级 Android Gradle Plugin (AGP)
- Unity
- Unreal Engine
根据谷歌官方文档 特定 Android API 级别所要 求的最低工具版本 中的说明,当应用 targetSdkVersion=34 时,AGP 版本的最低要求为 8.1.1。
实际验证发现,使用 7.1.2 即可满足当前版本编译需求,无需升到跨度更高的 8.1.1。
- 对于 Unity 2022.2 及更高版本,因其默认的 AGP 版本已符合要求,无需处理
- 对于 Unity 2022.2 以下的版本,需要参考以下步骤升级 AGP
升级 Gradle Wrapper 版本
-
在 Editor 菜单 Unity > Settings > External Tools 中找到 Gradle installed with Unity 选项并取消勾选后,在下方 Gradle 路径中选择设备的
gradle-7.2-bin的路径,如:
-
修改环境变量,将环境变量
GRADLE_HOME设置为 Gradle 7.2 版本的路径:# sh
export GRADLE_HOME=/Users/***/.gradle/wrapper/dists/gradle-7.2-bin/****/gradle-7.2
export PATH=${PATH}:${GRADLE_HOME}/bin
修改 AGP 版本依赖
升级至 Player Network SDK V1.24 后,Assets/Plugins/Android/baseProjectTemplate.gradle 中已经将 AGP 升级到 7.1.2 版本,无需修改。
查看 Assets/Plugins/Android/baseProjectTemplate.gradle 文件中的 "com.android.tools.build:gradle:x.x.x",如果版本低于 7.1.2,需要修改至 7.1.2。否则无需修改。

根据谷歌官方文档 特定 Android API 级别所要求的最低工具版本 中的说明,当应用 targetSdkVersion=34 时,AGP 版本的最低要求为 8.1.1。
实际验证发现,使用 7.1.2 即可满足当前版本编译需求,无需升到跨度更高的 8.1.1。
参考以下步骤升级 AGP:
升级 Gradle Wrapper 版本
-
下载 gradle-7.2-bin.zip 并解压;
-
修改环境变量
GRADLE_HOME到gradle-7.2-bin的解压路径:# sh
export GRADLE_HOME=/Users/***/.gradle/wrapper/dists/gradle-7.2-bin/****/gradle-7.2
export PATH=${PATH}:${GRADLE_HOME}/bin -
修改引擎中的
/Engine/Build/Android/Java/gradle/gradle/wrapper/gradle-wrapper.properties文件, 将distributionUrl改为 Gradle 7.2 的 URL:distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip