47 votos

Android AlarmManager - RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

Alguien puede explicarme la diferencia entre AlarmManager.RTC_WAKEUP y AlarmManager.ELAPSED_REALTIME_WAKEUP? He leído la documentación, pero todavía no entienden realmente la implicación de uno sobre el otro.

Ejemplo de código:

    alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
                     scheduledAlarmTime, 
                     pendingIntent);

    alarmManager.set(AlarmManager.RTC_WAKEUP, 
                     scheduledAlarmTime, 
                     pendingIntent);

Cómo diferentes las dos líneas de código que se ejecutará? Cuando será que esos dos líneas de código a ejecutar en relación a cada uno de los otros?

Le agradezco su ayuda.

73voto

Rejinderi Puntos 3584

AlarmManager.ELAPSED_REALTIME_WAKEUP tipo es usado para activar la alarma desde el momento del arranque:

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);

va a hacer que la alarma 10 minutos después de que el dispositivo se inicia.

Hay un temporizador que comienza a funcionar cuando el dispositivo se inicia para medir el tiempo de funcionamiento del dispositivo y este es el tipo que dispara la alarma de acuerdo con el tiempo de funcionamiento del dispositivo.

Considerando, AlarmManager.RTC_WAKEUP activará la alarma de acuerdo con el tiempo del reloj. Por ejemplo, si usted:

int thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);

esto, por otro lado, se activará la alarma de 30 segundos a partir de ahora.

AlarmManager.ELAPSED_REALTIME_WAKEUP tipo rara vez se utiliza en comparación con AlarmManager.RTC_WAKEUP.

67voto

mborsuk Puntos 476

A pesar de que el actualmente aceptado y votado respuesta, AlarmManager.ELAPSED_REALTIME* tipos junto con SystemClock.elapsedRealtime() siempre ha sido más fiable que el RTC relojes para las alarmas y el tiempo.

El uso de ELAPSED_REALTIME_WAKEUP con AlarmManager va a confiar en un monótono del reloj a partir del momento de arranque "y sigue garrapata incluso cuando la CPU está en los modos de ahorro de energía, así que se la recomiendo base para propósito general intervalo de tiempo". Así,

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
                 + 60*1000, pendingIntent);

harán de su PendingIntent fuego en 1 min (60*1000 milisegundos).

Considerando, Que AlarmManager.RTC_WAKEUP es para el estándar de la "pared" de tiempo en milisegundos desde la época. Así,

alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                 + 60*10000, pendingIntent);

también puede activar la alarma de 60 segundos a partir de ahora, pero no de forma fiable, ya que como se señaló en el SystemClock documentación:

El reloj de pared puede ser configurado por el usuario o la red de telefonía (ver setCurrentTimeMillis(largo)), por lo que el tiempo puede saltar hacia atrás o reenvía de forma impredecible. Este reloj debe ser utilizado sólo cuando la correspondencia con el mundo real de las fechas y tiempos, es importante, como en un calendario o un reloj de alarma de la aplicación. Intervalo de tiempo transcurrido las mediciones deben usar un reloj diferentes. Si usted está usando Sistema.currentTimeMillis(), considere la posibilidad de escuchar la ACTION_TIME_TICK, ACTION_TIME_CHANGED y ACTION_TIMEZONE_CHANGED La intención de emisiones para saber cuando cambia el tiempo.

También, la pregunta sólo se hace referencia sólo a la *_WAKEUP alarmas pero vea también el AlarmManager documentación en que para asegurarse de que usted entiende lo que la activación vs no-activación de las alarmas de proporcionar.

11voto

Ena Puntos 797

Sólo una nota. Usted puede obtener el tiempo de actividad de millis llamando a:

long uptimeMillis =  SystemClock.elapsedRealtime();

Así que si quieres disparar la alarma de 30 segundos a partir de ahora, y desea utilizar el tiempo de reloj en lugar de la normal del reloj, usted puede hacer:

long thirtySecondsFromNow =  SystemClock.elapsedRealtime() + 30 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);

Cuando quieres buscar algo de tiempo transcurrido en lugar de una fecha y hora específicas, es mejor usar el tiempo de actividad. Eso es debido a que la corriente de tiempo definido por el usuario en el dispositivo puede cambiar si el usuario cambia el uso de la configuración.

2voto

ahmadalibaloch Puntos 194

He programado este problema en mi propio proyecto de esta manera. en el siguiente código que estoy utilizando

AlarmManager.ELAPSED_REALTIME_WAKEUP

para ajustar la alarma a una hora determinada. la variable 'intentName' es usada en la intentFilter para el receptor de esta alarma. porque estoy disparando muchas alarmas de este tipo. cuando puedo cancelar todas las alarmas. yo uso el método de cancelar. dada en la parte inferior.

//para sostener las 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 span función es este:

 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);
}

para cancelar la alarma de la función es este.

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();
    }
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: