अलार्म मैनजर पहले से अलार्म सेट है या नहीं, इसकी जांच कैसे करें?


231

जब मेरा ऐप शुरू होता है, तो मैं चाहता हूं कि यह जांचा जाए कि क्या एक विशेष अलार्म (अलार्म मैनजर के माध्यम से पंजीकृत) पहले से ही सेट है और चल रहा है। Google के परिणाम यह दर्शाते हैं कि ऐसा करने का कोई तरीका नहीं है। क्या यह अभी भी सही है? नए अलार्म बनाने के लिए किसी भी कार्रवाई से पहले उपयोगकर्ता को सलाह देने के लिए मुझे यह जांच करने की आवश्यकता है।


4
कृपया उस उत्तर को मान्य करें जो आपके मुद्दे को हल करता है या अपना स्वयं का समाधान पोस्ट करता है।
अनीस

जवाबों:


322

पोस्ट किए गए टिप्पणी रॉन के बाद, यहां विस्तृत समाधान है। मान लीजिए कि आपने इस तरह के एक लंबित इरादे के साथ एक दोहराए जाने वाले अलार्म को पंजीकृत किया है:

Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, 
                                      intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1);

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);

जिस तरह से आप यह देखने के लिए जाँच करेंगे कि क्या यह सक्रिय है:

boolean alarmUp = (PendingIntent.getBroadcast(context, 0, 
        new Intent("com.my.package.MY_UNIQUE_ACTION"), 
        PendingIntent.FLAG_NO_CREATE) != null);

if (alarmUp)
{
    Log.d("myTag", "Alarm is already active");
}

यहाँ कुंजी वह है FLAG_NO_CREATEजो जावदोक में वर्णित है: if the described PendingIntent **does not** already exists, then simply return null(एक नया बनाने के बजाय)


9
यह सिर्फ एक एक्शन स्ट्रिंग के साथ इरादे का उपयोग करना है? मैंने एक वर्ग, नई आशय (संदर्भ, MyClass.class) को निर्दिष्ट करने की कोशिश की, लेकिन यह काम नहीं करता है। अलार्म बजने पर भी यह हमेशा अशक्त रहता है।
toc777

5
toc777, नहीं, इसे एक स्ट्रिंग होने की आवश्यकता नहीं है, जो आपके घोषणापत्र में एक घोषित कार्रवाई से मेल खाती है। xml
क्रिस नाइट

4
क्रिस, यह एक और मुद्दा था जो मेरी समस्या का कारण बन रहा था। जो आशय मैंने ऊपर बताया है वह वास्तव में काम करता है :)
toc777

41
ध्यान दें कि आप दोनों फोन करने की आवश्यकता होगी alarmManager.cancel(pendingIntent)और pendingIntent.cancel()वापसी गलत पर इस समाधान के लिए आदेश में।
केविन कूपर

26
यह मामला स्पष्ट नहीं है, इस उत्तर में कोड सत्यापित नहीं करता है कि लंबित आशय अलार्म मैनेजर के साथ पंजीकृत किया गया है। कोड बस सत्यापित करता है कि PendingIntent को एक समान लक्ष्य इरादे के साथ getBroadcast के माध्यम से बनाया गया था। आप GetBroadcast सब के बाद, लेकिन सभी कैलेंडर और अलार्म प्रबंधक सामान से पहले अलार्मअप कोड चलाकर इसे साबित कर सकते हैं। यह सच हो जाएगा। यह तथ्य बताता है कि आपको झूठे को वापस जाने के लिए मूल्य प्राप्त करने के लिए PendingIntent.cancel क्यों करना होगा। सख्ती से, यह सवाल का जवाब नहीं है।
bigh_29

114

जिन लोगों को इसकी आवश्यकता हो सकती है, उनके लिए यहां एक उत्तर है।

उपयोग adb shell dumpsys alarm

आप जान सकते हैं कि अलार्म सेट कर दिया गया है और वे कब अलार्म और अंतराल पर जा रहे हैं। साथ ही कितनी बार इस अलार्म को लगाया गया है।


36
वास्तव में ओपी के लिए एक प्रोग्रामेटिक उत्तर नहीं है, लेकिन एक शांत टिप है। जानकर बहुत अच्छा लगा।
जस्टसमूय

2
अलार्म की आम तौर पर लंबी सूची को फ़िल्टर करने के लिए एक grep जोड़ें: adb shell dumpsys alarm | grep <e.g. package name of your app>नए विंडोज सिस्टम पर काम करता है (मैं Win10 का उपयोग करता हूं)
muetzenflo

3
grep मोबाइल डिवाइस पर निष्पादित होता है, न कि आपके पीसी पर। तो अगर grep काम करता है तो Android OS पर निर्भर करता है। पुराने फोन grep के साथ नहीं आते हैं।
हेनिंग

53

रिसीवर के साथ काम करने का उदाहरण (शीर्ष जवाब सिर्फ कार्रवाई के साथ था)।

//starting
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), MyReceiver.class);
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom string action name
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap

//and stopping
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up
alarmManager.cancel(pendingIntent);//important
pendingIntent.cancel();//important

//checking if alarm is working with pendingIntent
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working...");

यह उल्लेख के लायक है:

यदि बाद में एप्लिकेशन बनाने की प्रक्रिया (प्रक्रिया) एक ही तरह के PendingIntent (एक ही ऑपरेशन , एक ही Intent - क्रिया, डेटा, श्रेणियां, घटक, झंडे ) को पुनः प्राप्त करती है, तो यह एक PendingIntent को उसी टोकन का प्रतिनिधित्व करता है, यदि वह अभी भी मान्य है, और इस प्रकार इसे रद्द करने () को हटाने के लिए कॉल कर सकते हैं।

संक्षेप में, आपके PendingIntent में इस पर नियंत्रण रखने के लिए समान विशेषताएं (संचालन और इरादे की संरचना) होनी चाहिए।


1
मुझे यकीन नहीं है कि यह पर्याप्त है। उस स्थिति में जहां एक PendingIntent को AlarmManager के साथ पंजीकृत किया गया है और फिर दोनों रद्द तरीकों से रोक दिया गया है, ऊपर'Working 'अभी भी सही होगा। लगता है कि PendingIntent को AlarmManager से हटाया नहीं गया है, और यह एक उदाहरण देता रहेगा। हम कैसे प्रभावी रूप से जानते हैं कि अलार्म कब चालू / बंद किया गया है?
johnDisplayClass

यह वास्तव में पूरी तरह से काम किया। ध्यान देने योग्य बातें: setAction () और requestCode () को आपके डिवाइस से एप्लिकेशन को अनइंस्टॉल करने के लिए सभी getBroadcast () के समान होने की आवश्यकता है। इसने मुझे बाहर कर दिया। धन्यवाद
johnDisplayClass

बहुत अच्छा काम करता है। धन्यवाद!
अंबरन

1
अच्छा उदाहरण है, लेकिन मैं वहां निजी अनुरोध कोड के रूप में 1001 का उपयोग नहीं करूंगा। उदाहरण को और अधिक स्पष्ट करने के लिए सिर्फ 0।
क्रिस

1
कृपया "शीर्ष उत्तर" आदि का उपयोग करने से बचें। इसके बजाय उत्तर का लिंक प्रदान करें। क्योंकि उत्तर लोकप्रियता के आधार पर पृष्ठ पर स्थितियां बदल सकते हैं।
काठिर

44

अलार्म प्रबंधक की निर्धारित विधि के लिए डॉक्स से इस उद्धरण पर ध्यान दें :

यदि पहले से ही इस इरादे के लिए एक अलार्म निर्धारित है (दो इरादों की समानता Intent.filterEquals द्वारा परिभाषित की जा रही है), तो इसे हटा दिया जाएगा और इसे एक से बदल दिया जाएगा।

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

आपको एक अलग दृष्टिकोण की आवश्यकता है यदि आप गणना करने की कोशिश कर रहे हैं कि पहले से बनाए गए अलार्म पर कितना समय शेष है, या यदि आपको वास्तव में यह जानने की आवश्यकता है कि क्या ऐसा अलार्म भी मौजूद है। उन प्रश्नों का उत्तर देने के लिए, अलार्म बनाते समय साझा किए गए प्रीफ़ डेटा को सहेजने पर विचार करें। आप जिस समय अलार्म सेट किया गया था उस समय आप घड़ी टाइमस्टैम्प को स्टोर कर सकते हैं, जिस समय आप अलार्म बंद होने की उम्मीद करते हैं, और दोहराने की अवधि (यदि आप एक दोहराए जाने वाले अलार्म को सेटअप करते हैं)।


2
मेरी राय में यह स्वीकृत उत्तर होना चाहिए। जब तक ओपी के पास एक विशेष स्थिति है जो अलार्म को
बहाल

मेरे मामले में, मैं जानना चाहता हूं कि क्या अलार्म पहले से सेट है और यदि मैं नया नहीं बनाना चाहता या मौजूदा अलार्म को रीसेट करना चाहता हूं।
इमरान असलम

2
शानदार जवाब। ओपी ने यह सब क्यों नहीं जांचा? ऐसा कुछ नहीं है जो आपको करने की आवश्यकता है।
विजय कुमार कांता

2
इस समाधान में कई लूप छेद हैं, यह पहले से बनाए गए अलार्म समय को ओवरराइड कर सकता है (यह कहता है कि यदि समय को टी + 24 की तरह निर्दिष्ट करने की आवश्यकता है) तो हर बार ऐप लॉन्च होने पर अलार्म समय एक ऐसी स्थिति को आगे बढ़ाता रहता है जो इसे कभी नहीं मिल सकता है कई के लिए ट्रिगर, इसलिए अलार्म की जांच करना अगर इसका पहले से मौजूद है तो अधिक विश्वसनीय है
नागा

10

मेरे पास 2 अलार्म हैं। मैं घटनाओं की पहचान करने के लिए कार्रवाई के बजाय एक्स्ट्रा के साथ इरादे का उपयोग कर रहा हूं:

Intent i = new Intent(context, AppReciever.class);
i.putExtra("timer", "timer1");

बात यह है कि अंतर के साथ आशय (और अलार्म) अभ्यस्त होना अतिरिक्त है। तो यह पहचानने में सक्षम है कि कौन सा अलार्म सक्रिय है या नहीं, मुझे अलग-अलग परिभाषित करना था requestCode:

boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i, 
                    PendingIntent.FLAG_NO_CREATE) != null);

और यहां बताया गया है कि अलार्म कैसे बनाया गया:

public static final int TIMER_1 = 1;
public static final int TIMER_2 = 2;

PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
            cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
pending = PendingIntent.getBroadcast(context, TIMER_2, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
            cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);

इरादे एक्स्ट्रा का उपयोग करना और इस समाधान ने मेरे लिए काम किया। केवल एक बदलाव मैं सेवा का उपयोग कर रहा हूं, इसलिए मैंने इसे बदल दिया हैPendingIntent.getService
पंकज

8

बस एक और उपाय मिला, यह मेरे लिए काम करने लगता है

Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);

boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null);
if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");}

if(!isWorking) {
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent,    PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week
    Log.d("Notif", "Notification every (ms): " + timeNotif);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent);
    }

कभी-कभी, मार्शमैलो पर, जब आप किसी एप्लिकेशन को बलपूर्वक रोकते हैं, तो GetBroadcast () गैर-शून्य वापस आ जाएगा, लेकिन अलार्म सेट नहीं है।
होपिया

6

जबकि यहाँ लगभग सभी लोगों ने सही उत्तर दिया है, किसी भी निकाय ने यह नहीं बताया कि अलारम्स किस आधार पर काम करते हैं

आप वास्तव में AlarmManagerइसके बारे में और इसके काम के बारे में अधिक जान सकते हैं । लेकिन यहाँ त्वरित जवाब है

आप भविष्य में किसी समय AlarmManagerमूल रूप से शेड्यूल देखते PendingIntentहैं। तो अनुसूचित अलार्म को रद्द करने के लिए आपको रद्द करने की आवश्यकता है PendingIntent

बनाते समय हमेशा दो बातों का ध्यान रखें PendingIntent

PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
  • अनुरोध कोड - विशिष्ट पहचानकर्ता के रूप में कार्य करता है
  • झंडा - के व्यवहार को परिभाषित करता है PendingIntent

अब यह जांचने के लिए कि अलार्म पहले से निर्धारित है या अलार्म को रद्द करने के लिए आपको बस उसी तक पहुंचने की आवश्यकता है PendingIntent। यदि आप समान अनुरोध कोड का उपयोग करते FLAG_NO_CREATEहैं और नीचे दिखाए गए जैसे उपयोग करते हैं तो यह किया जा सकता है

PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE);

if (pendingIntent!=null)
   alarmManager.cancel(pendingIntent);

यदि FLAG_NO_CREATEयह पहले से मौजूद नहीं है null, तो इसके साथ ही वापस आ जाएगी PendingIntent। यदि यह पहले से मौजूद है तो यह मौजूदा का संदर्भ देता हैPendingIntent


यदि अनुरोध कोड एक पहचानकर्ता है, तो क्या मिलान कार्रवाई के साथ इरादे को पारित करना महत्वपूर्ण है?
सेकुला

अगर आपके पास लंबित इरादे हैं तो अलार्म बजाने वाले के लिए समय निर्धारित करने का कोई तरीका है?
एम। स्मिथ

4

मैंने एक सरल (बेवकूफ या नहीं) बैश स्क्रिप्ट बनाई, जो कि एडी शेल से लोंगो को निकालती है, उन्हें टाइमस्टैम्प में परिवर्तित करती है और इसे लाल रंग में दिखाती है।

echo "Please set a search filter"
read search

adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;)

कोशिश करो ;)


1
    Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
            PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    sqlitewraper.context, 0, intent,
                    PendingIntent.FLAG_NO_CREATE);

FLAG_NO_CREATE लंबित आशय नहीं बनाता है, ताकि यह बूलियन मान को झूठा कर दे।

            boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
                    new Intent("com.my.package.MY_UNIQUE_ACTION"),
                    PendingIntent.FLAG_NO_CREATE) != null);

            if (alarmUp) {
                System.out.print("k");

            }

            AlarmManager alarmManager = (AlarmManager) sqlitewraper.context
                    .getSystemService(Context.ALARM_SERVICE);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
                    System.currentTimeMillis(), 1000 * 60, pendingIntent);

AlarmManager के बाद लंबित इरादे के मूल्य की जांच करें क्योंकि यह सच है क्योंकि AlarmManager अद्यतन लंबित आशय का ध्वज है।

            boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
                    new Intent("com.my.package.MY_UNIQUE_ACTION"),
                    PendingIntent.FLAG_UPDATE_CURRENT) != null);
            if (alarmUp1) {
                System.out.print("k");

            }

0

Im इस धारणा के तहत कि ऐसा करने का कोई तरीका नहीं है, हालांकि यह अच्छा होगा।

आप कहीं भी रिकॉर्ड किया गया Alarm_last_set_time, और On_boot_starter BroadcastReciever: BOOT_COMPLETED थोड़े चीज होने के द्वारा एक समान परिणाम प्राप्त कर सकते हैं।

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