Czy ktoś może mi wyjaśnić różnicę między AlarmManager.RTC_WAKEUP
iAlarmManager.ELAPSED_REALTIME_WAKEUP
? Przeczytałem dokumentację, ale nadal nie do końca rozumiem konsekwencje używania jednego nad drugim.
Przykładowy kod:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
Jak różne będą dwie linie kodu wykonane? Kiedy te dwa wiersze kodu zostaną wykonane względem siebie?
Doceniam twoją pomoc.
źródło
System.currentTimeMillis()
zamiastSystem.currentTimeMills()
:)thirtySecondsFromNow
.Pomimo obecnie zaakceptowanej i przegłosowanej odpowiedzi, typy AlarmManager.ELAPSED_REALTIME * wraz z SystemClock.elapsedRealtime () zawsze były bardziej niezawodne niż zegary RTC dla alarmów i czasu.
Używanie ELAPSED_REALTIME_WAKEUP z AlarmManager będzie polegać na zegarze monotonicznym począwszy od czasu rozruchu i będzie kontynuował tykanie nawet wtedy, gdy procesor jest w trybach oszczędzania energii, więc jest to zalecana podstawa dla ogólnego pomiaru czasu w odstępach czasu . Więc,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60*1000, pendingIntent);
sprawi, że Twój PendingIntent zostanie uruchomiony w ciągu 1 minuty (60 * 1000 milisekund).
Podczas gdy AlarmManager.RTC_WAKEUP jest dla standardowego czasu "ściany" w milisekundach od epoki. Więc,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 60*10000, pendingIntent);
może również wywołać alarm za 60 sekund od teraz, ale nie niezawodnie, ponieważ jak zaznaczono w dokumentacji SystemClock :
Ponadto pytanie odnosiło się tylko do alarmów * _WAKEUP, ale zapoznaj się również z dokumentacją AlarmManager , aby upewnić się, że rozumiesz, co zapewniają alarmy budzenia, a co nie.
źródło
elapsedRealtime()
jest podSystemClock
zamiastSystem
. EDYCJA: ... Osiągnięto dzienny limit głosów ...Tylko uwaga. Możesz uzyskać czas pracy w milisach połączeń:
long uptimeMillis = SystemClock.elapsedRealtime();
Więc jeśli chcesz uruchomić alarm za 30 sekund od teraz i chcesz użyć zegara uptime zamiast normalnego zegara, możesz wykonać:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000; alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Ilekroć chcesz sprawdzić upływ czasu zamiast określonej daty / godziny, najlepiej jest skorzystać z uptime. Dzieje się tak, ponieważ aktualny czas ustawiony przez użytkownika w urządzeniu może ulec zmianie, jeśli użytkownik zmieni go za pomocą ustawień.
źródło
W ten sposób zaprogramowałem ten problem we własnym projekcie. w poniższym kodzie używam
AlarmManager.ELAPSED_REALTIME_WAKEUP
ustawić alarm na określony czas. zmienna „intentName” jest używana w intentFilter do odbierania tego alarmu. ponieważ odpalam wiele alarmów tego typu. kiedy anuluję wszystkie alarmy. używam metody anuluj. podane na dole.
// do wstrzymywania alarmów i anulowania ich w razie potrzeby
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);
gdzie funkcja span jest taka:
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); }
to jest funkcja kasowania alarmu.
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(); } }
źródło
Kilka ważnych uwag przy wyborze alarmu do użycia : (dla kogo już przeczytano głosy za)
RTC_WAKEUP
Death Valley - zmiana czasu:Jeśli użytkownik musi ręcznie czas przesiąść się na przeszłość alarmu nie zgaśnie, a przyszłość spowoduje alarm zgaśnie natychmiast piłkę do
RTC
datownik.Nie rób używaj tego alarmu do weryfikacji po stronie klienta / ważnych zadań, ponieważ może się nie powieść.
WAKEUP
Sens (Zefir i powyżej)w ogóle - nie dużo. Nie wybudza urządzenia w trakcie
idle
lub w trakciedoze
, w tym celualarmManager.setExactAndAllowWhileIdle
lubalarmManager.setAndAllowWhileIdle
( Drzemka i bezczynność )źródło