AlarmManager Android – RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

Quelqu’un peut-il m’expliquer la différence entre AlarmManager.RTC_WAKEUP et AlarmManager.ELAPSED_REALTIME_WAKEUP ? J’ai lu la documentation mais je ne comprends toujours pas l’implication d’utiliser l’un sur l’autre.

Exemple de code:

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

Dans quelle mesure les deux lignes de code seront-elles différentes? Quand ces deux lignes de code s’exécuteront-elles l’une par rapport à l’autre?

J’apprécie ton aide.

AlarmManager.ELAPSED_REALTIME_WAKEUP type AlarmManager.ELAPSED_REALTIME_WAKEUP permet de déclencher l’alarme depuis le démarrage:

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

va effectivement faire sonner l’alarme 10 min après le démarrage de l’appareil .

Il y a une timer qui commence à fonctionner lorsque l’appareil démarre pour mesurer la disponibilité de l’appareil et c’est le type qui déclenche votre alarme en fonction de la disponibilité de l’appareil.

Alors que AlarmManager.RTC_WAKEUP déclenchera l’alarme en fonction de l’heure de l’horloge. Par exemple si vous faites:

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

Cela déclenche l’alarme dans 30 secondes .

AlarmManager.ELAPSED_REALTIME_WAKEUP type AlarmManager.ELAPSED_REALTIME_WAKEUP est rarement utilisé par rapport à AlarmManager.RTC_WAKEUP .

Malgré la réponse actuellement acceptée et approuvée, les types AlarmManager.ELAPSED_REALTIME * avec SystemClock.elapsedRealtime () ont toujours été plus fiables que les horloges RTC pour les alarmes et la synchronisation.

Utiliser ELAPSED_REALTIME_WAKEUP avec AlarmManager reposera sur une horloge monotone à partir du temps de démarrage ” et continue à cocher même si le processeur est en mode d’économie d’énergie, de même que la base recommandée pour la temporisation d’intervalle “. Alors,

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

fera votre feu en attente en 1 min (60 * 1000 millisecondes).

Alors que AlarmManager.RTC_WAKEUP correspond à l’heure “mur” standard en millisecondes depuis l’époque. Alors,

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

peut également déclencher l’alarme dans 60 secondes à partir de maintenant, mais pas de manière fiable, car comme indiqué dans la documentation de SystemClock :

L’horloge murale peut être définie par l’utilisateur ou le réseau téléphonique (voir setCurrentTimeMillis (long)), de sorte que l’heure peut sauter en arrière ou en avant de manière imprévisible. Cette horloge ne doit être utilisée que lorsque la correspondance avec des dates et des heures réelles est importante, par exemple dans une application de calendrier ou de réveil. Les mesures d’intervalle ou de temps écoulé doivent utiliser une horloge différente. Si vous utilisez System.currentTimeMillis (), envisagez d’écouter les diffusions d’intention ACTION_TIME_TICK, ACTION_TIME_CHANGED et ACTION_TIMEZONE_CHANGED pour savoir quand l’heure change.

En outre, la question faisait uniquement référence aux alarmes * _WAKEUP, mais également à la documentation de AlarmManager pour vous assurer que vous compreniez ce que fournissent les alarmes de réveil et de non-réveil.

Juste une note. Vous pouvez obtenir la disponibilité du millis en appelant:

 long uptimeMillis = SystemClock.elapsedRealtime(); 

Donc, si vous voulez déclencher l’alarme dans 30 secondes et que vous souhaitez utiliser l’horloge de disponibilité au lieu de l’horloge normale, vous pouvez:

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

Lorsque vous souhaitez vérifier le temps écoulé au lieu d’une date / heure spécifique, il est préférable d’utiliser le temps de disponibilité. En effet, l’heure actuelle définie par l’utilisateur dans l’appareil peut changer si l’utilisateur la modifie à l’aide des parameters.

J’ai programmé ce problème dans mon propre projet de cette façon. en dessous de code j’utilise

 AlarmManager.ELAPSED_REALTIME_WAKEUP 

pour régler l’alarme à une heure spécifique. la variable ‘intentName’ est utilisée dans intentFilter pour recevoir cette alarme. parce que je tire de nombreuses alarmes de ce type. quand j’annule toutes les alarmes. J’utilise la méthode annuler. donné en bas.

// retient les alarmes et annule si nécessaire

  public static ArrayList alarmIntens = new ArrayList(); 

//

  public static Ssortingng 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.toSsortingng(); 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); 

où la fonction span est la suivante:

  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 fonction d’annulation d’alarme est la suivante.

 public static void cancel(Context c) { AlarmManager am = (AlarmManager) c .getSystemService(Context.ALARM_SERVICE); // cancel all alarms for (Iterator iterator = alarmIntens.iterator(); iterator .hasNext();) { Ssortingng intentName = (Ssortingng) iterator.next(); // cancel Intent intent = new Intent(intentName); PendingIntent pi = PendingIntent.getBroadcast(c, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); am.cancel(pi); // iterator.remove(); } } 

Quelques notes importantes lors du choix de l’alarme à utiliser : (pour qui a déjà lu les votes avec voix haute)

La vallée de la mort RTC_WAKEUP – changement d’heure:
Si l’utilisateur a manuellement changé le temps passé, l’alarme ne se déclenchera pas et l’avenir provoquera le déclenchement immédiat de l’alarme si elle dépasse l’horodatage RTC .
N’utilisez pas cette alarme pour effectuer des tâches de vérification / tâches importantes côté client, car elles risquent d’échouer.

La signification de WAKEUP (Marshmallow et ci-dessus)
En général – pas beaucoup. Ne pas réveiller le périphérique lorsqu’il est idle ou en idle , pour ce alarmManager.setExactAndAllowWhileIdle ou alarmManager.setAndAllowWhileIdle ( Doze & Idle )