How to resolve "Missing PendingIntent mutability flag" lint warning in android api 30+?

As soon as I updated the target SDK to 30 (Android R), a lint warning Missing PendingIntent mutability flag appeared on my PendingIntent.FLAG_UPDATE_CURRENT flag when I want to define PendingIntent.

How should I handle this lint with no effect on the app functionality?


Solution 1:

You can set your pending intent as

val updatedPendingIntent = PendingIntent.getActivity(
   applicationContext,
   NOTIFICATION_REQUEST_CODE,
   updatedIntent,
   PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag 
)

According to the docs here: https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability

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.

Choose your flag accordingly.

If you want to read more about this i would suggest that you read this great article here: https://medium.com/androiddevelopers/all-about-pendingintents-748c8eb8619

Solution 2:

If you're not using the latest version of WorkManager, you'll see this issue. It's been fixed in version 2.7.0-alpha02:

Make PendingIntent mutability explicit, to fix a crash when targeting Android 12

Keep in mind that 2.7.0-alpha02 is only compatible with the Android 12 Developer Preview 1 SDK. So you may want to wait until it hits the beta or RC.

Update April 21, 2021 -- Adding to this answer for anyone googling the issue, the bug you may encounter may look something like this:

java.lang.IllegalArgumentException: com.myapp.myapp: Targeting S+ (version 10000 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.
        at android.app.PendingIntent.checkFlags(PendingIntent.java:386)
        at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:657)
        at android.app.PendingIntent.getBroadcast(PendingIntent.java:644)
        at androidx.work.impl.utils.ForceStopRunnable.getPendingIntent(ForceStopRunnable.java:174)
        at androidx.work.impl.utils.ForceStopRunnable.isForceStopped(ForceStopRunnable.java:108)
        at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:86)
        at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:75)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)

You do not have to be actually directly using WorkManager in your app to see this crash.

The solution, as outlined here, is to add a dependency to your build.gradle file for Android 12 builds:

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

Note that this dependency is different whether you are using Java only, Kotlin + coroutines, RxJava2, GCMNetworkManager, etc. So be sure to check the dox above.

Obviously replace the version number above with the latest. And as mentioned, it is NOT compatible with pre-android-13 builds.

Solution 3:

If you let your app to run in android 12, there is a new PendingIntent mutability flag. If you don't want your PendingIntent to be muted, use

PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

    }else {
        pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    }

If you want your PendingIntent to be muted use the following:

PendingIntent pendingIntent;
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);

    }else {
        pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    }

In Google documentation says, Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable. The change should be straightforward. Also, make sure you add the following work manager dependency if you are using AdMob 20.4.0 or lower in your app:

//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'

Note that currently work manager dependency version is 2.7.1. You can update the version to the latest one if you want.