PendingIntent and mutability

Lifecycle and app components Mid-level Kotlin 2.0+ API 31+ Reviewed By Best Latest Apps

Pick the fix

Tapping any of three notifications always opens item 1. What's the fix?

fun openItem(context: Context, id: Int): PendingIntent {
    val intent = Intent(context, DetailActivity::class.java).putExtra("id", id)
    return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
}
Options
Hint 1 of 1

How does the system decide two PendingIntents are the same?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Use a distinct request code per item (and FLAG_IMMUTABLE)

Correct. PendingIntents that match except for extras are treated as the same.

Why not the others?
  • B Use FLAG_MUTABLE. Mutability doesn't make the tokens distinct.
  • C Add FLAG_ACTIVITY_NEW_TASK. That's about the task, not which PendingIntent is reused.
  • D Post the notifications with a delay. Timing doesn't matter; matching does.

30-second answer

A PendingIntent is a token that lets another app or the system, such as a notification or an alarm, fire an intent later with your app's identity and permissions. Since Android 12 you must say whether others can change it. Use FLAG_IMMUTABLE almost always; use FLAG_MUTABLE only when the receiver must fill in data, like inline reply or bubbles.

Practise saying it · 35 s. No recording, just a timer

Explain PendingIntent and its flags.

Say your answer out loud, then check which of these points you covered:

  • Token to act with your app's identity
  • FLAG_IMMUTABLE by default
  • Mutable only when the receiver fills data
  • Request codes distinguish tokens

Deep dive

A mutable PendingIntent with an implicit inner intent is a security risk: another app could redirect it.

Request codes and extras matter: two PendingIntents that differ only in extras are the same token unless the request code (or action, data or component) differs; FLAG_UPDATE_CURRENT only replaces the existing token's extras.

Since Android 14, a mutable PendingIntent must use an explicit intent.

Notification tap targets should open an explicit Activity, often with a back stack from TaskStackBuilder.

Common mistakes

  • Omitting the mutability flag and crashing on Android 12+.
  • Using FLAG_MUTABLE by default.
  • Expecting different extras to make separate PendingIntents.

Senior take & follow-ups

Explain identity delegation and the security angle, then the request-code trap.

Follow-up questions

Think of your answer first, then open the hint.

  1. Why might every notification open the same item?

    Show hint

    The PendingIntents differ only in extras, so the first one is reused.

  2. When is FLAG_MUTABLE required?

    Show hint

    When the receiver fills in the intent, as with inline replies.

Suggest a fix if something here is wrong or out of date.