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. Нажав на остальные, окно уведомлений свернется.
Дополнительная информация: Функция displayNotification()
находится в классе с именем 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);
Это имеет большое значение, потому что мне нужен дополнительный «ответ», чтобы отразить, каким был ответ String при создании уведомления. Вместо этого при использовании PendingIntent.FLAG_UPDATE_CURRENT
дополнительный «ответ» отражает ответ String на последний вызов displayNotification()
.
Я знаю, почему это происходит из документации FLAG_UPDATE_CURRENT
. Однако я не знаю, как это обойти в данный момент.
источник
Борется с
RemoteViews
и несколькими различнымиIntents
для каждогоButton
наHomeScreen
Widget. Сработало при добавлении этих: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);
источник
setAction
setAction
, вы можете сделать следующееaddCategory
.PendingIntent
ИспользуетсяIntent.filterEquals
для проверки равенства действия, данных, типа, класса и категорий. developer.android.com/reference/android/content/…Установить действие Решил это для меня. Вот мое понимание ситуации:
У меня есть несколько виджетов, к каждому из которых прикреплен PendingIntent. Всякий раз, когда кто-то обновлялся, обновлялись все. Флаги служат для описания того, что происходит с точно такими же PendingIntents.
Описание FLAG_UPDATE_CURRENT теперь читается намного лучше:
Если тот же PendingIntent, который вы создаете, уже существует, обновите все старые до нового PendingIntent, которое вы создаете.
Точно такое же определение смотрит на весь PendingIntent, ЗА ИСКЛЮЧЕНИЕМ дополнительных функций. Таким образом, даже если у вас есть разные дополнения для каждого намерения (для меня я добавлял appWidgetId), то для Android они одинаковы.
Добавление .setAction с некоторой фиктивной уникальной строкой сообщает ОС. Они совершенно разные и ничего не обновляют. В конце концов, вот моя реализация, которая работает так, как я хотел, где к каждому виджету прикреплено собственное намерение конфигурации:
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);
источник
Я вижу ответы, но нет объяснений. Также ни один из ответов не касается всех возможных решений, поэтому я постараюсь прояснить это.
Документация:
Причина проблемы:
Вы создаете 2 уведомления с 2 ожидающими намерениями. Каждое незавершенное намерение связано с намерением:
Intent intent = new Intent(context, testActivity.class);
Однако эти 2 намерения равны, поэтому, когда приходит ваше второе уведомление, оно запускает первое намерение.
Решение:
Вы должны сделать каждое намерение уникальным, чтобы никакие ожидающие выполнения намерения никогда не были равными. Как сделать намерения уникальными? Не по статистике, которую вы ставите
putExtra()
. Даже если экстры разные, намерения могут быть одинаковыми. Чтобы сделать каждое намерение уникальным, вы должны установить уникальное значение для действия намерения, или данных, или типа, или класса, или категории, или кода запроса: (любой из них будет работать)intent.setAction(...)
intent.setData(...)
intent.setType(...)
intent.setClass(...)
intent.addCategory(...)
PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);
Примечание . Установка уникального кода запроса может быть сложной задачей, потому что вам нужен int, а
System.currentTimeMillis()
возвращает long, что означает, что некоторые цифры будут удалены. Поэтому я бы рекомендовал выбрать категорию или действие и установить уникальную строку.источник
У меня была такая же проблема, и я смог ее исправить, изменив флаг на:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
источник
Как сказано в документации, используйте уникальный код запроса:
источник
Fwiw, мне повезло
PendingIntent.FLAG_CANCEL_CURRENT
больше, чем сPendingIntent.FLAG_UPDATE_CURRENT
.источник
У меня была такая же проблема, и я исправил ее, выполнив следующие действия.
1) Снимите любой флаг для намерения
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
2) вставьте intent.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, второй и последний. Второй - это «код запроса», и это должен быть уникальный номер (например, идентификатор вашего уведомления), иначе, если (как в вашем примере он равен нулю, он всегда будет перезаписан).
источник
// 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 () , intent, PendingIntent.FLAG_UPDATE_CURRENT);
источник
У меня такая же проблема, и я использую PendingIntent.html.FLAG_UPDATE_CURRENT, чтобы исправить ее.
Я проверил исходный код. В ActivityManagerService.java ключевой метод выглядит следующим образом. Когда флаг PendingIntent.FLAG_UPDATE_CURRENT и updateCurrent истинно. Некоторые дополнения будут заменены новыми, и мы получим замененный 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<PendingIntentRecord> 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(); }
источник