Google官方要求新、老app在一定时间要求内需要面向Android 12、Android 13构建,不然不给app过审。我们之前是面向Android API 30构建的,现在需要支持面向Android API 33构建。
https://developer.android.com/about/versions
https://support.google.com/googleplay/android-developer/answer/11926878
在支持Android 13的时候遇到了很多问题,在此做下记录,提供参考。
unity-android和gradle升级_蝶泳奈何桥.的博客-CSDN博客_unity升级gradle
我们项目是基于Unity 2018.4.36f1开发的,以下修改和问题都基于该Unity版本,高版本Unity遇到的问题可能会有些许不一样。
Gradle下载地址:https://gradle.org/releases/
下载完后在Unity的Preferences/External Tools中设置Unity打包时所用的Gradle Version。
将 %ANDROID_SDK%\build-tools\33.0.0 目录下的 d8.bat 改成 dx.bat
将 %ANDROID_SDK%\build-tools\33.0.0\lib 目录下的 d8.jar 改成 dx.jar
修改Android工程中对应的compileSdkVersion和targetSdkVersion到33。
生成对应的jar或aar包(根据自己项目来定)
如果需要构建aab,则需要在mainTemplate.gradle后添加task来处理生成的aab。(详见问题十一)
AndroidManifest中,所有包含 intent-filter 的 service、receiver、activity 都加上android:exported="true"或android:exported=“false”。(详见问题五)
修改项目中所有PendingIntent.getActivity和PendingIntent.getBroadcast方法。(详见问题六、问题八、问题九)
添加PendingIntent.FLAG_IMMUTABLE或PendingIntent.FLAG_MUTABLE。
PendingIntent pendingIntent = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);else pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
解决Unity在Android13只调用Awake不调用Start的问题。
如遇打包失败、游戏闪退崩溃、游戏报错等问题,请参考下面的记录。
Unity构建Android API 33时报错:
Exception:CommandInvokationFailure: Gradle build failed. @/Applications/Unity2018.4.36_inter/PlaybackEngines/AndroidPlayer/Tools/OpenJDK/MacOS/bin/java -classpath “/Applications/Unity2018.4.36_inter/PlaybackEngines/AndroidPlayer/Tools/gradle/lib/gradle-launcher-5.1.1.jar” org.gradle.launcher.GradleMain “-Dorg.gradle.jvmargs=-Xmx4096m” “assembleRelease”@@stderr[@编译器 (1.8.0-adoptopenjdk) 中出现异常错误。如果在 Bug Database (http://bugs.java.com) 中没有找到该错误, 请通过 Java Bug 报告页 (http://bugreport.java.com) 建立该 Java 编译器 Bug。请在报告中附上您的程序和以下诊断信息。谢谢。@java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable N a m e I m p l ) @ a t c o m . s u n . t o o l s . j a v a c . u t i l . A s s e r t . e r r o r ( A s s e r t . j a v a : 133 ) @ a t c o m . s u n . t o o l s . j a v a c . c o d e . T y p e A n n o t a t i o n s . a n n o t a t i o n T y p e ( T y p e A n n o t a t i o n s . j a v a : 231 ) @ a t c o m . s u n . t o o l s . j a v a c . c o d e . T y p e A n n o t a t i o n s NameImpl)@ at com.sun.tools.javac.util.Assert.error(Assert.java:133)@ at com.sun.tools.javac.code.TypeAnnotations.annotationType(TypeAnnotations.java:231)@ at com.sun.tools.javac.code.TypeAnnotations NameImpl)@atcom.sun.tools.javac.util.Assert.error(Assert.java:133)@atcom.sun.tools.javac.code.TypeAnnotations.annotationType(TypeAnnotations.java:231)@atcom.sun.tools.javac.code.TypeAnnotationsTypeAnnotationPositions.separateAnnotationsKinds(TypeAnnotations.java:294)@…
使用JDK11版本来构建可以解决该问题。但是我们目前使用的是Unity 2018.4.36f1,不支持使用JDK11版本构建。
记录下问题解决:annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.SharedN
Unity官网说了,只有2020版本的unity才准备去支持JDK11,老版本一律不支持。
经过查询,发现需要修改Unity构建时的Gradle版本。
unrecognized Attribute name MODULE (class com.sun.tools.javac.util.SharedNameTable$NameImpl)
Question - Must target API level 31
Resolved - Target API 31 Issues and Solutions
https://developers.google.com/ar/develop/unity-arf/android-12-build
最终解决方案为:
修改Unity打包时的Gradle Version为6.1.1,Gradle Plugin Version为4.0.1。
Gradle下载地址:https://gradle.org/releases/
下载完后在Unity的Preferences/External Tools中设置Unity打包时所用的Gradle Version。
之后修改Unity工程中的mainTemplate.gradle,将Gradle Plugin Version改为4.0.1。
打包时报错:
FAILURE: Build failed with an exception.
- Where:
Build file ‘C:\Project\PiggyGO\Temp\gradleOut\build.gradle’ line: 242
- What went wrong:
A problem occurred configuring root project ‘gradleOut’.
Could not get unknown property ‘additionalParameters’ for task ‘:dexBuilderDebug’ of type com.android.build.gradle.internal.tasks.DexArchiveBuilderTask.
- Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
- Get more help at https://help.gradle.org
查到是multidex的问题。
Android Studio最全面编译构建优化!!!_Nbin_Newby的博客-程序员宝宝_android studio 多核编译 - 程序员宝宝
最终解决方案为:
去掉第三方的multidex及其关联代码。
打包时报错:
FAILURE: Build failed with an exception.
- What went wrong:
Could not determine the dependencies of task ‘:compileReleaseJavaWithJavac’.
Installed Build Tools revision 33.0.0 is corrupted. Remove and install again using the SDK Manager.
修改安卓SDK目录下的BuildTools-33.0.0部分文件名称。
unity-android和gradle升级_蝶泳奈何桥.的博客-CSDN博客
Android Studio error “Installed Build Tools revision 31.0.0 is corrupted”
将 %ANDROID_SDK%\build-tools\33.0.0 目录下的 d8.bat 改成 dx.bat
将 %ANDROID_SDK%\build-tools\33.0.0\lib 目录下的 d8.jar 改成 dx.jar
打包时报错:
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:lintVitalRelease’.
Lint infrastructure error
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.android.tools.lint.gradle.api.ReflectiveLintRunner.runLint(ReflectiveLintRunner.kt:38)
at com.android.build.gradle.tasks.LintBaseTask.runLint(LintBaseTask.java:114)
at
在mainTemplate.gradle中添加 checkReleaseBuilds false。
Error: Execution failed for task ‘:app: lintVitalRelease’ any one can solve it?
安装时报错:
adb: failed to install C:\Project\PiggyGO\Build\PiggyTravel_Android_4.4.0.1.apk: Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI: /data/app/vmdl661069248.tmp/base.apk (at Binary XML file line #112): com.aladinfun.piggytravel.android.MainActivity: Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined when intent filters are present]
Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined
https://developer.android.com/about/versions/12/behavior-changes-12#exported
Android 12 已来,你的 App 崩溃了吗? - 掘金
项目AndroidManifest中,所有包含 intent-filter 的 service、receiver、activity 都加上 android:exported=“true” 或 android:exported=“false”
上面加了自定义的是ok了,但是还有一个Unity隐藏的:
com.unity.androidnotifications.UnityNotificationRestartOnBootReceiver: Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined when intent filters are present
Mobile notifications are breaking android 12 builds
如果在装包时,出现上述报错,那么还需要在AndroidManifest中增加下述代码:
进入后崩溃:
--------- beginning of crash
2022-10-11 11:59:03.874 17946-18035/com.aladinfun.piggytravel.android E/AndroidRuntime: FATAL EXCEPTION: pool-26-thread-1
Process: com.aladinfun.piggytravel.android, PID: 17946
java.lang.IllegalArgumentException: com.aladinfun.piggytravel.android: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
at android.app.PendingIntent.checkFlags(PendingIntent.java:401)
at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:671)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:658)
at androidx.work.impl.utils.ForceStopRunnable.getPendingIntent(ForceStopRunnable.java:174)
at androidx.work.impl.utils.ForceStopRunnable.isForceStopped(ForceStopRunnable.java:108)
at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:86)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:75)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
在Android12后,调用PendingIntent时,需要显式地声明mutable或immutable。如果不显式地声明,就会抛出异常。
详见下面官方文档:
https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
修改方法就是在用到PendingIntent的地方加上FLAG_IMMUTABLE或者FLAG_MUTABLE。但是有一些SDK和框架的代码我们没法主动修改,这就需要查阅相关的更新文档了。
Bug - Android 12 App crashes on startup due to error with PendingIntent (Google Mobile Ads plugin us
How to resolve “Missing PendingIntent mutability flag” lint warning in android api 30+?
https://developer.android.com/jetpack/androidx/releases/work#groovy
通过别人的贴子发现,如果是库引起的问题,会报错在具体一行中,而我们的报错是androidx.work框架报出来的,那么这说明是安卓原生库有问题。
查阅相关文档后,发现谷歌官方框架修复了这个问题:
https://android.googlesource.com/platform/frameworks/support/+/8656febfe4ffbd1de91299f9ae9b9c6147e723d6
最终在依赖中添加下面两个库即可:
// For apps targeting Android 12, add WorkManager dependency. implementation "androidx.work:work-runtime:2.7.1" implementation "androidx.work:work-runtime-ktx:2.7.1"
游戏启动后,卡在启动界面,C#脚本只调用Awake不调用Start。
在启动游戏时,请求一个AndroidManifest没有声明的权限即可。
Question - Android: targeting API level 31 makes the game freeze on Android 12
上面的代码加上后,发现在绝大多数机型下可以正常运行,但在部分Android12及以上的三星设备上仍然黑屏。
同问题六,项目里用的本地推送插件没有兼容android12,在使用PendingIntent的时候没有添加FLAG_IMMUTABLE或者FLAG_MUTABLE,从而导致调用方法时报错。
java.lang.IllegalArgumentException: com.aladinfun.piggytravel.android: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
查到这个作者插件原GitHub,阅读源码发现net.agasper.unitynotification.UnityNotificationManager里面的SetNotification没有兼容Android12。
https://github.com/Agasper/unity-android-notifications/blob/master/PluginSrc/app/src/main/java/net/agasper/unitynotification/UnityNotificationManager.java
源码在此,作者没有做更新,没有兼容Android12。
Free Android local notifications plugin open source。这是这个作者宣传自己插件的帖子。
最终down下了作者的源码,修改对应方法后重新生成jar包,扔到项目中,修改方法大致如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayMs, rep, PendingIntent.getBroadcast(currentActivity, id, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));else am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delayMs, rep, PendingIntent.getBroadcast(currentActivity, id, intent, PendingIntent.FLAG_UPDATE_CURRENT));
同问题六,Facebook SDK报错:
Caused by: java.lang.IllegalArgumentException: com.aladinfun.piggytravel.android: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
at android.app.PendingIntent.checkFlags(PendingIntent.java:401)
at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:671)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:658)
at com.facebook.AccessTokenManager.setTokenExpirationBroadcastAlarm(AccessTokenManager.kt:121)
at com.facebook.AccessTokenManager.setCurrentAccessToken(AccessTokenManager.kt:94)
at com.facebook.AccessTokenManager.setCurrentAccessToken(AccessTokenManager.kt:47)
at com.facebook.AccessToken$Companion.setCurrentAccessToken(AccessToken.kt:428)
at com.facebook.AccessToken.setCurrentAccessToken(Unknown Source:2)
at com.facebook.login.LoginManager.finishLogin(LoginManager.java:894)
at com.facebook.login.LoginManager.onActivityResult(LoginManager.java:247)
at com.facebook.login.LoginManager$1.onActivityResult(LoginManager.java:186)
at com.facebook.internal.CallbackManagerImpl.onActivityResult(CallbackManagerImpl.kt:44)
at com.facebook.unity.BaseActivity.onActivityResult(BaseActivity.java:51)
at android.app.Activity.dispatchActivityResult(Activity.java:8613)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5340)
官方说在Facebook SDK版本11.3.0解决了该问题。
Android facebook-login library 11.2.0 crashes Android 12 - Targeting S+ (version 31 and above) requi
https://github.com/facebook/facebook-android-sdk/issues/997#issuecomment-914691737
升级Facebook Unity SDK,并修改Dependences.xml,将对应Faceboook SDK升到12.2.0版本。
Facebook分享成功但是分享回调中传来unknown error。
官方回应Facebook Share SDK 12.3.0有问题,已在13.0.0版本修复,但是我们的Unity版本不支持更高级别的Facebook SDK版本了,所以只能降回12.2.0。
Share action is success but return UnknownError in facebook sdk 12.0.0+ · Issue #1043 · facebook/fac
需要将Facebook Share Sdk降级为12.2.0。
打aab包时报错:
FileNotFoundException: Temp/gradleOut/build/outputs/bundle/release/gradleOut.aab does not exist
高版本gradle构建aab时,会生成gradleOut-release.aab,但Unity找的是gradleOut.aab,名字对不上了,打包自然就失败了。
FileNotFoundException: Temp\gradleOut\build\outputs\bundle\release\gradleOut.aab does not exist
注意:如果按照上面帖子的方法会产生下面的报错,找不到capitalize方法。需要做一些修改。详见下面的最终修改内容。
FAILURE: Build failed with an exception.
Where:
Build file ‘/Volumes/build_workspace/piggygo_client/client_android/build_repo/Temp/gradleOut/build.gradle’ line: 200What went wrong:
A problem occurred configuring root project ‘gradleOut’.Failed to notify project evaluation listener.
Could not create task ‘:bundleDebug’.
No such property: capitalize for class: java.lang.String
Android variants not detected.
Please make sure you place the directive:
apply plugin: ‘applovin’
after you apply the Android plugin in your build.gradle file
在mainTemplate.gradle最后添加重命名task即可:
tasks.whenTaskAdded { task -> if (task.name == "bundleRelease") { def renameTaskName = "renameBundleReleaseAab" def flavor = "release" tasks.create(renameTaskName, Copy) { def path = "${buildDir}/outputs/bundle/${flavor}/" from(path) include "gradleOut-release.aab" destinationDir file("${buildDir}/outputs/bundle/${flavor}/") rename "gradleOut-release.aab", "gradleOut.aab" } task.finalizedBy(renameTaskName) }}
在部分Android 12及以上的手机上运行没有声音,三星居多。
最新解决办法,反编译classes.jar,修改UnityPlayer类的addPhoneCallListener实现,判断if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) return;再编回classes.jar,注意打包机是Mac需要修改Mac安装目录下的Class
Android平台 Target API level 升级到 31,在Android 12上启动黑屏卡死 – UWA问答
Android平台 Target API level 升级到 31,在Android 12上启动黑屏卡死