¿Alguien puede explicarme la diferencia entre AlarmManager.RTC_WAKEUP
y AlarmManager.ELAPSED_REALTIME_WAKEUP
? He leído la documentación pero todavía no entiendo realmente las implicaciones de usar uno sobre el otro.
Código de ejemplo:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
¿Qué tan diferente se ejecutarán las dos líneas de código? ¿Cuándo se ejecutarán esas dos líneas de código entre sí?
Aprecio tu ayuda.
fuente
System.currentTimeMillis()
lugar deSystem.currentTimeMills()
:)thirtySecondsFromNow
.A pesar de la respuesta actualmente aceptada y votada, los tipos AlarmManager.ELAPSED_REALTIME * junto con SystemClock.elapsedRealtime () siempre han sido más confiables que los relojes RTC para alarmas y temporización.
El uso de ELAPSED_REALTIME_WAKEUP con AlarmManager se basará en un reloj monótono a partir del tiempo de arranque " y continúa marcando incluso cuando la CPU está en modo de ahorro de energía, por lo que es la base recomendada para el tiempo de intervalo de propósito general ". Entonces,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60*1000, pendingIntent);
hará que su PendingIntent se dispare en 1 minuto (60 * 1000 milisegundos).
Considerando que, AlarmManager.RTC_WAKEUP es para el tiempo estándar de "muro" en milisegundos desde la época. Entonces,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60*10000, pendingIntent);
también puede activar la alarma dentro de 60 segundos, pero no de manera confiable, porque como se indica en la documentación de SystemClock :
Además, la pregunta solo hizo referencia a las alarmas * _WAKEUP, pero consulte también la documentación de AlarmManager sobre eso para asegurarse de que comprende lo que proporcionan las alarmas de activación y no activación .
fuente
elapsedRealtime()
es inferior enSystemClock
lugar deSystem
. EDITAR: ... Se alcanzó el límite diario de votos ...Solo una nota. Puede obtener el tiempo de actividad millis llamando:
long uptimeMillis = SystemClock.elapsedRealtime();
Entonces, si desea disparar la alarma dentro de 30 segundos y desea usar el reloj de tiempo de actividad en lugar del reloj normal, puede hacer lo siguiente:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Siempre que desee verificar el tiempo transcurrido en lugar de una fecha / hora específica, es mejor usar el tiempo de actividad. Esto se debe a que la hora actual establecida por el usuario en el dispositivo puede cambiar si el usuario la cambia usando la configuración.
fuente
Programé este problema en mi propio proyecto de esta manera. en el siguiente código que estoy usando
AlarmManager.ELAPSED_REALTIME_WAKEUP
para configurar la alarma a una hora específica. la variable 'intentName' se utiliza en intentFilter para recibir esta alarma. porque estoy disparando muchas alarmas de este tipo. cuando cancelo todas las alarmas. utilizo el método cancelar. dado en la parte inferior.
// para mantener alarmas y cancelar cuando sea necesario
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);
donde la función span es esta:
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); }
La función de cancelación de alarma es esta.
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(); } }
fuente
Algunas notas importantes al elegir qué alarma usar : (para quién ya leyeron los votos a favor)
El
RTC_WAKEUP
valle de la muerte: cambio de hora:si el usuario ha cambiado manualmente la hora al pasado, la alarma no se activará, y el futuro hará que la alarma se active inmediatamente si pasa la
RTC
marca de tiempo.No haga utilice esta alarma para realizar tareas importantes o de verificación del lado del cliente porque existe la posibilidad de que falle.
El
WAKEUP
significado (Marshmallow y superior)En general, no mucho. No despertará el dispositivo cuando
idle
o mientras está endoze
, por esoalarmManager.setExactAndAllowWhileIdle
oalarmManager.setAndAllowWhileIdle
( Doze & Idle )fuente