[android] Android AlarmManager-RTC_WAKEUP 대 ELAPSED_REALTIME_WAKEUP

누군가가 나에게 사이의 차이 설명 할 수 AlarmManager.RTC_WAKEUPAlarmManager.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_WAKEUPtype은에 비해 거의 사용되지 않습니다 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또는 동안 장치를 깨우지 않습니다.dozealarmManager.setExactAndAllowWhileIdlealarmManager.setAndAllowWhileIdle


답변