MediaSessionCompatTargeting S version 31 and above requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On Android 12 and later, a PendingIntent must declare whether it is mutable or immutable. Media apps often hit this through MediaSessionCompat, media notifications, and media button actions because those features create or consume PendingIntent objects constantly. The fix is usually small, but choosing the right flag matters for both correctness and security.
Why the Crash Happens
When your app targets API level 31 or above, Android rejects PendingIntent creation if neither FLAG_IMMUTABLE nor FLAG_MUTABLE is present. The platform now requires the app to state whether the intent contents may be modified after creation.
For most media use cases, the intent content is fixed. A play, pause, or open-player action should not be rewritten later, so immutable is the safer default.
Use FLAG_IMMUTABLE for Fixed Media Actions
If the action, extras, and target component are known up front, create the PendingIntent with FLAG_IMMUTABLE.
The same rule applies when setting the session activity:
If you are just launching an activity or sending a fixed media control broadcast, immutable is almost always correct.
Use FLAG_MUTABLE Only When the Framework Requires It
Mutable pending intents are needed only when some later API must add or alter data before delivery. A common example is RemoteInput in a notification reply flow. That is not the normal case for media transport buttons.
The decision rule is simple:
- if no later mutation is required, use immutable
- if documented framework behavior needs mutation, use mutable
Do not choose mutable just to make the crash disappear. It broadens the attack surface for no benefit.
Create a Small Compatibility Helper
In a mixed-minSdk project, a helper keeps the flag logic consistent across the app.
Then use the helper at every creation site:
That reduces the chance of fixing one call site and forgetting three others in notifications or playback helpers.
Where to Look in a Media App
The exception message often appears near MediaSessionCompat, but the real bug may live elsewhere. Search for all PendingIntent factory calls:
- '
PendingIntent.getActivity' - '
PendingIntent.getBroadcast' - '
PendingIntent.getService' - notification action builders
- session activity configuration
In older codebases the problem is often in a notification utility class, not the media session itself.
Common Pitfalls
The biggest mistake is setting FLAG_MUTABLE everywhere without asking whether mutation is actually required. That fixes the symptom but ignores the reason Android made the requirement explicit.
Another common issue is adding FLAG_IMMUTABLE and accidentally removing FLAG_UPDATE_CURRENT. If the app relied on refreshed extras for the same request code, behavior can change in subtle ways.
Developers also often patch the main notification action and miss a second PendingIntent used for the session activity, a custom action, or a media button receiver. Test the full playback flow, not just app startup.
Finally, remember that library code can also create pending intents. If the crash stack trace points outside your own class, inspect the call site that passes the intent into the library rather than assuming the support library itself is defective.
Summary
- Android 12 and later require every
PendingIntentto be immutable or mutable. - Use
FLAG_IMMUTABLEas the default for media actions and session activity intents. - Reserve
FLAG_MUTABLEfor documented cases that truly need post-creation mutation. - Search all
PendingIntentcreation sites in the media flow, not just the first one in the stack trace. - Retest notification actions, lock-screen controls, and activity launch paths on API 31 and above.

