Проблема с отменой AlarmManager - PendingIntent - PullRequest
10 голосов
/ 09 сентября 2010

У меня есть приложение, которое напоминает людям делать их задачи. Так что есть один 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)]);

Ответы [ 5 ]

12 голосов
/ 28 августа 2011

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

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

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

filterEquals(Intent)

public boolean filterEquals (Intent other)

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

5 голосов
/ 03 декабря 2010

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

am.cancel(sender);

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

Она гласит:

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

alarmManager.cancel (pendingIntent);

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

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

1 голос
/ 26 февраля 2013

Я думаю, что параметр requestCode в getBroadcast() должен быть упомянут. Я согласен, что все тревоги будут отменены в соответствии с заданным Намерением. Но аварийный сигнал можно сделать уникальным, используя уникальный requestCode при определении PendingIntent для отмены. Таким образом, будут отменены только те сигналы тревоги, которые имеют одинаковые значения intent и 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 существует в соответствии с this :

PendingIntent pending1 = PendingIntent.getBroadcast(this, TIMER_2, i, 
                PendingIntent.FLAG_NO_CREATE);
boolean alarmUp = (pending1 != null);

alarmUp будет false (обратите внимание, FLAG_NO_CREATE используется, чтобы не создавать новый, если он не существует), поэтому попытайтесь использовать тот же requestCode :

PendingIntent pending2 = PendingIntent.getBroadcast(this, TIMER_1, i, 
                PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);

alarmUp будет true , теперь попытка с новым намерением содержит другое дополнение:

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 также будет true , поскольку i и i2 одинаковы, хотя дополнительные значения не совпадают, поэтому теперь вы можете удалить этот сигнал тревоги:

am.cancel(pending2);
0 голосов
/ 07 июля 2013

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

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

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

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

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

0 голосов
/ 06 апреля 2013

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

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

Дополнительные не будут работать, чтобы отменить ваше ожидающее намерение.1006 *

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

это содержимое сайта разработчика Android filterEquals(Intent)

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

, если мы рассмотрим ваш сценарий, когда вы передадите этот Extra для намерения в то время, вам нужно только сохранить уникальный идентификатор в некоторых sharedpreference, который указан в параметре, и одну вещь, которую вы должны иметь в виду, что ID должен быть уникальным.

и, когда вы предполагаете отменить этот сигнал, просто передайте то же самое намерение с сохраненным идентификатором и отмените 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()
...