누군가가 나에게 사이의 차이 설명 할 수 AlarmManager.RTC_WAKEUP
와 AlarmManager.ELAPSED_REALTIME_WAKEUP
? 나는 문서를 읽었지만 여전히 하나를 사용하는 것의 의미를 실제로 이해하지 못합니다.
예제 코드 :
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
두 줄의 코드가 얼마나 다르게 실행됩니까? 이 두 줄의 코드는 언제 서로 상대적으로 실행됩니까?
도와 주셔서 감사합니다.
답변
AlarmManager.ELAPSED_REALTIME_WAKEUP
type은 부팅 시간 이후 알람을 트리거하는 데 사용됩니다.
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);
실제로 장치가 부팅 되고 10 분 후에 알람이 울립니다 .
장치의 가동 시간을 측정하기 위해 장치가 부팅 될 때 실행되는 타이머가 있으며 장치의 가동 시간에 따라 알람을 트리거하는 유형입니다.
반면, AlarmManager.RTC_WAKEUP
시계의 시간에 따라 알람이 트리거됩니다. 예를 들어 다음과 같은 경우 :
long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);
반면에 지금부터 30 초 후에 알람이 울 립니다 .
AlarmManager.ELAPSED_REALTIME_WAKEUP
type은에 비해 거의 사용되지 않습니다 AlarmManager.RTC_WAKEUP
.
답변
현재 승인되고 찬성 된 답변에도 불구하고 SystemClock.elapsedRealtime ()과 함께 AlarmManager.ELAPSED_REALTIME * 유형은 항상 알람 및 타이밍에 대한 RTC 시계보다 더 안정적이었습니다.
AlarmManager와 함께 ELAPSED_REALTIME_WAKEUP를 사용하면 부팅 시간부터 시작되는 단조로운 시계에 의존하고 ” CPU가 절전 모드에있을 때도 계속 틱하므로 범용 간격 타이밍의 권장 기준입니다 .” 그래서,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
+ 60*1000, pendingIntent);
PendingIntent가 1 분 (60 * 1000 밀리 초) 안에 실행됩니다.
반면에 AlarmManager.RTC_WAKEUP는 epoch 이후 표준 “월”시간 (밀리 초)입니다. 그래서,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ 60*10000, pendingIntent);
SystemClock 문서에 설명 된 대로 지금부터 60 초 후에 경보를 트리거 할 수도 있지만 안정적이지 않습니다 .
벽시계는 사용자 또는 전화 네트워크에서 설정할 수 있으므로 (setCurrentTimeMillis (long) 참조) 시간이 예기치 않게 앞뒤로 이동할 수 있습니다. 이 시계는 달력 또는 알람 시계 응용 프로그램에서와 같이 실제 날짜 및 시간과의 통신이 중요한 경우에만 사용해야합니다. 간격 또는 경과 시간 측정은 다른 시계를 사용해야합니다. System.currentTimeMillis ()를 사용하는 경우 ACTION_TIME_TICK, ACTION_TIME_CHANGED 및 ACTION_TIMEZONE_CHANGED Intent 브로드 캐스트를 수신하여 시간이 언제 변경되는지 확인하는 것이 좋습니다.
또한이 질문은 * _WAKEUP 경보 만 참조했지만 , wakeup과 non-wakeup 경보가 제공하는 내용을 이해할 수 있도록 AlarmManager 설명서 도 참조 하세요.
답변
메모입니다. 가동 시간 밀리 호출을 얻을 수 있습니다.
long uptimeMillis = SystemClock.elapsedRealtime();
따라서 지금부터 30 초 후에 알람을 실행하고 일반 시계 대신 가동 시간 시계를 사용하려면 다음을 수행 할 수 있습니다.
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
특정 날짜 / 시간 대신 경과 된 시간을 확인하려면 가동 시간을 사용하는 것이 가장 좋습니다. 사용자가 설정을 통해 시간을 변경하면 장치에서 사용자가 설정 한 현재 시간이 변경 될 수 있기 때문입니다.
답변
이 문제를 내 프로젝트에서 이런 식으로 프로그래밍했습니다. 아래 코드에서 내가 사용하고 있습니다.
AlarmManager.ELAPSED_REALTIME_WAKEUP
특정 시간에 알람을 설정합니다. 이 알람을 수신하기 위해 인 텐트 필터에서 변수 ‘intentName’이 사용됩니다. 이런 유형의 알람을 많이 발동하고 있기 때문입니다. 모든 알람을 취소 할 때. 취소 방법을 사용합니다. 하단에 주어집니다.
// 알람을 보류하고 필요할 때 취소
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);
스팬 함수는 다음과 같습니다.
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);
}
알람 해제 기능은 이쪽입니다.
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();
}
}
답변
사용할 알람을 선택할 때 몇 가지 중요한 참고 사항 🙁 이미 찬성 투표를 읽은 사람)
RTC_WAKEUP
죽음의 계곡 – 시간 변경 :
사용자가 울리지 않습니다 경보 과거 수동으로 변경 시간을 가지고 있으며, 미래는 알람이 지나치는 경우 즉시 꺼 발생할 경우 RTC
타임 스탬프. 이 알람은 실패 할 가능성이 있으므로 클라이언트 측 확인 / 중요 작업을 수행하는 데 사용
하지 마십시오 .
WAKEUP
의미 (위의 산들과)
일반적으로 -별로. , 또는 ( 잠자기 및 유휴 )에 있을 때 idle
또는 동안 장치를 깨우지 않습니다.doze
alarmManager.setExactAndAllowWhileIdle
alarmManager.setAndAllowWhileIdle