Android Platform SDK API 31 Target

Currently in August, Google is requiring NEW apps to target API 31 (Android 12) in order to be submitted to Google Play. By November, Google will also require EXISTING app updates to target API 31.

The NDK that Unreal Engine 5 (and 4) supports is NDK r21. However, NDK r21 only supports up to Platform API 30 (Android 11). Android 12 API’s were only added into NDK r23+

If we need to target Android API 31 (Android 12), what options are there?

1 Like

unreal engine 4) target Android API 33 :grin:
the truth is that there are no Android 13 phones yet :sweat_smile:

image

I don’t think that unreal 5 will have problems target API 31-33

Has anyone actually attempted to target API 31+ (Android 12)? I don’t believe Unreal Engine 4/5 will work if the target API is 31+, since in my builds, the game crashes:

08-15 12:45:55.218  2062  2062 F DEBUG   : Abort message: 'JNI DETECTED ERROR IN APPLICATION: JNI IsSameObject called with pending exception java.lang.IllegalArgumentException: com.sunmachineentertainment.gobig: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
08-15 12:45:55.218  2062  2062 F DEBUG   : 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.
08-15 12:45:55.218  2062  2062 F DEBUG   :   at void android.app.PendingIntent.checkFlags(int, java.lang.String) (PendingIntent.java:382)
08-15 12:45:55.218  2062  2062 F DEBUG   :   at android.app.PendingIntent android.app.PendingIntent.getBroadcastAsUser(android.content.Context, int, android.content.Intent, int, android.os.UserHandle) (PendingIntent.java:673)
08-15 12:45:55.218  2062  2062 F DEBUG   :   at android.app.PendingIntent android.app.PendingIntent.getBroadcast(android.content.Context, int, android.content.Intent, int) (PendingIntent.java:660)
08-15 12:45:55.218  2062  2062 F DEBUG   :   at boolean com.epicgames.unreal.GameActivity.LocalNotificationScheduleAtTime(android.content.Context, int, java.lang.String, boolean, java.lang.String, java.lang.String, java.lang.String, java.lang.String) (GameActivity.java:5242)
08-15 12:45:55.218  2062  2062 F DEBUG   :   at int com.epicgames.unreal.GameActivity.AndroidThunkJava_LocalNotificationScheduleAtTime(java.lang.String, boolean, java.lang.String, java.lang.String, java.lang.String, java.lang.String) (GameActivity.java:5190)

I’ve made some local modifications to the Engine’s source in an attempt to prevent the crashing so that the JAVA source conforms to the API 31 requirements, but this does not address the fact that NDK r21 does NOT support Platform API 31+. I suspect that still targeting NDK r21e along with API 31+ is still ok, as long as there’s no C++ code calling platform methods through the NDK that doesn’t conform to Platform API 31 specs, but this is probably still pretty fragile, since there’s nothing preventing future code from doing so.

NDK r21e:

NDK r23c:

diff --git a/Engine/Build/Android/Java/src/com/epicgames/unreal/GameActivity.java.template b/Engine/Build/Android/Java/src/com/epicgames/unreal/GameActivity.java.template
index 9d88c2c6bdd0..5efde987449e 100644
--- a/Engine/Build/Android/Java/src/com/epicgames/unreal/GameActivity.java.template
+++ b/Engine/Build/Android/Java/src/com/epicgames/unreal/GameActivity.java.template
@@ -5069,7 +5069,7 @@ public class GameActivity extends $${gameActivitySuperClass}$$ implements Surfac
                notificationIntent.putExtra("local-notification-activationEvent", activationEvent);
 
                // Designate the callback as a PendingIntent
-               PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+               PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
 
                TimeZone targetTimeZone = TimeZone.getTimeZone("UTC");
 
@@ -5139,7 +5139,7 @@ public class GameActivity extends $${gameActivitySuperClass}$$ implements Surfac
                for(int curID : idList)
                {
                        AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
-                       PendingIntent pendingIntent = PendingIntent.getBroadcast(this, curID, new Intent(this, LocalNotificationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
+                       PendingIntent pendingIntent = PendingIntent.getBroadcast(this, curID, new Intent(this, LocalNotificationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
                        pendingIntent.cancel();
                        alarmManager.cancel(pendingIntent);
                }
@@ -5167,7 +5167,7 @@ public class GameActivity extends $${gameActivitySuperClass}$$ implements Surfac
 
                        //Cancel the intent itself as well as from the alarm manager
                        AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
-                       PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationId, new Intent(this, LocalNotificationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
+                       PendingIntent pendingIntent = PendingIntent.getBroadcast(this, notificationId, new Intent(this, LocalNotificationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
                        pendingIntent.cancel();
                        alarmManager.cancel(pendingIntent);

and you don’t believe me :upside_down_face:

I suppose you don’t use Android Local Notifications? That might explain you not crashing possibly?

it is likely) but unknown

let’s test it) it’s an interesting experiment) try this packing method and let me know if it fails
https://forums.unrealengine.com/t/pack-a-game-for-android-without-installing-android-studio-update-android-12/492029

Hey…You found solution ? iam stuck at same place

As stated in my post above, I am targeting Platform SDK API 31, but keeping the NDK at r21. I had to make modifications to some Unreal Source (GameActivity.java.template) in order to make Android happy.

Unreal Engine has really been a pain for mobile support, as mobile toolchains keep changing and Unreal hasn’t been keeping up (new Xcode, deprecated Android versions, etc).

All I had to do to make API 31 work was add:

Text.AppendLine(“\t\t android:exported="true"”);

To UEDeployAndroid.cs. Row 2700 and 2720. (UE 4.27)
Should be in the bShowLaunchImage if statement and the else statement of the same thing.

1 Like

For me it worked. I saw somewhere else on these forums.
Open project settings then under Android DIsable “Show Launch Image” and then under android advanced APK packaging You will see extra permission for activity. Write this there android:exported=“true”

And your problem solved

1 Like

I just kept everythig as is and set target SDK to 31. Worked for me …

Same issue. Storage permission error but there is no ask for storage permission.

The link isn’t working… It’s been taken down or been turned to private.

so whats going on now how can we get ue4 to target 31 for google play?

OMG My game was completed and about to try in mobiles before publishing. And this is happening for me from last 10 days. I keep on trying on 5.2 with no success. How can I come up with this intriguing problem.