'Android 12 Pending Intent Immutable flag not available under API 23

Similar to this question, but not the same

After update to Android 12 (SDK 31) we change PendingIntent.getActivity(context, 0, intent, 0) to PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) like suggested.

But PendingIntent.FLAG_IMMUTABLE is not available for SDK under 23. If I add if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) to keep both versions, I stay with the lint warning about not using the correct flag for the else case.

What is the expected behaviour here? Thanks!



Solution 1:[1]

From the documentation of 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 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.

In summary, you should add the FLAG_IMMUTABLE flag to your PendingIntent when targeting API 31 or later, unless you need your PendingIntent to be mutable, in which case you need to use FLAG_MUTABLE.

Because FLAG_IMMUTABLE was introduced in API 23, you have to use FLAG_MUTABLE as a fallback for lower versions.

val flag =
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE
  else PendingIntent.FLAG_MUTABLE

You can combine this with your existing intent flags, if you have any, using a bitwise or operation. For example:

val flags = flag or PendingIntent.FLAG_ONE_SHOT

Solution 2:[2]

I just got the same problem, here is how i fixed it:

val flags =
  if (SDK_INT >= Build.VERSION_CODES.S) {
    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
  } else {
    PendingIntent.FLAG_UPDATE_CURRENT
  }

  return Intent(context, TastingReceiver::class.java).let { intent ->
    intent.putExtra(EXTRA_TASTING_ID, tasting.id)
    PendingIntent.getBroadcast(
    context,
    tasting.id.hashCode(),
    intent,
    flags
   )
}

Solution 3:[3]

You can simply ignore the warning: on APIs levels under 23, the flag will simply be ignored (tested on API 21).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ninjinski
Solution 3 Max