PendingIntent от второго действия перезаписывает первое действие и contentIntent для уведомления

Код:

int id = 0;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
  .setContentTitle(context.getString(R.string.notification_on_the_move_gps_title))
  .setContentText(context.getString(R.string.notification_on_the_move_text));

builder.setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(R.string.notification_on_the_move_gps_big_text)));

Intent mainIntent = new Intent(context, MainActivity.class);

Intent turnOffIntent = new Intent(context, MainActivity.class);
turnOffIntent.putExtra(MainApp.KEY_TURN_OFF_NOTIFICATION_ID, id);

TaskStackBuilder mainBuilder = TaskStackBuilder.create(context);
mainBuilder.addParentStack(MainActivity.class);
mainBuilder.addNextIntent(mainIntent);
PendingIntent mainPendingIntent = mainBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(mainPendingIntent);

TaskStackBuilder turnOffBuilder = TaskStackBuilder.create(context);
turnOffBuilder.addParentStack(MainActivity.class);
turnOffBuilder.addNextIntent(turnOffIntent);
PendingIntent turnOffPendingIntent = turnOffBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

builder
  .setSmallIcon(R.drawable.ic_stat_notification)
  .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher))
  .setAutoCancel(true)
  .setLights(Color.BLUE, 500, 500)
  .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
  .addAction(R.drawable.ic_stat_notification, "Open", mainPendingIntent)
  .addAction(R.drawable.ic_stat_notification_off, "Turn off", turnOffPendingIntent);

NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify(id, builder.build());

Проблема:

Нажатие на нерасширенное или расширенное тело уведомления или на кнопку "Открыть действие" всегда передает намерение с (KEY_TURN_OFF_NOTIFICATION_ID) дополнительно.

Я пробовал перетащить TaskStackBuilder и просто создать PendingIntent:

Intent mainIntent = new Intent(context, MainActivity.class);
PendingIntent piMain = PendingIntent.getActivity(context, 0, mainIntent, 0);

Intent turnOffIntent = new Intent(context, MainActivity.class);
turnOffIntent.putExtra(MainApp.KEY_TURN_OFF_NOTIFICATION_ID, id);
PendingIntent piTurnOff = PendingIntent.getActivity(context, 0, turnOffIntent, 0);

но, с тем же эффектом: (

Если я опускаю setContentIntent(), естественно, нажатие на тело уведомления ничего не делает.

Если я установил setContentIntent() после установки действий, то дополнительный никогда не будет получен в MainActivity.

Ответ 1

В doc:

Из-за этого поведения важно знать, когда два намерения считаются одинаковыми для целей получения PendingIntent. Обычная ошибка, которую делают люди, заключается в создании нескольких объектов PendingIntent с Intents, которые изменяются только в их "лишнем" содержимом, ожидая, что каждый раз будет получать другой PendingIntent. Этого не происходит. Части намерения, которые используются для сопоставления, являются теми же, что определены Intent.filterEquals. Если вы используете два объекта Intent, которые эквивалентны Intent.filterEquals, тогда вы получите тот же PendingIntent для обоих из них.

Таким образом, вы должны сделать эти намерения разными, как в методе Intent.filterEquals:

То есть, если их действие, данные, тип, класс и категории одинаковы. Это не сравнивает дополнительные данные, включенные в намерения.

В качестве побочной заметки у меня была та же проблема при работе над уведомлениями об загрузке firefox для android здесь

Ответ 2

Следовательно, флаг PendingIntent.FLAG_UPDATE_CURRENT будет просто перезаписывать дополнительные функции, если вы создаете новое намерение, когда меняются только дополнительные параметры.

Попробуйте добавить разные

  • действие вроде intent.setAction("DISTINCT.ACTION.HERE") или
  • категория, подобная intent.addCategory("DISTINCT.CATEGORY.HERE")

для каждой цели.

приветствия: -)