web-dev-qa-db-ja.com

Android AlarmManager-RTC_WAKEUP vs ELAPSED_REALTIME_WAKEUP

誰かがAlarmManager.RTC_WAKEUPAlarmManager.ELAPSED_REALTIME_WAKEUPの違いを説明できますか?私はドキュメントを読みましたが、それでも他のものを使用することの意味を本当に理解していません。

サンプルコード:

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

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

2行のコードの実行はどの程度異なりますか?これらの2行のコードはいつ相互に実行されますか?

私はあなたの助けに感謝します。

83

AlarmManager.ELAPSED_REALTIME_WAKEUPタイプは、起動時からアラームをトリガーするために使用されます。

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

一方、これはアラームをトリガーします秒後

AlarmManager.ELAPSED_REALTIME_WAKEUPタイプと比較すると、AlarmManager.RTC_WAKEUPタイプはほとんど使用されません。

129
Rejinderi

現在受け入れられて投票されている答えにもかかわらず、AlarmManager.ELAPSED_REALTIME *タイプとSystemClock.elapsedRealtime()は、アラームおよびタイミング用のRTCクロックよりも常に信頼性が高くなっています。

AlarmManagerでELAPSED_REALTIME_WAKEUPを使用すると、ブート時間「から始まる単調なクロックに依存し、CPUが省電力モードになっている場合でもティックし続けるため、一般的なインターバルタイミングの推奨基準です」。そう、

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

pendingIntentが1分(60 * 1000ミリ秒)で起動します。

一方、AlarmManager.RTC_WAKEUPは、エポック以降のミリ秒単位の標準的な「壁」時間用です。そう、

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

SystemClock documentation に記載されているように、今から60秒後にアラームをトリガーすることもできますが、確実ではありません。

ウォールクロックは、ユーザーまたは電話ネットワーク(setCurrentTimeMillis(long)を参照)によって設定できるため、時間が前後にジャンプすることがあります。この時計は、カレンダーや目覚まし時計のアプリケーションなど、実際の日付と時刻との対応が重要な場合にのみ使用してください。間隔または経過時間の測定では、異なるクロックを使用する必要があります。 System.currentTimeMillis()を使用している場合は、ACTION_TIME_TICK、ACTION_TIME_CHANGED、およびACTION_TIMEZONE_CHANGED Intentブロードキャストをリッスンして、時間の変更を確認することを検討してください。

また、質問は* _WAKEUPアラームのみを参照していましたが、 AlarmManager のドキュメントも参照して、ウェイクアップアラームと非ウェイクアップアラームが提供するものを理解してください。

104
mborsuk

ちょっとだけ。 uptime millis呼び出しを取得できます。

long uptimeMillis =  SystemClock.elapsedRealtime();

したがって、30秒後にアラームを起動し、通常のクロックの代わりに稼働時間クロックを使用する場合は、次の操作を実行できます。

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

特定の日付/時間ではなく、経過時間を確認する場合は、常に稼働時間を使用することをお勧めします。これは、ユーザーが設定を使用して変更すると、デバイスでユーザーが設定した現在の時刻が変更される可能性があるためです。

17
Ena

私はこの問題を自分のプロジェクトでこのようにプログラムしました。以下のコードで私は使用しています

AlarmManager.ELAPSED_REALTIME_WAKEUP

特定の時間にアラームを設定します。変数 'intentName'は、このアラームを受信するためにintentFilterで使用されます。私はこのタイプの多くのアラームを発しているからです。すべてのアラームをキャンセルしたとき。メソッドcancelを使用します。下にある。

//アラームを保持し、必要なときにキャンセルする

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

使用するアラームを選択する :(すでに投票された投票を読んだ人)の場合の重要な注意事項

TheRTC_WAKEUP死の谷-時間の変化:
ユーザーが過去に手動で時間を変更した場合、アラームはオフにならず、futureはRTCタイムスタンプを超えるとすぐにアラームをオフにします。
Do not失敗する可能性があるため、このアラームを使用してクライアント側の検証/重要なジョブを実行しません。

WAKEUP意味(マシュマロ以上)
一般的に-それほどではありません。 idleのとき、またはdozeにいる間、そのalarmManager.setExactAndAllowWhileIdle または alarmManager.setAndAllowWhileIdle居眠り&アイドル

0
Andro Secy