it-swarm.com.de

Android AlarmManager - RTC_WAKEUP vs. ELAPSED_REALTIME_WAKEUP

Kann mir jemand den Unterschied zwischen AlarmManager.RTC_WAKEUP und AlarmManager.ELAPSED_REALTIME_WAKEUP erklären? Ich habe die Dokumentation gelesen, verstehe aber immer noch nicht wirklich die Bedeutung der Verwendung von einer über der anderen.

Beispielcode:

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

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

Wie unterschiedlich werden die beiden Codezeilen ausgeführt? Wann werden diese beiden Codezeilen relativ zueinander ausgeführt?

Ich schätze Ihre Hilfe.

82

AlarmManager.ELAPSED_REALTIME_WAKEUP type wird verwendet, um den Alarm seit dem Booten auszulösen:

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

wird den Alarm tatsächlich auslösen 10 Minuten nach dem Booten des Geräts

Es gibt einen Timer, der läuft, wenn das Gerät hochfährt, um die Betriebszeit des Geräts zu messen. Dies ist der Typ, bei dem der Alarm entsprechend der Betriebszeit des Geräts ausgelöst wird.

AlarmManager.RTC_WAKEUP löst den Alarm entsprechend der Uhrzeit aus. Zum Beispiel, wenn Sie dies tun:

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

andererseits wird der Alarm 30 Sekunden ab jetzt ausgelöst. 

AlarmManager.ELAPSED_REALTIME_WAKEUP type wird im Vergleich zu AlarmManager.RTC_WAKEUP nur selten verwendet. 

128
Rejinderi

Trotz der aktuell akzeptierten und aktualisierten Antwort waren die AlarmManager.ELAPSED_REALTIME * -Typen zusammen mit SystemClock.elapsedRealtime () immer zuverlässiger als die RTC - Uhren für Alarme und Timing.

Die Verwendung von ELAPSED_REALTIME_WAKEUP mit AlarmManager basiert auf einer monotonen Uhr ab Startzeit " und tickt auch dann weiter, wenn sich die CPU im Energiesparmodus befindet. Dies ist die empfohlene Grundlage für das allgemeine Intervall-Timing ". So,

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

lässt Ihr PendingIntent in 1 Minute (60 * 1000 Millisekunden) feuern.

Während AlarmManager.RTC_WAKEUP für die Standardzeit "wall" in Millisekunden seit der Epoche steht. So,

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

kann auch in 60 Sekunden den Alarm auslösen, jedoch nicht zuverlässig, da wie in der SystemClock-Dokumentation :

Die Wanduhr kann vom Benutzer oder vom Telefonnetz eingestellt werden (siehe setCurrentTimeMillis (long)), sodass die Zeit unvorhersehbar vor- oder zurückspringen kann. Diese Uhr sollte nur verwendet werden, wenn die Übereinstimmung mit realen Datums- und Uhrzeitangaben wichtig ist, z. B. in einem Kalender oder einer Weckeranwendung. Intervall- oder abgelaufene Zeitmessungen sollten eine andere Uhr verwenden. Wenn Sie System.currentTimeMillis () verwenden, sollten Sie die Sendungen ACTION_TIME_TICK, ACTION_TIME_CHANGED und ACTION_TIMEZONE_CHANGED anhören, um herauszufinden, wann sich die Zeit ändert.

Außerdem bezog sich die Frage nur auf die * _WAKEUP-Alarme, aber lesen Sie auch die AlarmManager - Dokumentation, um sicherzustellen, dass Sie verstehen, was die Weck- und Nicht-Weckalarme bieten.

104
mborsuk

Nur eine Notiz. Sie können die Uptime Millis anrufen:

long uptimeMillis =  SystemClock.elapsedRealtime();

Wenn Sie also den Wecker in 30 Sekunden auslösen möchten und die Betriebszeituhr anstelle der normalen Uhr verwenden möchten, können Sie Folgendes tun:

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

Wann immer Sie nach einer abgelaufenen Zeit anstelle eines bestimmten Datums/einer bestimmten Uhrzeit suchen möchten, sollten Sie die Betriebszeit am besten verwenden. Dies liegt daran, dass sich die vom Benutzer auf dem Gerät eingestellte aktuelle Uhrzeit ändern kann, wenn der Benutzer sie mithilfe der Einstellungen ändert.

16
Ena

Ich habe dieses Problem in meinem eigenen Projekt auf diese Weise programmiert. Im Code unten verwende ich

AlarmManager.ELAPSED_REALTIME_WAKEUP

um den Alarm zu einem bestimmten Zeitpunkt einzustellen . Die Variable 'intentName' wird im intentFilter zum Empfang dieses Alarms verwendet. weil ich viele Alarme dieses Typs auslöse. wenn ich alle Alarme storniere. Ich benutze die Methode Cancel. unten angegeben.

// Alarme halten und bei Bedarf abbrechen

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

wo ist die Funktion 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);
}

alarmabbruchfunktion ist dies.

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

Einige wichtige Hinweise, wenn Auswahl des zu verwendenden Alarms :( für wen, der bereits die abgelegten Stimmen gelesen hat)

TheRTC_WAKEUPDeath Valley - Zeitumstellung: 
Wenn der Benutzer die Zeit manuell in die Vergangenheit geändert hat, wird der Alarm nicht ausgelöst, und in Zukunft wird der Alarm sofort ausgelöst, wenn er den Zeitstempel RTC überschreitet.
Nicht Verwenden Sie diesen Alarm, um clientseitige Überprüfungen/wichtige Jobs auszuführen, da die Möglichkeit besteht, dass ein Fehler auftritt. 

TheWAKEUPBedeutung (Marshmallow und darüber)
Im Allgemeinen - nicht viel. Weckt das Gerät nicht auf, wenn idle oder doze für diesen alarmManager.setExactAndAllowWhileIdle oder alarmManager.setAndAllowWhileIdle ( Doze & Idle )

0
Andro Secy