Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 or later), 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?

like image 482
Amir Hossein Ghasemi Avatar asked Apr 11 '21 13:04

Amir Hossein Ghasemi


People also ask

What is a PendingIntent Android?

A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it.


14 Answers

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

like image 83
Mayur Gajra Avatar answered Oct 12 '22 15:10

Mayur Gajra


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.

like image 30
Noel Avatar answered Oct 12 '22 14:10

Noel


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 mutated, 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 mutated use the following:

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.

like image 31
Josi Avatar answered Oct 12 '22 14:10

Josi


If your app is targeting Android 12 (targetSdkVersion = 31), and uses an old version of the WorkManager directly OR by any of the third-party libraries then you require to update it to the latest to resolve it.

dependencies {
    val work_version = "2.7.1"

    // (Java only)
    implementation("androidx.work:work-runtime:$work_version")

    // Kotlin + coroutines
    implementation("androidx.work:work-runtime-ktx:$work_version")

    // optional - RxJava2 support
    implementation("androidx.work:work-rxjava2:$work_version")        
}
like image 20
Nikunj Avatar answered Oct 12 '22 13:10

Nikunj


In my case it was also by third party libraries which were using old WorkManager versions, to force the new Android Work version on all dependencies use this in your root build.gradle file:

allproject {
  project.configurations.all {
    resolutionStrategy {
      force 'androidx.work:work-runtime:2.7.0'
    }
  }
}
like image 20
Niklas Avatar answered Oct 12 '22 14:10

Niklas


If you using Java and ADMOB you experience the PendingIntent Error wtih SDK S or Android 12. Here is a fix so ADMOB uses the correct work-runtime.

implementation 'com.google.android.gms:play-services-ads:19.5.0'
    constraints {
        implementation('androidx.work:work-runtime:2.7.0-alpha05') {
            because 'previous versions have a bug impacting this application'
        }
    }
like image 34
RRiVEN Avatar answered Oct 12 '22 13:10

RRiVEN


final int flag =  Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT;
PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_REQUEST_CODE, notificationIntent, flag);
like image 36
beginner Avatar answered Oct 12 '22 15:10

beginner


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

Java

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

Kotlin

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

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

Java

PendingIntent updatedPendingIntent = PendingIntent.getActivity(
   applicationContext,
   NOTIFICATION_REQUEST_CODE,
   updatedIntent,
   PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag 
)

Kotlin

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

At the Last implement this Dependecy

//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
like image 22
Rehan Khan Avatar answered Oct 12 '22 13:10

Rehan Khan


This is issue with Work library. Even the latest version is affected 2.7.0-alpha04

https://issuetracker.google.com/issues/194108978

As temporary workaround - comment out including "work" dependency in gradle and remove using that class through the project. At least in this way you may run app normally and work on another features and areas....

like image 32
Aleksandr Avatar answered Oct 12 '22 15:10

Aleksandr


This crash is resolved with : implementation 'androidx.work:work-runtime:2.7.1'

like image 43
Benoit Canonne Avatar answered Oct 12 '22 14:10

Benoit Canonne


I had crashes like Fatal Exception: java.lang.IllegalArgumentException. Not posted. PendingIntents attached to actions with remote inputs must be mutable.

I wrote this util method, which allows sending mutability as a param. Sometimes its required to get mutable flags, for example for reply actions in notifications.

private fun getPendingIntentFlags(isMutable: Boolean = false) =
    when {
        isMutable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE

        !isMutable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ->
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE

        else -> PendingIntent.FLAG_UPDATE_CURRENT
    }

Usage example:

val quickReplyPendingIntent = PendingIntent.getBroadcast(
                context, notificationId, replyIntent,
                getPendingIntentFlags(true)
            )
like image 22
Vasily Kabunov Avatar answered Oct 12 '22 14:10

Vasily Kabunov


As I had four different PendingIntents in my code, I started by adding FLAG_IMMUTABLE to all of them. However the problem remained. After spending a lot of time analyzing my 4 intents, it dawned on me that the problem might come from one of my libraries.

In build.gradle, libraries are normally highlighted when old, but this is not the case for the Firebase BOM.

I had:

implementation platform('com.google.firebase:firebase-bom:26.1.1')

It turned out this was very old. After updating to

implementation platform('com.google.firebase:firebase-bom:29.0.4')

all was fine. No more FLAG_IMMUTABLE errors

like image 37
j3App Avatar answered Oct 12 '22 14:10

j3App


in my project this line worked

PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

like image 28
Priyank Vyas Avatar answered Oct 12 '22 14:10

Priyank Vyas


This issue comes when you upgrade your project and target android version 12, Android Run App On Android 12. The solution is used you can Update your All Pending Intern

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent enter image description here

Used Below Code

 PendingIntent pendingIntent = null;
        if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.S){
             pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_MUTABLE);

        }else {
             pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT);

        }

And Also implement this Dependency Work if you are using a receiver in your project

//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
like image 27
Codeplayon Avatar answered Oct 12 '22 14:10

Codeplayon