Android AlarmManager - RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP
Может кто-нибудь объяснить мне разницу между AlarmManager.RTC_WAKEUP
и AlarmManager.ELAPSED_REALTIME_WAKEUP
? Я прочитал документацию, но до сих пор не понимаю смысла использования одного над другим.
Пример кода:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
Насколько отличаются две строки кода? Когда эти две строки кода будут выполняться относительно друг друга?
Я ценю вашу помощь.
Ответы
Ответ 1
AlarmManager.ELAPSED_REALTIME_WAKEUP
type используется для запуска тревоги с момента загрузки:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);
фактически отключит будильник через 10 минут после загрузки устройства.
Существует таймер, который запускается, когда устройство загружается для измерения времени безотказной работы устройства, и это тип, который запускает ваш сигнал тревоги в соответствии с временем работы устройства.
В то время как AlarmManager.RTC_WAKEUP
вызывает тревогу в соответствии с временем работы часов. Например, если вы выполните:
long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);
это, с другой стороны, вызовет сигнал через 30 секунд.
AlarmManager.ELAPSED_REALTIME_WAKEUP
тип редко используется по сравнению с AlarmManager.RTC_WAKEUP
.
Ответ 2
Несмотря на принятый и опротестованный ответ, типы AlarmManager.ELAPSED_REALTIME * вместе с SystemClock.elapsedRealtime() всегда были более надежными, чем часы RTC для аварийных сигналов и времени.
Использование ELAPSED_REALTIME_WAKEUP с AlarmManager будет основываться на монотонных часах, начиная с момента загрузки "и продолжает галочкой, даже когда ЦП находится в режимах энергосбережения, поэтому рекомендуется использовать временные интервалы общего назначения". Таким образом,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
+ 60*1000, pendingIntent);
сделает ваш огонь PendingIntent за 1 минуту (60 * 1000 миллисекунд).
Принимая во внимание, что AlarmManager.RTC_WAKEUP является стандартным временем "стены" в миллисекундах с эпохи. Таким образом,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ 60*10000, pendingIntent);
может также вызвать будильник через 60 секунд, но не надежно, потому что, как указано в документации SystemClock:
Настенные часы могут быть установлены пользователем или телефонной сетью (см. setCurrentTimeMillis (long)), поэтому время может перепрыгнуть назад или вперед непредсказуемо. Эти часы следует использовать только тогда, когда важна переписка с реальными датами и временем, например в приложении календаря или будильника. Интервал или прошедшее время измерения должны использовать разные часы. Если вы используете System.currentTimeMillis(), рассмотрите возможность прослушивания ACTION_TIME_TICK, ACTION_TIME_CHANGED и ACTION_TIMEZONE_CHANGED Intent, чтобы узнать, когда изменится время.
Кроме того, на этот вопрос были указаны только аварийные сигналы * _WAKEUP, но также см. также документацию AlarmManager, чтобы убедиться, что вы понимаете, что пробуждения и предупреждения без пробуждения.
Ответ 3
Просто заметьте. Вы можете запросить миллионы вызовов:
long uptimeMillis = SystemClock.elapsedRealtime();
Итак, если вы хотите запустить будильник через 30 секунд, и вы хотите использовать часы безотказной работы вместо обычных часов, вы можете сделать:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Всякий раз, когда вы хотите проверить какое-то истекшее время вместо конкретной даты/времени, лучше всего использовать время безотказной работы. Это потому, что текущее время, заданное пользователем в устройстве, может измениться, если пользователь изменит его с помощью настроек.
Ответ 4
Я запрограммировал эту проблему в своем собственном проекте таким образом. в нижнем коде я использую
AlarmManager.ELAPSED_REALTIME_WAKEUP
чтобы установить будильник в определенное время.
переменная "targetName" используется в файле намерения для получения этого сигнала. потому что я стреляю по многим тревогам этого типа. когда я отменяю все тревоги. Я использую метод cancel. даны в нижней части.
//удерживать тревоги и отменить при необходимости
public static ArrayList<String> alarmIntens = new ArrayList<String>();
//
public static String setAlarm(int hour, int minutes, long repeatInterval,
final Context c) {
/*
* to use elapsed realTime monotonic clock, and fire alarm at a specific time
* we need to know the span between current time and the time of alarm.
* then we can add this span to 'elapsedRealTime' to fire the alarm at that time
* this way we can get alarms even when device is in sleep mood
*/
Time nowTime = new Time();
nowTime.setToNow();
Time startTime = new Time(nowTime);
startTime.hour = hour;
startTime.minute = minutes;
//get the span from current time to alarm time 'startTime'
long spanToStart = TimeUtils.spanInMillis(nowTime, startTime);
//
intentName = "AlarmBroadcast_" + nowTime.toString();
Intent intent = new Intent(intentName);
alarmIntens.add(intentName);
PendingIntent pi = PendingIntent.getBroadcast(c, alarms++, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//
AlarmManager am = (AlarmManager) c
.getSystemService(Context.ALARM_SERVICE);
//adding span to elapsedRealTime
long elapsedRealTime = SystemClock.elapsedRealtime();
Time t1 = new Time();
t1.set(elapsedRealTime);
t1.second=0;//cut inexact timings, seconds etc
elapsedRealTime = t1.toMillis(true);
if (!(repeatInterval == -1))
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
elapsedRealTime + spanToStart, repeatInterval, pi);
else
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsedRealTime
+ spanToStart, pi);
где функция span такова:
public static long spanInMillis(Time startTime, Time endTime) {
long diff = endTime.toMillis(true) - startTime.toMillis(true);
if (diff >= 0)
return diff;
else
return AlarmManager.INTERVAL_DAY - Math.abs(diff);
}
Функция отмены тревоги - это.
public static void cancel(Context c) {
AlarmManager am = (AlarmManager) c
.getSystemService(Context.ALARM_SERVICE);
// cancel all alarms
for (Iterator<String> iterator = alarmIntens.iterator(); iterator
.hasNext();) {
String intentName = (String) iterator.next();
// cancel
Intent intent = new Intent(intentName);
PendingIntent pi = PendingIntent.getBroadcast(c, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
//
iterator.remove();
}
}
Ответ 5
Некоторые важные примечания, когда выбирает, какой сигнал будет использоваться: (для кого уже прочитали вышеперечисленные голоса)
RTC_WAKEUP
Смертельная долина - изменение времени:
Если пользователь вручную изменил время на прошлое, сигнал тревоги не погаснет, а в будущем произойдет немедленное отключение будильника, если оно прошло с отметкой времени RTC
.
Не использовать. этот аварийный сигнал, чтобы выполнять любую проверку на стороне клиента/важные задания, потому что у него есть шанс потерпеть неудачу.
Значение WAKEUP
(Зефир и выше)
В общем - мало. Не будет пробуждать устройство, когда idle
или пока находится в doze
, для этого alarmManager.setExactAndAllowWhileIdle
или alarmManager.setAndAllowWhileIdle
(Doze and Idle)