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);