अलार्म शेड्यूल करें

अलार्म (AlarmManager क्लास पर आधारित) की मदद से, अपने ऐप्लिकेशन के लाइफ़टाइम के बाहर समय के हिसाब से कार्रवाइयां की जा सकती हैं. उदाहरण के लिए, किसी अलार्म का इस्तेमाल करके लंबे समय तक चलने वाली कोई प्रोसेस शुरू की जा सकती है. जैसे, मौसम का पूर्वानुमान डाउनलोड करने के लिए, दिन में एक बार कोई सेवा शुरू करना.

अलार्म में ये सुविधाएं होती हैं:

  • इनकी मदद से, तय किए गए समय और/या अंतराल पर इंटेंट ट्रिगर किए जा सकते हैं.

  • इनका इस्तेमाल ब्रॉडकास्ट रिसीवर के साथ किया जा सकता है, ताकि अन्य कार्रवाइयां करने के लिए जॉब या WorkRequest शेड्यूल किए जा सकें.

  • ये आपके ऐप्लिकेशन के बाहर काम करते हैं. इसलिए, इनका इस्तेमाल इवेंट या कार्रवाइयों को ट्रिगर करने के लिए किया जा सकता है. ऐसा तब भी किया जा सकता है, जब आपका ऐप्लिकेशन न चल रहा हो और डिवाइस स्लीप मोड में हो.

  • इनसे, ऐप्लिकेशन के लिए ज़रूरी संसाधनों को कम करने में मदद मिलती है. टाइमर या लगातार चल रही सेवाओं पर निर्भर न रहकर भी, कार्रवाइयां शेड्यूल की जा सकती हैं.

अलार्म सेट करना

जब कोई ऐप्लिकेशन अलार्म का सटीक समय सेट नहीं करता, तो सिस्टम अलार्म को आने वाले समय में किसी भी समय पर डिलीवर करता है. इन अलार्म के लिए, यह गारंटी दी जाती है कि अलार्म तय समय के आस-पास बजेगा. साथ ही, बैटरी बचाने से जुड़ी पाबंदियों का भी पालन किया जाता है. जैसे, डोज़ मोड.

डेवलपर, एपीआई की इन सुविधाओं का इस्तेमाल करके, अलार्म के ट्रिगर होने का समय अपनी पसंद के मुताबिक सेट कर सकते हैं.

किसी खास समय के बाद अलार्म सेट करना

अगर आपका ऐप्लिकेशन set(), setInexactRepeating(), या setAndAllowWhileIdle() को कॉल करता है, तो अलार्म, ट्रिगर होने के लिए तय किए गए समय से पहले कभी नहीं बजेगा.

Android 12 (एपीआई लेवल 31) और इसके बाद के वर्शन में, सिस्टम अलार्म को ट्रिगर होने के समय के एक घंटे के अंदर चालू कर देता है. हालांकि, ऐसा तब तक होता है, जब तक बैटरी बचाने से जुड़ी कोई पाबंदी लागू न हो. जैसे, बैटरी सेवर या डोज़ मोड.

किसी समयावधि के दौरान अलार्म डिलीवर करना

अगर आपका ऐप्लिकेशन setWindow() को कॉल करता है, तो अलार्म, ट्रिगर होने के लिए तय किए गए समय से पहले कभी नहीं बजेगा. बैटरी बचाने से जुड़ी पाबंदियां लागू न होने पर, अलार्म को तय समयसीमा के अंदर डिलीवर किया जाता है. यह समयसीमा, अलार्म ट्रिगर होने के समय से शुरू होती है.

अगर आपका ऐप्लिकेशन, Android 12 या इसके बाद के वर्शन को टारगेट करता है, तो सिस्टम, टाइम-विंडो वाले अलार्म को कम से कम 10 मिनट तक के लिए रोक सकता है. इस वजह से, 600000 में मौजूद windowLengthMillis पैरामीटर की वैल्यू आम तौर पर 600000 पर सेट होती हैं. सिस्टम छोटी विंडो को अडजस्ट कर सकता है. ऐसा खास तौर पर तब होता है, जब अलार्म को आने वाले समय में ट्रिगर करने के लिए शेड्यूल किया गया हो.

अलार्म को तय किए गए समय पर बार-बार बजाना

अगर आपका ऐप्लिकेशन setInexactRepeating() को कॉल करता है, तो सिस्टम कई अलार्म चालू करता है:

  1. पहला अलार्म, तय की गई समयावधि के अंदर बजेगा. यह समयावधि, ट्रिगर करने के लिए दिए गए समय से शुरू होती है.
  2. इसके बाद के अलार्म, आम तौर पर तय की गई समयावधि के बाद बजते हैं. अलार्म को लगातार दो बार चालू करने के बीच का समय अलग-अलग हो सकता है.

एग्ज़ैक्ट अलार्म सेट करें

सिस्टम, आने वाले समय में तय किए गए समय पर एग्ज़ैक्ट अलार्म सेट करता है.

ज़्यादातर ऐप्लिकेशन, कई सामान्य कामों को पूरा करने के लिए, इनऐक्ज़ैक्ट अलार्म का इस्तेमाल करके टास्क और इवेंट शेड्यूल कर सकते हैं. अगर आपके ऐप्लिकेशन का मुख्य फ़ंक्शन, ठीक समय पर सेट किए गए अलार्म पर निर्भर करता है, जैसे कि अलार्म क्लॉक ऐप्लिकेशन या कैलेंडर ऐप्लिकेशन, तो एग्ज़ैक्ट अलार्म का इस्तेमाल किया जा सकता है.

इस्तेमाल के ऐसे उदाहरण जिनमें सटीक समय वाले अलार्म की ज़रूरत नहीं होती

यहां उन सामान्य वर्कफ़्लो की सूची दी गई है जिनके लिए सटीक अलार्म की ज़रूरत नहीं होती:

अपने ऐप्लिकेशन के लाइफ़टाइम के दौरान, टाइमिंग से जुड़ी कार्रवाइयां शेड्यूल करना
Handler क्लास में, समय से जुड़ी कार्रवाइयों को मैनेज करने के कई अच्छे तरीके शामिल हैं. जैसे, आपका ऐप्लिकेशन चालू होने पर हर n सेकंड में कुछ काम करना: postAtTime() और postDelayed(). ध्यान दें कि ये एपीआई, सिस्टम के अपटाइम पर निर्भर करते हैं, न कि रीयल टाइम पर.
शेड्यूल किया गया बैकग्राउंड वर्क, जैसे कि ऐप्लिकेशन को अपडेट करना और लॉग अपलोड करना
WorkManager की मदद से, समय के हिसाब से होने वाले काम को शेड्यूल किया जा सकता है. टास्क के लिए, दोहराव का इंटरवल और flexInterval (कम से कम 15 मिनट) तय किया जा सकता है, ताकि टास्क के रनटाइम को ज़्यादा बारीकी से तय किया जा सके.
उपयोगकर्ता की ओर से तय की गई ऐसी कार्रवाई जो किसी तय समय के बाद होनी चाहिए. भले ही, सिस्टम निष्क्रिय स्थिति में हो
सटीक समय वाले अलार्म का इस्तेमाल न करें. खास तौर पर, setAndAllowWhileIdle() पर कॉल करें.
उपयोगकर्ता की ओर से तय की गई ऐसी कार्रवाई जो किसी तय समय के बाद होनी चाहिए
सटीक समय वाले अलार्म का इस्तेमाल न करें. खास तौर पर, set() पर कॉल करें.
उपयोगकर्ता की ओर से तय की गई ऐसी कार्रवाई जो तय की गई समयावधि में हो सकती है
सटीक समय वाले अलार्म का इस्तेमाल न करें. खास तौर पर, setWindow() पर कॉल करें. ध्यान दें कि अगर आपका ऐप्लिकेशन Android 12 या इसके बाद के वर्शन को टारगेट करता है, तो सबसे कम अवधि वाली विंडो की लंबाई 10 मिनट होनी चाहिए.

ठीक समय पर बजने वाला अलार्म सेट करने के तरीके

आपका ऐप्लिकेशन, इनमें से किसी एक तरीके का इस्तेमाल करके एग्ज़ैक्ट अलार्म सेट कर सकता है. इन तरीकों को इस तरह से क्रम में लगाया गया है कि सूची में सबसे नीचे मौजूद तरीके, समय के हिसाब से ज़्यादा ज़रूरी टास्क पूरे करते हैं. हालांकि, इसके लिए सिस्टम के ज़्यादा संसाधनों की ज़रूरत होती है.

setExact()

बैटरी बचाने के अन्य तरीकों का इस्तेमाल न किए जाने पर, अलार्म को आने वाले समय में सटीक समय पर चालू करें.

इस तरीके का इस्तेमाल करके सटीक अलार्म सेट करें. हालांकि, अगर आपके ऐप्लिकेशन का काम उपयोगकर्ता के लिए समय के हिसाब से ज़रूरी है, तो इस तरीके का इस्तेमाल न करें.

setExactAndAllowWhileIdle()

बैटरी बचाने की सुविधा चालू होने पर भी, अलार्म को आने वाले समय में सटीक समय पर चालू किया जा सकता है.

setAlarmClock()

आने वाले समय में किसी तय समय पर अलार्म सेट करना. ये सूचनाएं उपयोगकर्ताओं को साफ़ तौर पर दिखती हैं. इसलिए, सिस्टम इन्हें भेजने के समय में कभी बदलाव नहीं करता. सिस्टम इन अलार्म को सबसे ज़रूरी अलार्म के तौर पर पहचानता है. साथ ही, अलार्म देने के लिए, अगर ज़रूरी हो, तो कम बैटरी मोड बंद कर देता है.

सिस्टम के संसाधनों का इस्तेमाल

जब सिस्टम, आपके ऐप्लिकेशन की ओर से सेट किए गए सटीक अलार्म ट्रिगर करता है, तो डिवाइस की बैटरी लाइफ़ जैसे कई संसाधनों का इस्तेमाल होता है. ऐसा खास तौर पर तब होता है, जब डिवाइस पावर-सेविंग मोड में हो. इसके अलावा, सिस्टम इन अनुरोधों को आसानी से बैच नहीं कर सकता, ताकि संसाधनों का बेहतर तरीके से इस्तेमाल किया जा सके.

हमारा सुझाव है कि जब भी हो सके, अलार्म को सटीक समय पर न बजने के लिए सेट करें. ज़्यादा समय तक काम करने के लिए, अलार्म की BroadcastReceiver से WorkManager या JobScheduler का इस्तेमाल करके, अलार्म शेड्यूल करें. डिवाइस के डॉज़ मोड में होने पर काम करने के लिए, setAndAllowWhileIdle() का इस्तेमाल करके अनुमानित समय वाला अलार्म बनाएं. इसके बाद, अलार्म से कोई काम शुरू करें.

एग्ज़ैक्ट अलार्म की सही अनुमति का एलान करना

अगर आपका ऐप्लिकेशन, Android 12 या उसके बाद के वर्शन को टारगेट करता है, तो आपको "अलार्म और रिमाइंडर" के लिए खास ऐप्लिकेशन ऐक्सेस की अनुमति लेनी होगी. इसके लिए, अपने ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल में, SCHEDULE_EXACT_ALARM अनुमति का एलान करें. इसके लिए, यहां दिया गया कोड स्निपेट देखें:

<manifest ...>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

अगर आपका ऐप्लिकेशन, Android 13 (एपीआई लेवल 33) या उसके बाद के वर्शन को टारगेट करता है, तो आपके पास SCHEDULE_EXACT_ALARM या USE_EXACT_ALARM अनुमति में से किसी एक को चुनने का विकल्प होता है.

<manifest ...>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

SCHEDULE_EXACT_ALARM और USE_EXACT_ALARM अनुमतियां, दोनों एक जैसी सुविधाओं के बारे में बताती हैं. हालांकि, इन्हें अलग-अलग तरीके से दिया जाता है और ये अलग-अलग इस्तेमाल के उदाहरणों के साथ काम करती हैं. आपके ऐप्लिकेशन को एग्ज़ैक्ट अलार्म का इस्तेमाल करना चाहिए. साथ ही, SCHEDULE_EXACT_ALARM या USE_EXACT_ALARM अनुमति का एलान सिर्फ़ तब करना चाहिए, जब आपके ऐप्लिकेशन में उपयोगकर्ता को उपलब्ध कराए जाने वाले किसी फ़ंक्शन के लिए, बिलकुल ठीक समय पर की जाने वाली कार्रवाइयों की ज़रूरत हो.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • उपयोगकर्ता ने अनुमति दी है
  • इस्तेमाल के ज़्यादा उदाहरण
  • ऐप्लिकेशन को यह पुष्टि करनी चाहिए कि अनुमति वापस नहीं ली गई है

Android 13 (एपीआई लेवल 33) और उसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के नए इंस्टॉलेशन के लिए, SCHEDULE_EXACT_ALARM अनुमति पहले से नहीं दी जाती है. अगर कोई उपयोगकर्ता, बैकअप और वापस लाने की सुविधा का इस्तेमाल करके, Android 14 पर काम करने वाले डिवाइस में ऐप्लिकेशन का डेटा ट्रांसफ़र करता है, तो नए डिवाइस पर SCHEDULE_EXACT_ALARM की अनुमति नहीं दी जाएगी. हालांकि, अगर किसी मौजूदा ऐप्लिकेशन के पास पहले से यह अनुमति है, तो डिवाइस को Android 14 पर अपग्रेड करने पर, उसे यह अनुमति पहले से मिल जाएगी.

ध्यान दें: अगर OnAlarmListener ऑब्जेक्ट का इस्तेमाल करके सटीक अलार्म सेट किया जाता है, जैसे कि setExact एपीआई के साथ, तो SCHEDULE_EXACT_ALARM अनुमति की ज़रूरत नहीं होती.

SCHEDULE_EXACT_ALARM अनुमति का इस्तेमाल करना

USE_EXACT_ALARM के उलट, SCHEDULE_EXACT_ALARM अनुमति उपयोगकर्ता को देनी होती है. उपयोगकर्ता और सिस्टम, दोनों SCHEDULE_EXACT_ALARM की अनुमति रद्द कर सकते हैं.

यह देखने के लिए कि आपके ऐप्लिकेशन को अनुमति मिली है या नहीं, एग्ज़ैक्ट अलार्म सेट करने से पहले, canScheduleExactAlarms() को कॉल करें. जब आपके ऐप्लिकेशन के लिए SCHEDULE_EXACT_ALARM अनुमति रद्द कर दी जाती है, तो आपका ऐप्लिकेशन काम करना बंद कर देता है. साथ ही, आने वाले समय के लिए सेट किए गए सभी एग्ज़ैक्ट अलार्म रद्द हो जाते हैं. इसका यह भी मतलब है कि canScheduleExactAlarms() से मिली वैल्यू, आपके ऐप्लिकेशन के पूरे लाइफ़साइकल के लिए मान्य रहती है.

जब आपके ऐप्लिकेशन को SCHEDULE_EXACT_ALARMS की अनुमति मिल जाती है, तब सिस्टम उसे ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED ब्रॉडकास्ट भेजता है. आपके ऐप्लिकेशन में ब्रॉडकास्ट रिसीवर लागू किया गया हो. यह रिसीवर ये काम करता हो:

  1. इससे पुष्टि होती है कि आपके ऐप्लिकेशन के पास अब भी खास ऐक्सेस है. ऐसा करने के लिए, canScheduleExactAlarms() को कॉल करें. यह जांच आपके ऐप्लिकेशन को ऐसे मामलों से बचाती है जहां उपयोगकर्ता आपके ऐप्लिकेशन को अनुमति देता है और फिर तुरंत उसे रद्द कर देता है.
  2. यह फ़ंक्शन, आपके ऐप्लिकेशन की मौजूदा स्थिति के आधार पर, उन सभी एग्ज़ैक्ट अलार्म को फिर से शेड्यूल करता है जिनकी आपके ऐप्लिकेशन को ज़रूरत होती है. यह लॉजिक, उस लॉजिक जैसा होना चाहिए जिसका इस्तेमाल आपका ऐप्लिकेशन, ACTION_BOOT_COMPLETED ब्रॉडकास्ट मिलने पर करता है.

उपयोगकर्ताओं से SCHEDULE_EXACT_ALARM की अनुमति मांगना

इस विकल्प का नाम 'अलार्म और रिमाइंडर सेट करने की अनुमति दें' है
पहली इमेज. सिस्टम सेटिंग में मौजूद, "अलार्म और रिमाइंडर" के लिए ऐप्लिकेशन को खास तौर पर ऐक्सेस करने की अनुमति देने वाला पेज. इस पेज पर जाकर, उपयोगकर्ता आपके ऐप्लिकेशन को सटीक अलार्म सेट करने की अनुमति दे सकते हैं.

अगर ज़रूरी हो, तो उपयोगकर्ताओं को सिस्टम सेटिंग में मौजूद अलार्म और रिमाइंडर स्क्रीन पर भेजा जा सकता है. जैसा कि पहली इमेज में दिखाया गया है. इसके लिए, यह तरीका अपनाएं:

  1. अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में, उपयोगकर्ता को बताएं कि आपके ऐप्लिकेशन को सटीक अलार्म शेड्यूल करने की ज़रूरत क्यों है.
  2. ऐसे इंटेंट को चालू करें जिसमें ACTION_REQUEST_SCHEDULE_EXACT_ALARM इंटेंट ऐक्शन शामिल हो.

बार-बार बजने वाला अलार्म सेट करना

दोहराए जाने वाले अलार्म की मदद से, सिस्टम आपके ऐप्लिकेशन को बार-बार सूचना भेज सकता है.

खराब तरीके से डिज़ाइन किए गए अलार्म की वजह से, तेज़ी से बैटरी खर्च हो सकती है और सर्वर पर काफ़ी लोड पड़ सकता है. इस वजह से, Android 4.4 (एपीआई लेवल 19) और इसके बाद के वर्शन पर, बार-बार बजने वाली सभी अलार्म अनुमानित समय पर बजने वाली अलार्म होती हैं.

बार-बार बजने वाले अलार्म की ये विशेषताएं होती हैं:

  • अलार्म का टाइप. ज़्यादा जानकारी के लिए, अलार्म का टाइप चुनना लेख पढ़ें.

  • ट्रिगर होने का समय. अगर ट्रिगर करने का समय पहले का है, तो अलार्म तुरंत ट्रिगर हो जाएगा.

  • अलार्म का इंटरवल. उदाहरण के लिए, दिन में एक बार, हर घंटे या हर पांच मिनट में.

  • यह एक ऐसा पेंडिंग इंटेंट है जो अलार्म ट्रिगर होने पर चालू होता है. एक ही पेंडिंग इंटेंट का इस्तेमाल करके दूसरा अलार्म सेट करने पर, यह पहले अलार्म की जगह ले लेता है.

किसी PendingIntent() को रद्द करने के लिए, FLAG_NO_CREATE को PendingIntent.getService() पर पास करें, ताकि इंटेंट का इंस्टेंस मिल सके. इसके बाद, उस इंटेंट को AlarmManager.cancel() पर पास करें

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

Java

AlarmManager alarmManager =
    (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent);
}

अलार्म का टाइप चुनें

बार-बार बजने वाले अलार्म का इस्तेमाल करते समय, सबसे पहले यह तय करना होता है कि अलार्म किस तरह का होना चाहिए.

अलार्म के लिए, आम तौर पर दो तरह की घड़ियों का इस्तेमाल किया जाता है: "बीता हुआ रीयल टाइम" और "रीयल टाइम क्लॉक" (आरटीसी). इलैप्स्ड रीयल टाइम, "सिस्टम बूट होने के बाद से बीता समय" को रेफ़रंस के तौर पर इस्तेमाल करता है. वहीं, रीयल टाइम क्लॉक, यूटीसी (वॉल क्लॉक) समय का इस्तेमाल करता है. इसका मतलब है कि समय बीतने के आधार पर अलार्म सेट करने के लिए, 'बीता हुआ रीयल टाइम' सबसे सही है. उदाहरण के लिए, हर 30 सेकंड में बजने वाला अलार्म. ऐसा इसलिए, क्योंकि यह टाइम ज़ोन या स्थान-भाषा से प्रभावित नहीं होता. रीयल टाइम क्लॉक टाइप, उन अलार्म के लिए बेहतर है जो मौजूदा स्थान-भाषा पर निर्भर करते हैं.

दोनों तरह के लॉक में "वेकअप" वर्शन होता है. इससे डिवाइस की स्क्रीन बंद होने पर, सीपीयू को चालू किया जा सकता है. इससे यह पक्का होता है कि अलार्म तय समय पर बजेगा. अगर आपके ऐप्लिकेशन में समय के हिसाब से काम करने वाली सुविधा है, तो यह तरीका फ़ायदेमंद है. उदाहरण के लिए, अगर किसी खास ऑपरेशन को पूरा करने के लिए, सीमित समय दिया गया है. अगर आपने अलार्म के टाइप के लिए, वेकअप वर्शन का इस्तेमाल नहीं किया है, तो दोहराए जाने वाले सभी अलार्म तब बजेंगे, जब आपका डिवाइस अगली बार चालू होगा.

अगर आपको अलार्म को किसी खास इंटरवल पर सेट करना है (उदाहरण के लिए, हर आधे घंटे में), तो बीते हुए असल समय के टाइप में से किसी एक का इस्तेमाल करें. आम तौर पर, यह बेहतर विकल्प है.

अगर आपको अलार्म को दिन के किसी खास समय पर ट्रिगर करना है, तो घड़ी पर आधारित किसी एक तरह के रीयल टाइम क्लॉक को चुनें. हालांकि, ध्यान दें कि इस तरीके से कुछ समस्याएं हो सकती हैं. ऐसा हो सकता है कि ऐप्लिकेशन, अन्य भाषाओं में ठीक से अनुवाद न कर पाए. साथ ही, अगर उपयोगकर्ता डिवाइस के समय की सेटिंग बदलता है, तो इससे आपके ऐप्लिकेशन में अनचाही समस्याएं हो सकती हैं. ऊपर बताए गए तरीके के मुताबिक, रीयल टाइम क्लॉक अलार्म टाइप का इस्तेमाल करने से भी, ऐप्लिकेशन को बेहतर तरीके से स्केल नहीं किया जा सकता. हमारा सुझाव है कि अगर हो सके, तो "बीता हुआ असल समय" अलार्म का इस्तेमाल करें.

यहां टाइप की सूची दी गई है:

  • ELAPSED_REALTIME: यह डिवाइस के बूट होने के बाद से, तय किए गए समय के आधार पर पेंडिंग इंटेंट को ट्रिगर करता है. हालांकि, इससे डिवाइस की स्क्रीन चालू नहीं होती. बीता हुआ समय, डिवाइस के स्लीप मोड में रहने के दौरान का समय भी शामिल करता है.

  • ELAPSED_REALTIME_WAKEUP: यह डिवाइस को चालू करता है और डिवाइस बूट होने के बाद, तय समय बीत जाने पर, लंबित इंटेंट को ट्रिगर करता है.

  • RTC: यह तय किए गए समय पर पेंडिंग इंटेंट को ट्रिगर करता है, लेकिन डिवाइस को चालू नहीं करता.

  • RTC_WAKEUP: यह डिवाइस को चालू करता है, ताकि तय किए गए समय पर लंबित इंटेंट को ट्रिगर किया जा सके.

बीते हुए समय के हिसाब से सेट किए गए अलार्म के उदाहरण

ELAPSED_REALTIME_WAKEUP का इस्तेमाल करने के कुछ उदाहरण यहां दिए गए हैं

डिवाइस को चालू करें, ताकि 30 मिनट बाद अलार्म बज सके. इसके बाद, हर 30 मिनट में अलार्म बजता रहेगा:

Kotlin

// Hopefully your alarm will have a lower frequency than this!
alarmMgr?.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR,
        alarmIntent
)

Java

// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

डिवाइस को चालू करें, ताकि एक मिनट बाद एक बार बजने वाला (दोबारा नहीं बजने वाला) अलार्म सेट किया जा सके:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

रीयल टाइम क्लॉक अलार्म के उदाहरण

यहां RTC_WAKEUP का इस्तेमाल करने के कुछ उदाहरण दिए गए हैं.

डिवाइस को चालू करो, ताकि अलार्म दोपहर 2 बजे बजे और हर दिन उसी समय बजे:

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 14)
}

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

Java

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

डिवाइस को सुबह ठीक 8:30 बजे अलार्म बजाने के लिए चालू करो. इसके बाद, हर 20 मिनट में अलार्म बजाओ:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

तय करें कि आपको अलार्म कितने सटीक समय पर चाहिए

जैसा कि पहले बताया गया है, अलार्म का टाइप चुनना, अलार्म बनाने का पहला चरण होता है. इसके अलावा, यह भी तय करना होता है कि आपको अलार्म कितने सटीक समय पर चाहिए. ज़्यादातर ऐप्लिकेशन के लिए, setInexactRepeating() सही विकल्प है. इस तरीके का इस्तेमाल करने पर, Android कई बार दोहराए जाने वाले अलार्म को सिंक्रनाइज़ करता है और उन्हें एक ही समय पर ट्रिगर करता है. इससे बैटरी की खपत कम होती है.

अगर हो सके, तो सटीक समय वाले अलार्म का इस्तेमाल न करें. हालांकि, अगर किसी ऐप्लिकेशन के लिए समय से जुड़ी ज़रूरी शर्तें पूरी करना ज़रूरी है, तो setRepeating() को कॉल करके, एग्ज़ैक्ट अलार्म सेट किया जा सकता है.

setInexactRepeating() की मदद से, अपनी पसंद के मुताबिक इंटरवल सेट नहीं किया जा सकता. हालांकि, setRepeating() की मदद से ऐसा किया जा सकता है. आपको इंटरवल के किसी एक कॉन्स्टेंट का इस्तेमाल करना होगा. जैसे, INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY वगैरह. पूरी सूची देखने के लिए, AlarmManager पर जाएं.

अलार्म रद्द करना

अपने ऐप्लिकेशन के हिसाब से, अलार्म रद्द करने की सुविधा शामिल की जा सकती है. अलार्म रद्द करने के लिए, अलार्म मैनेजर पर cancel() को कॉल करें. साथ ही, PendingIntent को पास करें, जिसे अब आपको ट्रिगर नहीं करना है. उदाहरण के लिए:

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

Java

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

डिवाइस के रीस्टार्ट होने पर अलार्म शुरू करना

डिवाइस बंद होने पर, डिफ़ॉल्ट रूप से सभी अलार्म बंद हो जाते हैं. ऐसा होने से रोकने के लिए, अपने ऐप्लिकेशन को इस तरह से डिज़ाइन किया जा सकता है कि अगर उपयोगकर्ता डिवाइस को रीबूट करता है, तो बार-बार बजने वाला अलार्म अपने-आप रीस्टार्ट हो जाए. इससे यह पक्का होता है कि AlarmManager अपना काम जारी रखेगा. इसके लिए, उपयोगकर्ता को अलार्म को मैन्युअल तरीके से रीस्टार्ट करने की ज़रूरत नहीं होगी.

इसका तरीका यहां बताया गया है:

  1. अपने ऐप्लिकेशन के मेनिफ़ेस्ट में, RECEIVE_BOOT_COMPLETED अनुमति सेट करें. इससे आपका ऐप्लिकेशन, ACTION_BOOT_COMPLETED को पाने की अनुमति देता है. यह ब्रॉडकास्ट, सिस्टम के बूट होने के बाद किया जाता है. यह सिर्फ़ तब काम करता है, जब उपयोगकर्ता ने ऐप्लिकेशन को कम से कम एक बार लॉन्च किया हो:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. ब्रॉडकास्ट पाने के लिए, BroadcastReceiver लागू करें:

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }

    Java

    public class SampleBootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
  3. अपने ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल में रिसीवर जोड़ें. इसके लिए, इंटेंट फ़िल्टर का इस्तेमाल करें. यह फ़िल्टर, ACTION_BOOT_COMPLETED कार्रवाई के आधार पर फ़िल्टर करता है:

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    ध्यान दें कि मेनिफ़ेस्ट में, बूट रिसीवर को android:enabled="false" पर सेट किया गया है. इसका मतलब है कि जब तक ऐप्लिकेशन इसे साफ़ तौर पर चालू नहीं करता, तब तक रिसीवर को कॉल नहीं किया जाएगा. इससे बूट रिसीवर को बेवजह कॉल करने से रोका जा सकता है. उपयोगकर्ता के लिए, रिसीवर को इस तरह चालू किया जा सकता है. उदाहरण के लिए, अगर उपयोगकर्ता कोई अलार्म सेट करता है, तो:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);

    इस तरह से रिसीवर को चालू करने के बाद, यह चालू ही रहेगा. भले ही, उपयोगकर्ता डिवाइस को रीबूट कर दे. दूसरे शब्दों में, प्रोग्राम के हिसाब से रिसीवर को चालू करने पर, मेनिफ़ेस्ट सेटिंग बदल जाती है. ऐसा डिवाइस को फिर से चालू करने पर भी होता है. जब तक आपका ऐप्लिकेशन इसे बंद नहीं करता, तब तक रिसीवर चालू रहेगा. किसी रिसीवर को बंद किया जा सकता है. उदाहरण के लिए, अगर उपयोगकर्ता अलार्म बंद कर देता है, तो उसे इस तरह बंद किया जा सकता है:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

डिवाइस के डॉज़ मोड में होने पर भी अलार्म सेट करने की सुविधा

Android 6.0 (एपीआई लेवल 23) पर चलने वाले डिवाइसों में, डोज़ मोड काम करता है. इससे डिवाइस की बैटरी लाइफ़ बढ़ाने में मदद मिलती है. डिवाइस के डोज़ मोड में होने पर, अलार्म नहीं बजते हैं. शेड्यूल किए गए सभी अलार्म, डिवाइस के डोज़ मोड से बाहर आने तक के लिए टाल दिए जाते हैं. अगर आपको डिवाइस के इस्तेमाल में न होने पर भी काम करना है, तो आपके पास कई विकल्प हैं:

  • एग्ज़ैक्ट अलार्म सेट करें.

  • WorkManager API का इस्तेमाल करें. इसे बैकग्राउंड में काम करने के लिए बनाया गया है. आपके पास यह बताने का विकल्प होता है कि सिस्टम को आपके काम को प्राथमिकता देनी चाहिए, ताकि काम जल्द से जल्द पूरा हो सके. ज़्यादा जानकारी के लिए, WorkManager के साथ टास्क शेड्यूल करना लेख पढ़ें

सबसे सही तरीके

बार-बार बजने वाली अलार्म को डिज़ाइन करते समय, आपके हर फ़ैसले का असर इस बात पर पड़ सकता है कि आपका ऐप्लिकेशन सिस्टम के संसाधनों का इस्तेमाल कैसे करता है. उदाहरण के लिए, मान लें कि कोई लोकप्रिय ऐप्लिकेशन है, जो किसी सर्वर के साथ सिंक होता है. अगर सिंक करने की प्रोसेस, घड़ी के समय पर आधारित है और ऐप्लिकेशन का हर इंस्टेंस रात 11:00 बजे सिंक होता है, तो सर्वर पर लोड की वजह से, इंतज़ार का समय बढ़ सकता है या "सेवा में रुकावट" की समस्या भी हो सकती है. अलार्म इस्तेमाल करने के लिए, इन सबसे सही तरीकों को अपनाएं:

  • बार-बार बजने वाले अलार्म की वजह से ट्रिगर होने वाले किसी भी नेटवर्क अनुरोध में रैंडमनेस (जिटर) जोड़ें:

    • अलार्म ट्रिगर होने पर, कोई भी स्थानीय काम करना. "लोकल वर्क" का मतलब ऐसे किसी भी काम से है जिसके लिए सर्वर से डेटा की ज़रूरत नहीं होती या सर्वर से कोई डेटा नहीं मिलता.

    • साथ ही, उस अलार्म को शेड्यूल करें जिसमें नेटवर्क अनुरोध शामिल हैं. यह अलार्म, किसी भी समय ट्रिगर हो सकता है.

  • अलार्म की फ़्रीक्वेंसी को कम से कम रखें.

  • डिवाइस को बेवजह चालू न करें. यह व्यवहार, अलार्म के टाइप के हिसाब से तय होता है. इसके बारे में अलार्म का टाइप चुनें में बताया गया है.

  • अलार्म के ट्रिगर होने का समय, ज़रूरत से ज़्यादा सटीक न बनाएं.

    setRepeating() के बजाय, setInexactRepeating() का इस्तेमाल करें. setInexactRepeating() का इस्तेमाल करने पर, Android कई ऐप्लिकेशन से बार-बार बजने वाले अलार्म सिंक करता है और उन्हें एक ही समय पर ट्रिगर करता है. इससे सिस्टम को डिवाइस को कम बार चालू करना पड़ता है. इसलिए, बैटरी की खपत कम होती है. Android 4.4 (एपीआई लेवल 19) से, बार-बार बजने वाली सभी अलार्म इनऐक्ज़ैक्ट अलार्म हैं. ध्यान दें कि setRepeating() की तुलना में setInexactRepeating() बेहतर है. हालांकि, अगर किसी ऐप्लिकेशन के सभी इंस्टेंस एक ही समय पर सर्वर से कनेक्ट होते हैं, तो सर्वर पर अब भी ज़्यादा लोड पड़ सकता है. इसलिए, नेटवर्क अनुरोधों के लिए, अपने अलार्म में कुछ रैंडमनेस जोड़ें. इसके बारे में पहले बताया जा चुका है.

  • अगर हो सके, तो अलार्म को घड़ी के समय के हिसाब से सेट न करें.

    दोहराए जाने वाले ऐसे अलार्म ठीक से काम नहीं करते हैं जिन्हें किसी खास समय पर ट्रिगर किया जाता है. अगर हो सके, तो ELAPSED_REALTIME का इस्तेमाल करें. अलग-अलग तरह के अलार्म के बारे में ज़्यादा जानकारी यहां दी गई है.