Может кто-нибудь объяснить мне разницу между AlarmManager.RTC_WAKEUP
и AlarmManager.ELAPSED_REALTIME_WAKEUP
? Я прочитал документацию, но до сих пор не совсем понимаю, что означает использование одного над другим.
Пример кода:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
Насколько по-разному будут выполняться две строки кода? Когда эти две строки кода будут выполняться относительно друг друга?
Я ценю вашу помощь.
источник
System.currentTimeMillis()
вместоSystem.currentTimeMills()
:)thirtySecondsFromNow
.Несмотря на принятый в настоящее время и одобренный ответ, типы 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 :
Кроме того, вопрос касается только сигналов тревоги * _WAKEUP, но также см. Документацию по AlarmManager , чтобы убедиться, что вы понимаете, что предоставляют сигналы пробуждения и не пробуждающие.
источник
elapsedRealtime()
это подSystemClock
вместоSystem
. РЕДАКТИРОВАТЬ: ... Дневной лимит голосов достигнут ...Просто примечание. Вы можете получить миллисекунд безотказной работы, позвонив:
long uptimeMillis = SystemClock.elapsedRealtime();
Поэтому, если вы хотите включить будильник через 30 секунд и хотите использовать часы безотказной работы вместо обычных часов, вы можете сделать:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Всякий раз, когда вы хотите проверить прошедшее время вместо определенной даты / времени, лучше использовать время безотказной работы. Это связано с тем, что текущее время, установленное пользователем на устройстве, может измениться, если пользователь изменит его с помощью настроек.
источник
Так я запрограммировал эту задачу в собственном проекте. в приведенном ниже коде я использую
AlarmManager.ELAPSED_REALTIME_WAKEUP
установить будильник на определенное время. переменная intentName используется в intentFilter для получения этого сигнала тревоги. потому что я запускаю много сигналов тревоги этого типа. когда я отменяю все будильники. Я использую метод отмены. дано внизу.
// для удержания сигналов тревоги и отмены при необходимости
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);
где функция диапазона это:
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(); } }
источник
Некоторые важные примечания при выборе того, какой будильник использовать : (для тех, кто уже прочитал голоса за)
Долина
RTC_WAKEUP
смерти - изменение времени:если пользователь вручную изменил время на прошлое, будильник не сработает, а будущее вызовет немедленное срабатывание будильника, если оно пройдет мимо
RTC
отметки времени.Не делайте используйте этот сигнал тревоги для выполнения каких-либо проверок на стороне клиента / важных задач, потому что он может выйти из строя.
WAKEUP
Смысл (Зефир и выше)В общем - не так много. Не будет выводить устройство из спящего режима, когда оно
idle
включеноdoze
, для этогоalarmManager.setExactAndAllowWhileIdle
илиalarmManager.setAndAllowWhileIdle
( Дремота и режим ожидания )источник