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

Solutions Collecting From Web of "Проблема с отменой AlarmManager – PendingIntent"

Согласно документации Android, чтобы остановить будильник, вы должны создать Intent с теми же данными, но не обязательно такими же дополнениями:

Public void cancel (операция PendingIntent)

Удалите все аварийные сигналы с соответствующим намерением. Любая тревога любого типа, чье намерение соответствует этому> одному (как определено filterEquals (Intent) ), будет отменено.

filterEquals(Intent)

Public boolean filterEquals (Intent other)

Определите, совпадают ли два намерения для целей разрешения (фильтрации) намерений. > То есть, если их действие, данные, тип, класс и категории одинаковы. Это не сравнивает лишние данные, включенные в намерения.

Как я сказал в своем комментарии, кажется, что вам просто нужно воссоздать тот же самый объект PendingIntent и поместить в него те же Extras. Затем вы вызываете

 am.cancel(sender); 

И ваш конкретный сигнал тревоги должен быть отменен. Я не могу найти лучший способ сделать это лично. Я нашел эту информацию, чтобы подтвердить мои ожидания в другом месте .

Он гласит:

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

alarmManager.cancel (pendingIntent);

Обратите внимание, что объект pendingIntent не должен быть одним и тем же объектом. Поля намерения, такие как действие, класс, категория и т. Д., Должны быть одинаковыми при создании тревоги. Цель используется для идентификации тревоги для ее отмены.

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

Я думаю, что нужно getBroadcast() параметр getBroadcast() в 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); 

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

 intent.putExtra("Name_pill", "pill"); 

Дополнительные привычки не будут работать, чтобы отменить ожидаемое намерение.

pendingIntent.cancel() удалит только это ожидающее намерение, которое срабатывает с filterEquals(Intent) же filterEquals(Intent) и этот метод не сравнивает любые дополнительные данные, данные для намерения.

Это содержание с сайта разработчика андроида 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() 

Как указано в документации по Android в ожидании намерений, которые эквивалентны по Intent.filterEquals, но имеют другой код запроса, считаются разными:

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

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

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

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