Android AlarmManager - RTC_WAKEUP बनाम ELAPSED_REALTIME_WAKEUP


87

क्या कोई मुझे AlarmManager.RTC_WAKEUPऔर के बीच का अंतर समझा सकता है AlarmManager.ELAPSED_REALTIME_WAKEUP? मैंने प्रलेखन पढ़ा है, लेकिन अभी भी वास्तव में एक के ऊपर एक का उपयोग करने के निहितार्थ को नहीं समझता।

उदाहरण कोड:

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

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

कोड की दो लाइनें कितनी अलग होंगी? कोड की उन दो पंक्तियों को एक दूसरे के सापेक्ष कब निष्पादित किया जाएगा?

तुम्हारी सहायता सराहनीय है।

जवाबों:


140

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

दूसरी ओर, यह अब से 30 सेकंड के अलार्म को चालू कर देगा ।

AlarmManager.ELAPSED_REALTIME_WAKEUPकी तुलना में प्रकार का उपयोग शायद ही कभी किया जाता है AlarmManager.RTC_WAKEUP


1
बिल्कुल यही मैने सोचा। मुझे बस कुछ पुष्टि की आवश्यकता थी। इसलिए अगर मैंने ऐसा कुछ किया है: अलार्म मैनजर ।सेट (अलार्म मैनजर.ईएलएपीएसईडी_आरएएलटी टाइम_वेकअप, सिस्टम.काउंटर टाइममिल्स () + ३० * १०००, लंबित); अजीब बातें हो सकता है (जो कि मैं क्या था जब तक मैंने देखा है कि यह काम नहीं कर रहा था की तरह मैंने सोचा।
केमिली Sévigny

2
कृपया ध्यान दें कि कोड :) के System.currentTimeMillis()बजाय होना चाहिएSystem.currentTimeMills()
HasanAboShally

17
"AlarmManager.ELAPSED_REALTIME_WAKEUP प्रकार शायद ही कभीManManager.RTC_WAKEUP की तुलना में उपयोग किया जाता है।" यह अटकलें और बुरी सलाह हैं। प्रलेखन के अनुसार: developer.android.com/training/scheduling/alarms.html "यदि आपको किसी विशेष अंतराल (उदाहरण के लिए, हर आधे घंटे) पर आग लगाने के लिए बस अपने अलार्म की आवश्यकता है, तो बीते हुए वास्तविक समय प्रकारों में से एक का उपयोग करें।" सामान्य तौर पर, यह बेहतर विकल्प है। ”
जारेड क्ल्स

1
@ mborsuk का जवाब बेहतर है और इस जवाब को सही कर रहा है: आपको बीते समय के लिए RTC का उपयोग नहीं करना चाहिए, जैसे कि thirtySecondsFromNow
मीका एफ।

2
बहुत अच्छी व्याख्या :)! मैं एक महत्वपूर्ण टिप्पणी जोड़ना चाहता हूं: एंड्रॉइड से आधिकारिक दस्तावेजों के बारे में, "AlarmManager.ELAPSED_REALTIME_WAKEUP" का उपयोग करके कुछ दिलचस्प हो सकता है जब यह एक ऐसे अनुप्रयोग की बात आती है जो एक सर्वर से HTTP अनुरोधों को निकालता है, और आप कोई भी उत्पन्न नहीं करना चाहते हैं अपने वेबसर्वर पर लोड करें। हजारों Android उपकरणों के बारे में सोचें, एक webservers पर GET का प्रदर्शन करते हुए, 10:30 PM: इस तथ्य के कारण कि डिवाइस के बूट समय पर काम करता है, "AlarmManager.ELAPSED_REALTIME_WAKEUP ये" हजारों "डिवाइस फायरिंग अनुरोध कर सकते हैं, नहीं एक ही समय में, लोड से बचने :)।
ivanleoncz

107

वर्तमान में स्वीकार किए गए और अप-वोट किए गए उत्तर के बावजूद, SystemManlock.elapsedRealtime () के साथ AlarmManager.ELAPSED_REALTIME * प्रकार हमेशा अलार्म और टाइमिंग के लिए RTC घड़ियों की तुलना में अधिक विश्वसनीय रहे हैं।

अलार्म मैनजर के साथ ELAPSED_REALTIME_WAKEUP का उपयोग बूट समय से शुरू होने वाली एक मोनोटोनिक घड़ी पर निर्भर करेगा " और सीपीयू बिजली की बचत मोड में होने पर भी टिक करना जारी रखता है, इसलिए सामान्य प्रयोजन अंतराल समय के लिए सिफारिश का आधार है "। इसलिए,

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

1 मिनट (60 * 1000 मिलीसेकंड) में आपकी लंबित आग बना देगा।

जबकि, AlarmManager.RTC_WAKEUP युग के बाद से मिलीसेकंड में मानक "दीवार" समय के लिए है। इसलिए,

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

भी अब से अलार्म 60 सेकंड गति प्रदान कर सकते हैं, लेकिन मज़बूती से नहीं, क्योंकि में बताया गया है SystemClock प्रलेखन :

दीवार घड़ी को उपयोगकर्ता या फोन नेटवर्क द्वारा सेट किया जा सकता है (देखें सेटक्रांति टाइममिल्स (लंबी)), इसलिए समय पीछे की ओर या अप्रत्याशित रूप से कूद सकता है। इस घड़ी का उपयोग केवल तब किया जाना चाहिए जब वास्तविक दुनिया की तारीखों और समय के साथ पत्राचार महत्वपूर्ण हो, जैसे कि कैलेंडर या अलार्म क्लॉक एप्लिकेशन में। अंतराल या बीता समय माप एक अलग घड़ी का उपयोग करना चाहिए। यदि आप System.currentTimeMillis () का उपयोग कर रहे हैं, तो जब समय बदलता है, तो यह जानने के लिए ACTION_TIME_TICK, ACTION_TIME_CHANGED और ACTION_TIMEZONE_CHANGED इरादे सुनने का विचार करें।

इसके अलावा, प्रश्न में केवल * _WAKEUP अलार्म का संदर्भ दिया गया है, लेकिन यह भी देखें कि आपको यह समझने के लिए कि क्या वेकअप बनाम नॉन-वेकअप अलार्म प्रदान करते हैं, इस पर AlarmManager प्रलेखन भी देखें ।


आपकी प्रतिक्रिया बहुत अच्छी है, लेकिन मेरे आवेदन में, मुझे उन अलार्मों को सेट करने की आवश्यकता है जो वास्तविक दुनिया की तारीख / समय और अब से सिर्फ 60 सेकंड में मेल खाते हैं। उस स्थिति में, RTC_WAKEUP मेरे लिए सबसे अच्छा समाधान है।
केमिली स्वेंग

8
यह ठीक है लेकिन यह प्रश्न का अधिक सटीक उत्तर है और वर्तमान में स्वीकृत उत्तर में चीजों को सही करता है।
मबोरसुक

यह जानकारी है, लेकिन ध्यान दें कि के लिए +1 elapsedRealtime()है के तहत SystemClockबजाय System। संपादित करें: ... दैनिक वोट सीमा तक पहुँच गया ...
जॉर्ज फ्यूएंटेस गोंजालेज 20

यह वहाँ के मुद्दे में सबसे अच्छे उत्तरों में से एक है। मैं 50 मीटर ऊंचे हिस्टैक (उर्फ "मेरे कोड में एक बग!") में सुई खोज रहा था, और आपके जवाब ने मुझे सीधे सुई की ओर ले गया!
AlxDroidDev

17

सिर्फ एक नोट। आप अपटाइम मिलिस कॉलिंग प्राप्त कर सकते हैं:

long uptimeMillis =  SystemClock.elapsedRealtime();

इसलिए यदि आप अभी से 30 सेकंड के अलार्म को फायर करना चाहते हैं, और आप सामान्य घड़ी के बजाय अपटाइम घड़ी का उपयोग करना चाहते हैं, तो आप कर सकते हैं:

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

जब भी आप किसी विशिष्ट तिथि / समय के बजाय कुछ बीते हुए समय की जांच करना चाहते हैं, तो अपटाइम का उपयोग करना सबसे अच्छा है। ऐसा इसलिए है क्योंकि डिवाइस में उपयोगकर्ता द्वारा निर्धारित वर्तमान समय बदल सकता है यदि उपयोगकर्ता सेटिंग्स का उपयोग करके इसे बदलता है।


3
+1 इंगित करने के लिए कि "जब भी आप बीते हुए समय की जांच करना चाहते हैं" का उपयोग करें। पूरी तरह से समझ में आता है।
सुलै

फिर से केवल तनाव के लिए: मेरी समझ यह है कि यह निश्चित रूप से अब से 30 सेकंड तक आग लगाएगा जब तक कि डिवाइस बंद होने जैसा कुछ न हो। अफसोस की बात है, मुझे लगता है कि RTC_WAKEUP का उपयोग करने के साथ मुद्दा यह है कि सिद्धांत रूप में, अब से 15 सेकंड पहले, यह संभव है कि अक्टूबर के अंत में कुछ शनिवार को 1 बजे जैसा कुछ हो जाए और सिस्टम घड़ी 1 घंटे पीछे चला जाए (यूएस में और बहुत कुछ) यूरोप, कम से कम), तो अलार्म वास्तव में 1 घंटे और 30 सेकंड तक ट्रिगर होने के बाद सेट नहीं होता है।
यानिक

2

मैंने इस समस्या को अपने प्रोजेक्ट में इस तरह से प्रोग्राम किया। नीचे दिए गए कोड में मैं उपयोग कर रहा हूं

AlarmManager.ELAPSED_REALTIME_WAKEUP

विशिष्ट समय पर अलार्म सेट करने के लिए। चर 'आशयनाम' का उपयोग इस अलार्म को रिसीव करने के इरादे में किया जाता है। क्योंकि मैं इस प्रकार के कई अलार्म फायर कर रहा हूं। जब मैं सभी अलार्म रद्द करता हूं। मैं विधि रद्द का उपयोग करें। नीचे दिया गया।

// अलार्म रखने और जरूरत पड़ने पर रद्द करने के लिए

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

1

कौन से अलार्म का उपयोग करते समय कुछ महत्वपूर्ण नोट्स : (जिनके लिए पहले से ही पढ़े गए वोट पढ़ते हैं)

RTC_WAKEUP मौत की घाटी - समय परिवर्तन:
उपयोगकर्ता अलार्म अतीत को मैन्युअल रूप से परिवर्तन समय बंद नहीं जाना होगा, और भविष्य अलार्म अतीत अगर यह तुरंत बंद होने के लिए कारण होगा, तो RTCटाइमस्टैम्प। किसी भी क्लाइंट साइड सत्यापन / महत्वपूर्ण कार्य करने के लिए इस अलार्म का उपयोग
करें क्योंकि यह विफल होने का मौका है।

WAKEUP अर्थ (Marshmallow और ऊपर)
सामान्य में - बहुत ज्यादा नहीं। उस या ( Doze & Idle ) के लिए idleया जब में doze, डिवाइस को नहीं जगाएगाalarmManager.setExactAndAllowWhileIdlealarmManager.setAndAllowWhileIdle

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.