Reputation: 22158
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?
Upvotes: 266
Views: 239999
Reputation: 1
Update Firebase to latest versión:
implementation 'com.google.firebase:firebase-messaging:23.4.0'
Upvotes: -1
Reputation: 529
Add these lines:
defaultConfig {
multiDexEnabled true
}
and also
dependencies {
def work_version = "2.8.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")
}
Upvotes: 1
Reputation: 176
You can update the pending intent like:
val updatedPendingIntent = PendingIntent.getActivity(
context,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
You can add PendingIntent.FLAG_IMMUTABLE along with | sign and it will work.
Upvotes: 15
Reputation: 4157
If your app is targeting Android 12 (targetSdkVersion = 31)
, and uses an older 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.8.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")
}
Upvotes: 27
Reputation: 7518
If you have this problem about Notification, DeepLink and Navigation, do not forget to update your navigation dependency version:
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
I had this problem because of old version navigation dependency.
Upvotes: 0
Reputation: 864
I created the PendingIntentCompat.kt
that abstracts PendingIntent
logic in a separate class.
object PendingIntentCompat {
@JvmStatic
@JvmOverloads
fun getActivity(
context: Context,
requestCode: Int,
intent: Intent,
flags: Int,
isMutable: Boolean = false
): PendingIntent {
return PendingIntent.getActivity(
context,
requestCode,
intent,
addMutabilityFlags(isMutable, flags)
)
}
@JvmStatic
@JvmOverloads
fun getService(
context: Context,
requestCode: Int,
intent: Intent,
flags: Int,
isMutable: Boolean = false
): PendingIntent {
return PendingIntent.getService(
context,
requestCode,
intent,
addMutabilityFlags(isMutable, flags)
)
}
@JvmStatic
@JvmOverloads
@RequiresApi(Build.VERSION_CODES.O)
fun getForegroundService(
context: Context,
requestCode: Int,
intent: Intent,
flags: Int,
isMutable: Boolean = false
): PendingIntent {
return PendingIntent.getForegroundService(
context,
requestCode,
intent,
addMutabilityFlags(isMutable, flags)
)
}
/**
* https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
*/
private fun addMutabilityFlags(isMutable: Boolean, flags: Int): Int {
var updatedFlags = flags
if (isMutable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
updatedFlags = flags or PendingIntent.FLAG_MUTABLE
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
updatedFlags = flags or PendingIntent.FLAG_IMMUTABLE
}
}
return updatedFlags
}
}
Upvotes: 0
Reputation: 2134
From :
https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE
"Up until Build.VERSION_CODES.R, PendingIntents are assumed to be mutable by default, unless FLAG_IMMUTABLE is set. Starting with Build.VERSION_CODES.S, it will be required to explicitly specify the mutability of PendingIntents on creation with either (@link #FLAG_IMMUTABLE} or FLAG_MUTABLE. It is strongly recommended to use FLAG_IMMUTABLE when creating a PendingIntent. FLAG_MUTABLE should only be used when some functionality relies on modifying the underlying intent, e.g. any PendingIntent that needs to be used with inline reply or bubbles."
To keep same behavior like to day change anything to "PendingIntent.FLAG_MUTABLE | anything "
When creating/retrieving a pending intent/ activity, services, provider, receiver
Places to look for :
PendingIntent.getBroadcast(...
.getPendingIntent(...
PendingIntent.getService
PendingIntent.getActivity
Also if your app using androidx.work make sure to upgrade to atleast :
implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
There was a bug they fixed in alpha02 related to all this changes in SDK 12.
Upvotes: 0
Reputation: 491
i wanna share a bit from my case. i changed the flag to FLAG_IMMUTABLE but still got the error only when the app is on background. i got it solved from here : https://github.com/firebase/firebase-android-sdk/issues/3115
the root cause is because i retrieve the FCM token in the deprecated way :
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(activity, new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
}
});
then i update the dependency :
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
String newToken = task.getResult();
});
Upvotes: 1
Reputation: 5288
here is my use case to move from 30 to 33 in KOTLIN.
1. Add media dependency
implementation "androidx.media:media:1.4.1"
2. Update work manager
implementation "androidx.work:work-runtime-ktx:2.7.0"
3. Update Immutable
fun getImmutableFlag() = if(isAndroidAPI31()) PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT else 0
fun isAndroidAPI31() = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S
private fun createOpenAppIntent(context: Context): PendingIntent {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
}
return PendingIntent.getActivity(context, 0, intent, getImmutableFlag())
}
4. Add exported tag in manifest if not added in all activity, services, provider, receiver
android:exported="true"
Hope this will work, have a good day.
Upvotes: 1
Reputation: 2508
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);
Upvotes: 29
Reputation: 397
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
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'
Upvotes: 2
Reputation: 2233
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.
Upvotes: 99
Reputation: 31
in my project this line worked
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Upvotes: 3
Reputation: 1291
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'
Upvotes: 8
Reputation: 6751
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)
)
Upvotes: 5
Reputation: 1582
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
Upvotes: 8
Reputation: 617
I updated my work-runtime-ktx
version to 2.7.1
After the above change i got into another error
java.lang.IllegalStateException: SimpleTypeImpl should not be created for error type: ErrorScope{Error scope for class <ERROR CLASS> with arguments: org.jetbrains.kotlin.types.IndexedParametersSubstitution@14ac19e7}
Look how i solved the above error by updating kotlin-gradle-plugin
version here.
Upvotes: 0
Reputation: 455
This crash is resolved with : implementation 'androidx.work:work-runtime:2.7.1'
Upvotes: 9
Reputation: 25433
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'
}
}
}
Upvotes: 13
Reputation: 2579
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'
}
}
Upvotes: 13
Reputation: 7410
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.
Upvotes: 85
Reputation: 61
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....
Upvotes: 4
Reputation: 9083
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
Upvotes: 265