Android 12 Crash on startup: PendingIntent mutability

Hey guys,

for the past few days, I’ve been battling a crash happening on Android 12 devices. The app crashes without a log, but I was able to get this from Firebase Crashlytics:

Fatal Exception: java.lang.IllegalArgumentException

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.

I’d like to note, that there is no PendingIntent present in my project’s source code.

I’ve been trying to replicate the crash using a blank project. I’ve copied over the plugins (some of which are custom) and many of the settings from the project where the crash is present, but I wasn’t able to replicate it and the blank project runs on Android 12 without a problem.

I’ve read through all I could find on the internet on this crash (not a single post mentioned this problem happening with Unreal Android build) and I tried about 100 builds but without success.

I would be very grateful if you would help me solve this problem. Thanks!

there is something in the engine code … but it needs to be understood …

I’m just scattering theories)) or maybe it’s just to write in manifest file? although my game also works on android 12 but does not get problems… or read this)) - https://developer.android.com/reference/android/app/PendingIntent

The eMUTABLE_FLAGS you mentioned is an ENUM, which specifies, which flags are mutable, so it’s not related to my problem.

Writing directly to AndroidMainfest.xml is pointless, because the file is rewritten after each build.

I have read the document, which you posted even before posting my question here, on the forum, but other than helping me understand what PendingIntent really is, it didn’t help me solve my problem.

Thanks for trying though.

no no ))

Yes, you can do it like so, but the question is what should I write there?

I have no idea what kind of mistake it is) I’m just trying to understand why you have it and I don’t have this error… or maybe it’s someone trying to use gameguardian and the game crashes :grinning:? what am I leading to, if there was an error in the engine I would also have to get feedback that there are problems …

so it’s either a plugin or someone can use cheat in game and change the wrong variables and the game crashes… I have no more theories :sweat_smile:

Running into the same issue - were you able to fix this on your end by any chance?

Same issue here. Game crashes on startup, with error in the Google Play Store debug logs:

Exception java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.APP/com.my.APP.DownloaderActivity}: java.lang.IllegalArgumentException: com.my.APP: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

How can I make the Unreal Engine 5 rendering process to set the FLAG_MUTABLE correctly so it won’t crash on startup when opening it on a real mobile device?

I had a problem with the plugin, after updating it everything works fine. First of all, check - Admob, Firebase … Important! I did not update the plugin correctly, I had to completely remove it and download / install it from the market again.

Hi KonPetTsu, Thank you for your reply. I tried updating plugins, but still get the same message. Also I’m not using the Admob, Firebase plugin in Unreal. Any other ideas?

Still the same error after installing the latest update off all plug-ins in Unreal Engine IDE.

Error in Google Play Developers console after uploading:

Caused by java.lang.IllegalArgumentException: com.my.MYAPP: 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.

I cannot find a way to specify FLAG_IMMUTABLE or FLAG_MUTABLE without changing code that is overwritten by Unreal when rendering the game.

Any help is appreciated!

I solved it hopefully. What you have to do when you get the error above:

  • Open the Unreal game project in Android Studio
  • Search with CTRL-SHIFT-F to all occurances of PendingIntent. (in the project, not the Android platform files)
  • When you see PendingIntent.FLAG_UPDATE_CURRENT or another flag change it to PendingIntent.FLAG_IMMUTABLE. Look for the getBroadcast documentation to learn more about flags (it can be 0 too): PendingIntent  |  Android Developers
  • Make a signed package in Android Studio (Google it)
  • Upload the .aab file and the IMMUTABLE error should be gone

If you still see an error regarding FLAG_IMMUTABLE, search again to files if you missed any.

More info here: All About PendingIntents. PendingIntents are an important part of… | by Nicole Borrelli | Android Developers | Medium

2 Likes

Hi, I tried your method, I changed every single Flag , even the Flags:0 but I still get that error.
I usually test my aab. on Firebase and recently I found less errors than usual but still there is 1 Flag Exception…

Just to know, can you tell us how many FLAG_IMMUTABLE you had to write to make it work?

Edit : I found another solution, I was working on a project born on 4.26.1 that was converted to 5.0.
I tried re-creating a new 5.0.3 project from blank and I migrate everything from the old project, same project settings and all, and now the problem is gone.

It seem that in the newer version of UE the Flag is fixed…
I suppose Unreal create the files to sign the apk just at the creation of the project and it never updates them?

Anyway I solved it , hope it helps

In case anyone ends up here as well. As of today, if you are targeting Android-12+, you will still crash if you use Local (and remote?) Notifications, since Engine code has not been fully modified. I’ve attached a patch file and have submitted a bug to Epic. In the meantime, if you use Engine Source, you can use this patch. Actually, if use the off-the-shelf launcher Unreal, you should be able to patch these files as well. The following patch was applied to UE5.1, but similar changes can be done on UE4.26 and UE5.0.3

---
 .../src/com/epicgames/unreal/GameActivity.java.template     | 6 +++---
 .../src/com/epicgames/unreal/LocalNotificationReceiver.java | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

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 6847fd729f84..e1d99143d455 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
@@ -5088,7 +5088,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");
 
@@ -5158,7 +5158,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);
 		}
@@ -5186,7 +5186,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);
 			
diff --git a/Engine/Build/Android/Java/src/com/epicgames/unreal/LocalNotificationReceiver.java b/Engine/Build/Android/Java/src/com/epicgames/unreal/LocalNotificationReceiver.java
index 285f7d0a81a5..5216372ca859 100644
--- a/Engine/Build/Android/Java/src/com/epicgames/unreal/LocalNotificationReceiver.java
+++ b/Engine/Build/Android/Java/src/com/epicgames/unreal/LocalNotificationReceiver.java
@@ -46,7 +46,7 @@ public class LocalNotificationReceiver extends BroadcastReceiver
 		notificationIntent.putExtra("localNotificationLaunchActivationEvent", activationEvent);
 
 		int notificationIconID = getNotificationIconID(context);
-		PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, notificationID, notificationIntent, 0);
+		PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, notificationID, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
 
 		NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
 		@SuppressWarnings("deprecation")
-- 
1 Like

Quick fix for this is adding this to your dependencies in build.gradle

implementation 'androidx.work:work-runtime-ktx:2.7.0'

hello bro, i do replace this code, and compile it, but i still get this error, did u resolve it?

You can check this gist that I created.

1 Like