MediaSessionCompat FLAG_IMMUTABLE Fix for Android 12
Problem Statement
When targeting Android 12 (API level 31) or higher, you may encounter the following runtime exception when using MediaSessionCompat:
java.lang.IllegalArgumentException: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntentThis error occurs because Android 12 introduced new security requirements for PendingIntent objects. The system now requires explicit declaration of whether a PendingIntent should be mutable or immutable.
Root Cause
The MediaSessionCompat class internally creates a PendingIntent for media button handling. In older versions of the AndroidX Media library, this internal implementation didn't specify the required mutability flag when targeting Android 12.
Solutions
Solution 1: Update AndroidX Media Library (Recommended)
Update to at least version 1.4.1 of the AndroidX Media library, which includes the necessary fix:
implementation 'androidx.media:media:1.4.1'This version specifically addresses:
- Mutability flag for creating PendingIntent to prevent crash when targeting Android S
- Class verification failures for NotificationCompat.MediaStyle
Solution 2: Manual PendingIntent Creation
If you cannot update the library immediately, manually create a PendingIntent and pass it to the MediaSessionCompat constructor:
override fun onCreate() {
super.onCreate()
val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
val pendingIntent = PendingIntent.getBroadcast(
baseContext,
0,
mediaButtonIntent,
PendingIntent.FLAG_IMMUTABLE
)
mediaSession = MediaSessionCompat(baseContext, "TAG", null, pendingIntent).apply {
setCallback(mediaSessionCallback)
isActive = true
}
sessionToken = mediaSession.sessionToken
}Solution 3: Update Dependencies with Work Manager
If you're not directly using PendingIntent but still encounter this error, it might be caused by outdated transitive dependencies. Update the Work Manager library:
// Kotlin
implementation 'androidx.work:work-runtime-ktx:2.8.0'
// Java
implementation 'androidx.work:work-runtime:2.8.0'Solution 4: Update Other Problematic Dependencies
Some common libraries that may cause this issue when outdated:
// Firebase Messaging
implementation 'com.google.firebase:firebase-messaging:23.0.0'
// Google Play Services Ads
implementation 'com.google.android.gms:play-services-ads:22.0.0'
// Chuck library (network interceptor)
debugImplementation "com.github.chuckerteam.chucker:library:3.5.2"
releaseImplementation "com.github.chuckerteam.chucker:library-no-op:3.5.2"Version Check Pattern for PendingIntent
When creating PendingIntent objects directly, use version checking:
val flag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_IMMUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
val pendingIntent = PendingIntent.getActivity(
context,
requestCode,
intent,
flag
)WARNING
Use FLAG_MUTABLE only if your app needs to modify the intent contents (e.g., for inline replies or bubbles). Google strongly recommends using FLAG_IMMUTABLE for most use cases.
Android Manifest Requirements for Android 12
Ensure your AndroidManifest.xml includes the proper exported attributes:
<activity
android:name=".MainActivity"
android:exported="true">
<!-- ... -->
</activity>
<service
android:name=".MediaService"
android:exported="true">
<!-- ... -->
</service>Verification
After applying the fix, verify your dependencies are up to date:
./gradlew app:dependenciesThis command will show your dependency tree and help identify any outdated libraries that might still be causing issues.
Conclusion
The Android 12 PendingIntent mutability requirement is a security enhancement that prevents unintended modification of intents. The most straightforward solution is to update your AndroidX Media library to version 1.4.1 or later. If that's not immediately possible, manually creating the PendingIntent with the appropriate flag provides a reliable workaround.
Always ensure all your dependencies are updated to their latest compatible versions to avoid similar issues with other components that might create PendingIntent objects internally.