Приходилось ли работать с PendingIntent в Android
Что проверяют
Понимаете ли вы, что PendingIntent это выданное чужому процессу право выполнить действие от имени вашего приложения. Отсюда два пласта вопроса: жизненный цикл, то есть срабатывание даже после смерти процесса, и безопасность, из-за которой система требует явно объявлять изменяемость объекта.
Как отвечать
Дайте определение через права: это обёртка над Intent, которую вы отдаёте системе или другому приложению, и при срабатывании действие выполняется с идентичностью и разрешениями вашего приложения. Создаётся фабриками getActivity, getBroadcast, getService, getForegroundService. Встречается в уведомлениях и их кнопках, в будильниках, в виджетах, в управлении воспроизведением.
Дальше два момента, ради которых вопрос и задают. Первый: начиная с Android 12 нужно явно указать FLAG_IMMUTABLE или FLAG_MUTABLE, иначе создание падает. По умолчанию берут неизменяемый, изменяемый нужен только там, где получатель дописывает данные, например при ответе прямо из уведомления.
Второй: тождественность. Два объекта считаются одинаковыми, если совпали код запроса, действие, данные, тип и компонент, а дополнительные параметры в сравнение не входят вовсе.
PendingIntent.getActivity(
context, orderId, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)Где спотыкаются
Ставят один и тот же код запроса всем уведомлениям. Поскольку дополнительные параметры в сравнении не участвуют, система переиспользует старый объект, и каждая карточка открывает один и тот же экран, обычно самый первый.
Второе: выбирают изменяемый флаг просто чтобы собралось. Изменяемый объект с неявным намерением внутри позволяет чужому приложению подставить получателя и воспользоваться разрешениями вашего.
Третье: забывают, что он живёт дольше экрана. Отменённый пользователем будильник сам не исчезает, отменять нужно и сам объект, а проверять его существование удобно флагом, запрещающим создание нового.