PendingIntent работает правильно для первого уведомления, но неправильно для остальных

protected void displayNotification(String response) { Intent intent = new Intent(context, testActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis()); notification.setLatestEventInfo(context, "Upload", response, pendingIntent); nManager.notify((int)System.currentTimeMillis(), notification); } 

Эта функция будет вызываться несколько раз. Я бы хотел, чтобы каждое notification запускало testActivity при нажатии. К сожалению, только первое уведомление запускает testActivity. Нажатие на остальные приводит к минимизации windows уведомления.

Дополнительная информация: Функция displayNotification() находится в classе с именем UploadManager . Context передается в UploadManager из activity которое создает экземпляр. Функция displayNotification() вызывается несколько раз из функции, также в UploadManager, которая работает в AsyncTask .

Редактировать 1: Я забыл упомянуть, что я передаю String-ответ в Intent intent в качестве extra .

  protected void displayNotification(String response) { Intent intent = new Intent(context, testActivity.class); intent.putExtra("response", response); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

Это имеет большое значение, потому что мне нужен дополнительный «ответ», чтобы отразить, какой был ответ строки, когда было создано уведомление. Вместо этого, используя PendingIntent.FLAG_UPDATE_CURRENT , дополнительный «ответ» отражает то, что ответ строки был последним вызовом displayNotification() .

Я знаю, почему это от чтения документации по FLAG_UPDATE_CURRENT . Тем не менее, я не уверен, как это сделать в данный момент.

Не используйте Intent.FLAG_ACTIVITY_NEW_TASK для PendingIntent.getActivity, вместо этого используйте FLAG_ONE_SHOT


Скопировано из комментариев:

Затем установите некоторое фиктивное действие в Intent, в противном случае дополнительные параметры будут удалены. Например

 intent.setAction(Long.toString(System.currentTimeMillis())) 

RemoteViews с RemoteViews и несколько разных Intents для каждой Button на виджета HomeScreen . Работали при добавлении этих:

1. intent.setAction(Long.toString(System.currentTimeMillis()));

2. PendingIntent.FLAG_UPDATE_CURRENT

  PackageManager pm = context.getPackageManager(); Intent intent = new Intent(context, MyOwnActivity.class); intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value"); intent.setAction(Long.toString(System.currentTimeMillis())); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent); 

Установите действие. Решите это для меня. Вот мое понимание ситуации:


У меня есть несколько виджетов, на которые есть PendingIntent. Всякий раз, когда кто-то обновлялся, все они обновлялись. Флаги должны описывать, что происходит с PendingIntents, которые являются точно такими же.

Описание FLAG_UPDATE_CURRENT читается намного лучше:

Если тот же PendingIntent, который вы делаете, уже существует, обновите все старые до нового PendingIntent, который вы делаете.

Определение точно такого же взгляда на весь PendingIntent ЗА ИСКЛЮЧЕНИЕМ дополнительных функций. Таким образом, даже если у вас есть разные дополнения для каждого намерения (для меня я добавлял appWidgetId), то для android они одинаковы.

Добавление .setAction с некоторой фиктивной уникальной строкой сообщает ОС. Они совершенно разные и ничего не обновляют. В конце концов, это моя реализация, которая работает так, как я хотел, где каждый виджет имеет свою собственную конфигурацию. Intent прилагается:

 Intent configureIntent = new Intent(context, ActivityPreferences.class); configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

ОБНОВИТЬ


Даже лучшее решение в случае, если вы работаете с трансляциями. Уникальные PendingIntents также определяются уникальными кодами запросов. Вот мое решение:

 //Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r int dummyuniqueInt = new Random().nextInt(543254); PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context, dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

У меня была такая же проблема, и я смог ее исправить, изменив флаг:

 PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

Я вижу ответы, но никаких объяснений. Также ни один из ответов не касается всех возможных решений, поэтому я попытаюсь сделать это понятным.

Документация:

Если вам действительно нужно одновременно несколько разных объектов PendingIntent (например, использовать в качестве двух уведомлений, показанных одновременно), вам нужно будет убедиться, что есть что-то, что отличается от них, чтобы связать их с разными PendingIntents. Это может быть любой из атрибутов Intent, рассмотренных Intent.filterEquals или разных целых кодов кода, переданных в getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast (Context, int , Intent, int) или getService (Контекст, int, Intent, int).

Причина проблемы:

Вы создаете 2 уведомления с двумя ожидающими намерениями. Каждое ожидающее намерение связано с намерением:

 Intent intent = new Intent(context, testActivity.class); 

Однако эти 2 намерения равны, поэтому, когда ваше второе уведомление поступит, оно запустит первое намерение.

Решение:

Вы должны сделать каждое намерение уникальным, чтобы никакие ожидающие намерения никогда не были равны. Как вы делаете намерения уникальными? Не с помощью дополнительных putExtra() вы ставите с помощью putExtra() . Даже если экстрасмены различны, намерения могут быть равны. Чтобы сделать каждое намерение уникальным, вы должны установить уникальное значение для действия намерения, или данных, или типа, или classа, или категории, или кода запроса: (любой из них будет работать)

  • action: intent.setAction(...)
  • data: intent.setData(...)
  • type: intent.setType(...)
  • class: intent.setClass(...)
  • категория: intent.addCategory(...)
  • код запроса: PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);

Примечание . Установка уникального кода запроса может быть сложной, потому что вам нужен int, а System.currentTimeMillis() возвращает long, что означает, что некоторые цифры будут удалены. Поэтому я бы рекомендовал либо пойти с категорией, либо действием и установить уникальную строку.

Fwiw, мне повезло с PendingIntent.FLAG_CANCEL_CURRENT чем с PendingIntent.FLAG_UPDATE_CURRENT .

Как указано в документации, используйте уникальный код запроса:

Если вам действительно нужно одновременно несколько разных объектов PendingIntent (например, использовать в качестве двух уведомлений, показанных одновременно), вам нужно будет убедиться, что есть что-то, что отличается от них, чтобы связать их с разными PendingIntents. Это может быть любой из атрибутов Intent, рассмотренных Intent.filterEquals или разных целых кодов кода, переданных в getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast (Context, int , Intent, int) или getService (Контекст, int, Intent, int).

У меня была та же проблема, и я исправил ее на следующих шагах

1) Очистить любой флаг для намерения

 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 

2) вставить намерение.setAction по нижеследующему коду

  intent.setAction(Long.toString(System.currentTimeMillis())); 

3) для Pendingintent, вставьте нижеприведенный код

  PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT); 

Я надеюсь работать с вами

 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); 

В PendingIntent есть два параметра int, второй и последний. Второй – «код запроса», и он должен быть номером unicue (например, идентификатором вашего сообщения), иначе if (как в вашем примере он равен нулю, он всегда будет перезаписан).

 // Use pending Intent and also use unique id for display notification.... // Get a PendingIntent containing the entire back stack PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager mNotificationManager = (NotificationManager) sqlitewraper.context.getSystemService(Context.NOTIFICATION_SERVICE); // Issue the notification mNotificationManager.notify(id, builder.build()); 

чтобы отправить данные правильно, вы должны отправить с ожидающим намерение идентификатор уведомления следующим образом: PendingIntent pendingIntent = PendingIntent.getActivity (context, (int) System.currentTimeMillis () , намерение, PendingIntent.FLAG_UPDATE_CURRENT);

У меня такая же проблема, и для исправления используйте PendingIntent.html.FLAG_UPDATE_CURRENT .

Я проверил исходный код. В ActivityManagerService.java ключевой метод заключается в следующем. Когда флаг PendingIntent.FLAG_UPDATE_CURRENT, а updateCurrent – true. Некоторые дополнительные функции будут заменены новыми, и мы получим замененный PendingIntent.

  IIntentSender getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle bOptions) { // ... omitted final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT |PendingIntent.FLAG_UPDATE_CURRENT); PendingIntentRecord.Key key = new PendingIntentRecord.Key( type, packageName, activity, resultWho, requestCode, intents, resolvedTypes, flags, bOptions, userId); WeakReference ref; ref = mIntentSenderRecords.get(key); PendingIntentRecord rec = ref != null ? ref.get() : null; if (rec != null) { if (!cancelCurrent) { if (updateCurrent) { if (rec.key.requestIntent != null) { rec.key.requestIntent.replaceExtras(intents != null ? intents[intents.length - 1] : null); } if (intents != null) { intents[intents.length-1] = rec.key.requestIntent; rec.key.allIntents = intents; rec.key.allResolvedTypes = resolvedTypes; } else { rec.key.allIntents = null; rec.key.allResolvedTypes = null; } } return rec; } rec.canceled = true; mIntentSenderRecords.remove(key); } 

У меня была такая же проблема, и я смог ее исправить, изменив флаг:

 LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(R.layout.appointment, null); AlertDialog.Builder bulider= new AlertDialog.Builder(PatientDetail.this); final AlertDialog alert=bulider.create(); bulider.setTitle("Enter Date/Time"); bulider.setView(textEntryView); bulider.setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { EditText typeText=(EditText) textEntryView.findViewById(R.id.Editdate); EditText input1 =(EditText) textEntryView.findViewById(R.id.Edittime); getDateAndTime(typeText.getText().toString(),input1.getText().toString()); } }); bulider.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); bulider.show(); } 
  • Отключить звук из NotificationChannel
  • Android: Как создать уведомление «Ongoing»?
  • Push-уведомления, когда приложение закрыто
  • Создание пользовательского уведомления, андроида
  • Проверьте, включены ли локальные уведомления в IOS 8
  • Уведомление Не показывать
  • возобновление деятельности извещения
  • Лучший способ сериализации NSData в hexadeximal string
  • Уведомления Android с кнопками на нем
  • Как выполнить метод, нажав на уведомление
  • Как нарисовать представление поверх всего?
  • Давайте будем гением компьютера.