Android продолжает кэшировать мои намерения. Дополнения, как объявить ожидающее намерение, которое сохраняет свежие дополнения?

Несколько дней назад я изо всех сил пытался найти способ использовать настраиваемые намерения для моих сигналов тревоги. Хотя я получил четкий ответ, что мне нужно настроить намерения на основе некоторого уникального идентификатора, например. setAction() все еще есть некоторые проблемы.

Я определяю PendingIntent следующим образом:

Intent intent = new Intent(this, viewContactQuick.class);
intent.setAction("newmessage"+objContact.getId());//unique per contact
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK ).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP );
intent.putExtra("id", Long.parseLong(objContact.getId()));
intent.putExtra("results", result.toArray());

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);

затем это используется диспетчером уведомлений

NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
// first try to clear any active notification with this contact ID
mNotificationManager.cancel(Integer.parseInt(objContact.getId()));

// then raise a new notification for this contact ID
mNotificationManager.notify(Integer.parseInt(objContact.getId()), notification);

Это работает следующим образом:

  • приложение создает сообщение для контакта
  • намерение предоставляется с идентификатором контакта и подробностями о сообщении
  • уведомление поднимается вместе с сообщением
  • действия пользователя над уведомлением, и приложение отображает сообщение, переданное намерением

Проблема

Это может произойти более одного раза для контакта. И когда генерируется второе сообщение, уведомление поднимается хорошо (с сообщением там все в порядке), но намерение, когда пользователь выполняет действие с уведомлением, использует старые данные, поэтому передается предыдущее сообщение, а не новое сообщение.

Так что каким-то образом цель заключается в кэшировании и повторном использовании предыдущих дополнений. Как я могу сделать его уникальным для каждого контакта и каждого действия?


person Pentium10    schedule 29.06.2010    source источник
comment
Есть ли способ очистить все кэшированные IntentExtras? Я предполагаю, что исправил это сейчас, но старые кэшированные намерения все еще остаются...   -  person OneWorld    schedule 10.12.2010
comment
Аналогичная проблема может возникнуть в зависимости от флагов Intent или режима запуска активности. В этом случае вам необходимо проверить Activity::onNewIntent, так как Activity::getIntent вернет ИСХОДНОЕ намерение, а не новое намерение с обновленным действием/дополнениями/и т. д.   -  person brack    schedule 07.01.2011


Ответы (2)


Если только один из ваших PendingIntents для этого контакта будет ожидающим в любой момент времени, или если вы всегда хотите использовать последний набор дополнений, используйте FLAG_UPDATE_CURRENT при создании PendingIntent.

Если сразу несколько PendingIntent для конкретного контакта будут ожидающими выполнения, и у них должны быть отдельные дополнительные функции, вам нужно будет добавить количество или отметку времени или что-то еще, чтобы различать их.

intent.setAction("actionstring" + System.currentTimeMillis());

ОБНОВЛЕНИЕ

Кроме того, слегка задокументированный второй параметр для getActivity() и kin для PendingIntent, по-видимому, может использоваться для создания отдельных объектов PendingIntent для одного и того же базового Intent, хотя я никогда не пробовал этого.

person CommonsWare    schedule 29.06.2010
comment
Я закончил тем, что добавил метку времени к действию. - person Pentium10; 05.07.2010
comment
классно! я использовал свой текущий идентификатор виджета, чтобы разделить их (также допуская некоторый уровень кэширования). - person DavidG; 13.09.2011
comment
У меня небольшой вопрос о setAction(). Что именно он делает? Я посмотрел на Дока, но он все еще был немного запутанным. - person Andy; 11.07.2012
comment
@Andy: setAction(), гм, устанавливает действие. Действие обычно используется с неявными Intent (подумайте, ACTION_VIEW, чтобы вызвать действие, чтобы перейти к просмотру чего-либо). Если ваш Intent указывает компонент назначения (например, new Intent(this, Something.class)), действие не используется для целей маршрутизации, но оно все равно используется для поездки. И действие — это одна из вещей, которая используется для определения того, эквивалентно ли одно Intent другому. - person CommonsWare; 11.07.2012
comment
Отличный ответ! Я могу подтвердить, что установка второго параметра для getActivity() на случайное целое число решает эту проблему. Жаль, что это устаревший параметр? - person IgorGanapolsky; 22.10.2012
comment
@IgorG.: Этот параметр не устарел. В документации утверждается, что он не используется, но документация в этой области явно несовершенна. - person CommonsWare; 22.10.2012
comment
Я думал, именно поэтому существуют filterEquals() и filterHashCode(). Кажется, они больше не работают: stackoverflow.com/questions/13553911/ - person AlikElzin-kilaka; 25.11.2012
comment
Я также могу подтвердить, что обновление второго параметра действительно делает каждый Intent и PendingIntent уникальным. - person Soham; 27.11.2012
comment
Вот ссылка на класс PendingIntent для установки флага: developer.android. ком/ссылка/андроид/приложение/ - person david; 13.10.2016

Обычно я указываю уникальный код запроса, чтобы мои PendingIntents не переопределяли друг друга:

PendingIntent pending = PendingIntent.getService(context, unique_id, intent, 0);

И в вашем случае я согласен с CommonsWare, вам просто нужен флаг FLAG_UPDATE_CURRENT. Новые дополнительные функции переопределяют старые значения.

person Fedor    schedule 29.06.2010
comment
Этого недостаточно, чтобы ваши PendingIntent не сталкивались друг с другом. Вы также должны использовать PendingIntent.FLAG_UPDATE_CURRENT - person IgorGanapolsky; 29.10.2012
comment
и создать уникальный_ид здесь - хорошее решение int unique_id = (int) System.currentTimeMillis(); - person Glenn Sonna; 23.02.2015
comment
Я не уверен, что вы можете использовать Long там или на самом деле произвольное случайное Int в этом отношении. IIRC, Android выдаст исключение, если вы используете любой из битов в большем байте для кодов запросов, что в основном ограничивает вас небольшими положительными числами. - person milosmns; 10.01.2020
comment
Да, нашел, что-то вроде этого - stackoverflow.com/questions/33331073/ - person milosmns; 10.01.2020