#android #alarmmanager #alarms
#Android #alarmmanager #сигналы тревоги
Вопрос:
Я настраиваю сигналы тревоги, используя этот код
//in onCreate()
mAlarmManager = (AlarmManager) getApplicationContext()
.getSystemService(ALARM_SERVICE);
//called for each timer I schedule
Intent intent = new Intent (Intents.MY_INTENT_ACTION);
PendingIntent pendIntent = PendingIntent.getBroadcast(
getApplicationContext(), alert.getID(),
intent, PendingIntent.FLAG_ONE_SHOT);
long delay = 1000 * alert.getDuration();
Calendar cal = Calendar.getInstance();
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis() delay, pendIntent);
Но поведение, которое я вижу, не соответствует тому, что я должен видеть в документации 1,
набор общедоступных пустых значений (тип int, длительное время запуска, операция PendingIntent)
Если для того же IntentSender уже запланирован сигнал тревоги, он сначала будет отменен…Если для этого намерения уже запланирован сигнал тревоги (с равенством двух намерений, определяемых filterEquals(Intent) ), то он будет удален и заменен этим…
это говорит о том, что вызов set(int type, long triggetAtTime, PendingIntent operation) для уже предупрежденного намерения должен заменить старый сигнал тревоги для этого намерения. Я не вижу никаких аварийных сигналов. Вместо этого каждый сигнал тревоги, который я запускаю, срабатывает, несмотря на то, что намерения, которые запускаются ожидающими намерениями, должны совпадать (по filterEquals(intent)), поскольку все, что я установил для каждого намерения, является идентичным действием.
Я делаю что-то не так, или API ведет себя не так, как задокументировано?
Примечание: изменение экземпляра PendingIntent на
PendingIntent pendIntent = PendingIntent.getBroadcast(
getApplicationContext(), CONSTANT_ID,
intent, PendingIntent.FLAG_ONE_SHOT);
Ведет себя как ожидалось, отбрасывая любой уже установленный сигнал тревоги и заменяя его новым сигналом тревоги.
Комментарии:
1. Попробуйте избавиться
alarm.getID()
и использовать0
.2. смотрите мой комментарий к ответу Джонга ниже.
Ответ №1:
Может быть, это потому, что вы присваиваете каждому сигналу тревоги другой идентификатор ( alert.getID()
дает разные идентификаторы или нет?). Согласно документации, это не должно иметь значения, но все же вы все равно должны попробовать.
Если это тоже не сработает, сохраните ссылку на ваш последний установленный сигнал тревоги, и когда вам нужно его отменить, отмените его самостоятельно, а затем установите следующий.
Комментарии:
1. Вероятно, это оно. Это имеет значение. Другой идентификатор означает, что технически это другое намерение.
2. На самом деле это функциональность, которую я ищу, но она не соответствует тому, что я ожидаю от документации, поэтому это заставляет меня подозревать, что мое понимание где-то ошибочно. Я добавил еще одно предложение к цитате из документации, указывающее, что понятие повторного использования идентичных IntentSenders (PendingIntents) рассматривается отдельно, и afaik функционирует нормально. Мой вопрос заключается в том, рассматривает ли AlarmManager намерения, сгенерированные PendingIntent, или просто уникальность PendingIntent
3. В документации говорится, что он вычисляет намерения с помощью filterEquals. filterEquals не имеет ничего общего с PendingIntent, поэтому я не уверен, что это имеет значение. Но он должен это проверить.
4. Постарайтесь сохранить ссылку на ваш последний установленный сигнал тревоги, чтобы вы могли отменить его при необходимости.
5. Я предполагаю, что в документации есть проблема. Я обнаружил, что документация AudioManager «своего рода» неправильная, но мне удалось это исправить, сохранив статическую ссылку на мой AudioManager. Попробуйте сохранить статическую ссылку на ваш AlarmManager. У меня есть статическая ссылка на AlarmManager в одном из моих приложений, и оно без проблем отменяет совпадающие намерения.
Ответ №2:
Вы пробовали использовать флаг PendingIntent: PendingIntent.FLAG_UPDATE_CURRENT
intead of PendingIntent.FLAG_ONE_SHOT
?
Комментарии:
1. Я думаю, мы никогда не узнаем
Ответ №3:
Похоже, консенсус заключается в том, что документация для AlarmManager.set(), а также другие методы AlarmManager утверждают, что намерения (а не только переносные PendingIntents) сравниваются, чтобы проверить, установлен ли уже конкретный сигнал тревоги.
Не полагайтесь на соответствие намерений AlarmManager, вместо этого полагайтесь на соответствие PendingIntents, которое, похоже, работает так, как объявлено.