Как с помощью AlarmManager доставляются прошлые тревоги?

У меня вопрос по установке будильников в AlarmManager. Я нашел в документах что-то, чего не понял (см. ниже). Я хотел бы установить 10 будильников, которые запускают режим звонка попеременно без звука и в обычном режиме, все с разным временем срабатывания. Теперь устройство переходит в спящий режим и снова становится активным после того, как все 10 будильников устареют. После этого AlarmManager немедленно передает сигнал тревоги? Будет ли это только 10-е (что с режимом звонка)?

Намерения тревоги доставляются с дополнительными данными типа int, называемыми Intent.EXTRA_ALARM_COUNT, которые указывают, сколько прошлых событий тревоги было накоплено в этой широковещательной рассылке намерения. Повторяющиеся будильники, которые не были доставлены из-за того, что телефон был в спящем режиме, могут иметь количество больше единицы при доставке.


person cody    schedule 11.12.2010    source источник


Ответы (2)


Насколько я понимаю, при планировании тревоги с помощью диспетчера тревог вы должны предоставить экземпляр PendingIntent.

Есть два типа будильников: одни просыпаются и работают, даже если телефон спит или заблокирован, а другие нет.

Кроме того, если вы должны были запланировать 10 событий одновременно, AlarmManager заменит существующее намерение Scheduled Pending новым, если только вы не назначали ему другие действия намерения. Когда я использую Alarms, я всегда использовал базу данных sqlite для постановки в очередь заданий, которые я хотел выполнить по какому-то расписанию. Оттуда я планировал один будильник за раз, потому что все они выполняли одно и то же намерение, когда звонил зуммер.

Дополнительный EXTRA_ALARM_COUNT будет иметь значение, если вы запланировали повторяющийся будильник, и он срабатывал несколько раз, когда пользовательское устройство спало. Когда телефон проснется, он воспроизведет все, что было поставлено в очередь в прошлом. В этом случае ваше ожидающее намерение сработает и будет иметь значение, равное тому, сколько раз ваш будильник был пропущен, потому что он был создан с использованием RTC или ELAPSED_REALTIME в качестве типа при вызове метода set.

Вот пример того, как я обычно взаимодействую с AlarmManger.

protected void scheduleNext(Context context) {
    AlarmManager alarmManager = getAlarmManager();
    Intent intent = new Intent(MyIntent.ACTION_DO_WORK);
    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

    String where = Queue.SCHEDULED_DATE + "= (select min(" + Queue.SCHEDULED_DATE + ") from queue where " + Queue.COMPLETED_DATE + " is null)";
    Cursor cursor = context.getContentResolver().query(Queue.CONTENT_URI, Queue.PROJECTION, where, null, null);

    if (cursor.moveToFirst()) {
        int id = cursor.getInt(cursor.getColumnIndex(Queue._ID));
        long when = cursor.getLong(cursor.getColumnIndex(Queue.SCHEDULED_DATE));
        alarmManager.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
    }   

    cursor.close();
}
person Michael    schedule 12.12.2010
comment
Спасибо за это объяснение. Чего я не понимаю, так это почему PendingIntents перезаписываются. Разве нельзя запланировать два PendingIntent, которые делают то же самое в разное время? - person cody; 12.12.2010
comment
И еще вопрос: ...Когда телефон проснется, он воспроизведет все, что стояло в очереди в прошлом. В этом случае ваше ожидающее намерение сработает... - вы имеете в виду только последнее PendingIntent? - person cody; 12.12.2010
comment
Да, AlarmManager отправит PendingIntent в следующий раз, когда устройство проснется, если будильник сработал, когда устройство находилось в спящем режиме. - person Michael; 12.12.2010
comment
У меня было такое же разочарование, когда я пытался поставить в очередь кучу вещей, которые я хотел активировать в разное время. Вот почему я начал реализовывать свою внутреннюю очередь. - person Michael; 12.12.2010
comment
Хорошо, и последнее: не могли бы вы объяснить, что такое повторяющиеся сигналы тревоги, разве они не имеют разных намерений? Возможно, это может быть решением этой проблемы... :) - person cody; 12.12.2010
comment
Хорошо .. Я читал, что для повторного будильника нужен фиксированный интервал. Таким образом, ваш способ планировать одни и те же намерения несколько раз кажется решением. Но когда вы вызываете свой scheduleNext()... это действительно немного расстраивает... - person cody; 12.12.2010
comment
У меня есть служба, которая отвечает за планирование будильника. Когда мое действие по выполнению работы завершается, оно запускает службу, чтобы запланировать следующее. Допустим, у меня есть пять вещей, которые нужно сделать в разное время. Служба «Моя работа» выполнит любую работу, для которой есть запланированное время в прошлом, и которая не была завершена. При выполнении всех прошлых заданий служба выполнения работ обновляет очередь с указанием даты/времени выполнения. После того, как все работы будут выполнены. Служба выполнения работы запускает расписание следующей службы, устанавливая будильник на следующее предстоящее время, когда необходимо выполнить работу. - person Michael; 12.12.2010
comment
Джеп, звучит хорошо. Я подумал о чем-то подобном... чтобы запланировать следующий будильник, как только завершится последняя реакция. Я попробую так. Спасибо! - person cody; 13.12.2010

Одна вещь, которая наиболее неизвестна (в основном потому, что в документации Android говорится, что ее "в данный момент не используется") заключается в том, что PendingIntent не будет повторно использоваться, если requestCode отличается. Поэтому вместо этого создайте PI с кодом запроса 0:

    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0); 

Вы можете реализовать счетчик и сделать что-то вроде:

    PendingIntent pendingIntent = PendingIntent.getService(context, counter, intent, 0); 

Я знаю, что это будет работать для доставленных/отправленных SMS-уведомлений PendingIntents, где у вас есть та же проблема: если PendingIntent используется повторно и у вас есть более 1 ожидающего уведомления, вы не будете знать, для какого SMS это было. Но велики шансы, что это также сработает для незавершенного оповещения PendingIntent.

Надеюсь это поможет.

person Flow    schedule 06.02.2011