Проблема с отменой 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).

Таким образом, вы можете назначить другой код запроса и отменить базу ожидающих намерений и забыть о дополнительных.

Был интересный сценарий, в котором я понял это поведение:

Я включил будильник в свой код и запустил его на устройстве, но не отменил его. Затем я изменил код запроса и запустил его снова. Таким образом была создана новая тревога. Я отменил новую тревогу, но будильник по-прежнему выполнялся из предыдущего кода. Я смущаюсь, почему будильник не отменяется. После того, как я узнал об этом из предыдущего кода с другим кодом запроса, я удалил приложение и снова установил его, и проблема была решена.