Проблема с отменой AlarmManager - PendingIntent
У меня есть приложение, которое напоминает людям о выполнении своих задач. Таким образом, есть один PendingIntent, теперь пользователь может удалить будильник, когда захочет. В этом коде есть только один PendingIntent для нескольких пользовательских аварийных сигналов, поэтому я запутался в том, что вы отменили этот конкретный аварийный сигнал, когда дополнительные настройки "pill"
. Оставшиеся аварийные сигналы не должны отменяться. Я не имею понятия об этой проблеме. Надеюсь, я поняла. Спасибо
Intent intent = new Intent(this, AlarmNotifyReceiver.class);
intent.putExtra("Name_pill", "pill");
sender = PendingIntent.getBroadcast(this,
DatabaseConstants.NOTIFICATION_ID + 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), sender);
updateTheFlag(pillName[(pillName.length-1)]);
Ответы
Ответ 1
В соответствии с документацией на Android, чтобы остановить будильник, вы должны создать Intent
с теми же данными, но не обязательно такими же дополнениями:
public void cancel (операция PendingIntent)
Удалите все аварийные сигналы с соответствующим намерением. Любая тревога любого типа, чье намерение соответствует этому > одному (как определено filterEquals (Intent)), будет отменено.
filterEquals(Intent)
public boolean filterEquals (Intent other)
Определите, совпадают ли два намерения для целей разрешения (фильтрации) намерений. > То есть, если их действие, данные, тип, класс и категории одинаковы. Это не сравнивает лишние данные, включенные в намерения.
Ответ 2
Как я уже сказал в своем комментарии, вам просто нужно воссоздать тот же самый объект PendingIntent и поместить в него такие же Extras. Затем вы вызываете
am.cancel(sender);
И ваш конкретный сигнал тревоги должен быть отменен. Я не могу найти лучший способ сделать это лично. Я нашел эту информацию, чтобы подтвердить свое ожидание в другом месте.
Он гласит:
Повторяющиеся аварийные сигналы должны быть отменены, чтобы остановить их. AlarmManager предоставляет метод cancel(), который требует того же класса намерений, с которым создается намерение. Так вы можете отменить будильник.
alarmManager.cancel(pendingIntent);
Обратите внимание, что объект pendingIntent не должен быть одним и тем же объектом. Поля намерения, такие как действие, класс, категория и т.д., Должны быть одинаковыми при создании тревоги. Цель состоит в том, чтобы идентифицировать будильник для его отмены.
Это в контексте повторения сигналов тревоги, но одноразовые тревоги должны быть отменены таким же образом, если я не ошибаюсь. Я не могу проверить его более подробно самостоятельно, потому что я на работе, но это должно работать.
Ответ 3
Я думаю, что нужно указать параметр requestCode в getBroadcast()
. Я согласен, что все аварийные сигналы будут отменены в соответствии с заданным намерением. Но тревогу можно сделать уникальной, используя уникальный RequestCode при определении PendingIntent для отмены. Таким образом, будут отменены только те сигналы тревоги, которые имеют одинаковую цель и requestCode:
int TIMER_1 = 1;
int TIMER_2 = 2;
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, AppReciever.class);
i.putExtra("timer", "one");
PendingIntent pending = PendingIntent.getBroadcast(this, TIMER_1, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);
затем проверьте, что PendingIntent существует в соответствии с этим:
PendingIntent pending1 = PendingIntent.getBroadcast(this, TIMER_2, i,
PendingIntent.FLAG_NO_CREATE);
boolean alarmUp = (pending1 != null);
alarmUp
будет ложным (обратите внимание, что FLAG_NO_CREATE используется, чтобы не создавать новый, если он не существует), поэтому попытка с одним и тем же кодом запроса:
PendingIntent pending2 = PendingIntent.getBroadcast(this, TIMER_1, i,
PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);
alarmUp
будет правдой, теперь попытка с новым намерением содержит различные дополнительные значения:
Intent i2 = new Intent(this, AppReciever.class);
i2.putExtra("timer", "two");
pending2 = PendingIntent.getBroadcast(this, TIMER_1, i2,
PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);
alarmUp
будет истинным, так как i
и i2
совпадают, хотя дополнительный нет, поэтому теперь вы можете удалить этот сигнал:
am.cancel(pending2);
Ответ 4
Итак, есть одно ожидающее намерение, теперь пользователь может удалить alram, когда он хочет. В этом коде есть только одно ожидающее несколько пользовательских аварийных сигналов, поэтому я запутался в отмене этого конкретного тревога, где дополнительные таблетки - это пилюля.
intent.putExtra("Name_pill", "pill");
Дополнительные привычки не будут работать, чтобы отменить ожидаемое намерение.
pendingIntent.cancel()
удалит только это ожидающее намерение, которое запускается с тем же filterEquals(Intent)
, и этот метод не сравнивает лишние данные, данные для намерения.
это содержание с сайта разработчика android filterEquals(Intent)
Определите, являются ли два намерения одинаковыми для целей намерения разрешение (фильтрация). То есть, если их действие, данные, тип, класс, и категории одинаковы. Это не сравнивает лишние данные включены в намерения.
если мы рассмотрим ваш сценарий, когда вы передадите это Extra
на намерение в то время, вам нужно сохранить только уникальный идентификатор в некотором sharedpreference
, который указан в параметре, и один факт, что вы должны иметь в виду, что идентификатор должен быть уникальным.
и когда вы решили отменить этот сигнал, просто передайте такое же намерение с сохраненным идентификатором и отмените его pendingintent
.
Создать
preference_saved_value = DatabaseConstants.NOTIFICATION_ID + 1
sender = PendingIntent.getBroadcast(this,
preference_saved_value, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
ОТМЕНА
sender = PendingIntent.getBroadcast(this,
preference_saved_value, intent,PendingIntent.FLAG_UPDATE_CURRENT);
sender.cancel()
Ответ 5
Как указано в документации по Android в ожидании намерений, которые эквивалентны по Intent.filterEquals, но имеют другой код запроса, считаются разными:
Если вам действительно нужно несколько различных объектов PendingIntent, активных в в то же время (например, для использования в качестве двух уведомлений, которые показаны одновременно в то же время), тогда вам нужно будет убедиться, что есть что-то они отличаются друг от друга, чтобы связать их с разными PendingIntents. Это может быть любой из атрибутов Intent, рассмотренных Intent.filterEquals или различные целые числа кода запроса, getActivity (Контекст, int, Intent, int), getActivities (Контекст, int, Intent [], int), getBroadcast (Context, int, Intent, int) или getService (Контекст, int, Intent, int).
Таким образом, вы можете назначить другой код запроса и отменить базу ожидающих намерений и забыть о дополнительных.
Был интересный сценарий, в котором я понял это поведение:
Я включил будильник в свой код и запустил его на устройстве, но не отменил его. Затем я изменил код запроса и запустил его снова. Таким образом была создана новая тревога. Я отменил новую тревогу, но будильник по-прежнему выполнялся из предыдущего кода. Я смущаюсь, почему будильник не отменяется. После того, как я узнал об этом из предыдущего кода с другим кодом запроса, я удалил приложение и снова установил его, и проблема была решена.