नोट: मैंने विभिन्न समाधानों की कोशिश की जो स्टैकऑवरफ़्लो (उदाहरण यहाँ ) पर यहाँ लिखे गए हैं । कृपया बिना जांचे इसे बंद कर दें कि आपके द्वारा लिखी गई परीक्षा का उपयोग करके आपके द्वारा किए गए कार्यों से आपका समाधान नीचे लिखा है।
पृष्ठभूमि
ऐप पर एक आवश्यकता है, कि उपयोगकर्ता एक विशिष्ट समय पर शेड्यूल किया जाने वाला रिमाइंडर सेट करता है, इसलिए जब ऐप इस समय चालू हो जाता है, तो यह पृष्ठभूमि में कुछ छोटा करता है (बस कुछ DB क्वेरी ऑपरेशन), और एक दिखाता है सरल अधिसूचना, अनुस्मारक के बारे में बताने के लिए।
अतीत में, मैंने अपेक्षाकृत विशिष्ट समय पर अनुसूचित होने के लिए कुछ सेट करने के लिए एक सरल कोड का उपयोग किया था:
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pendingIntent = PendingIntent.getBroadcast(context, requestId, Intent(context, AlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
when {
VERSION.SDK_INT >= VERSION_CODES.KITKAT -> alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
else -> alarmManager.set(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
}
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("AppLog", "AlarmReceiver onReceive")
//do something in the real app
}
}
उपयोग:
val timeToTrigger = System.currentTimeMillis() + java.util.concurrent.TimeUnit.MINUTES.toMillis(1)
setAlarm(this, timeToTrigger, 1)
समस्या
मैंने अब इस कोड को नए एंड्रॉइड वर्जन और एंड्रॉइड 10 के साथ Pixel 4 पर एमुलेटर पर टेस्ट किया है, और यह ट्रिगर नहीं लगता है, या शायद यह बहुत लंबे समय के बाद ट्रिगर करता है क्योंकि मैं इसे प्रदान करता हूं। मैं भयानक व्यवहार से अच्छी तरह से वाकिफ हूं कि कुछ ओईएम ने हाल के कार्यों से ऐप हटाने के लिए जोड़ा, लेकिन यह एक एमुलेटर और पिक्सेल 4 डिवाइस (स्टॉक) दोनों पर है।
मैंने अलार्म सेट करने के बारे में डॉक्स पर पढ़ा है , कि यह ऐप्स के लिए प्रतिबंधित हो गया है ताकि यह बहुत बार घटित न हो, लेकिन यह यह नहीं बताता है कि विशिष्ट समय पर अलार्म कैसे सेट किया जाए, और यह स्पष्ट नहीं करता है कैसे आता है Google का क्लॉक ऐप इसे करने में सफल होता है।
इतना ही नहीं, लेकिन जो मैं समझता हूं, उसके अनुसार, यह प्रतिबंध विशेष रूप से डिवाइस की कम बिजली की स्थिति के लिए लागू किया जाना चाहिए, लेकिन मेरे मामले में, मेरे पास यह राज्य नहीं था, डिवाइस पर और एमुलेटर दोनों पर। मैंने अब से लगभग एक मिनट में अलार्म सेट किया है।
यह देखते हुए कि कई अलार्म क्लॉक ऐप अब काम नहीं करते हैं, जैसा कि वे करते थे, मुझे लगता है कि कुछ ऐसा है जो डॉक्स पर गायब है। ऐसे ऐप्स का उदाहरण लोकप्रिय टाइमली ऐप है जिसे Google द्वारा खरीदा गया था लेकिन नए प्रतिबंधों को संभालने के लिए कभी भी नए अपडेट नहीं मिले और अब उपयोगकर्ता इसे वापस चाहते हैं। । हालाँकि, कुछ लोकप्रिय ऐप ठीक काम करते हैं, जैसे कि यह ।
मैंने क्या कोशिश की है
यह परीक्षण करने के लिए कि वास्तव में अलार्म काम करता है, मैं इन परीक्षणों को तब करता हूं जब अब से एक मिनट में अलार्म को ट्रिगर करने की कोशिश की जा रही है, पहली बार ऐप इंस्टॉल करने के बाद, जब सभी डिवाइस पीसी से जुड़ा होता है (लॉग देखने के लिए):
- परीक्षण जब ऐप अग्रभूमि में होता है, तो उपयोगकर्ता को दिखाई देता है। - 1-2 मिनट लगे।
- जब ऐप को पृष्ठभूमि पर भेजा गया था (उदाहरण के लिए होम बटन का उपयोग करके) परीक्षण करें - लगभग 1 मिनट लग गया
- परीक्षण करें जब ऐप का कार्य हाल के कार्यों से हटा दिया गया था। - मैंने 20 मिनट से ज्यादा इंतजार किया और अलार्म बजने पर, लॉग से लिखते हुए नहीं देखा।
- # 3 की तरह, लेकिन स्क्रीन को भी बंद कर दें। यह शायद बदतर होगा ...
मैंने अगली चीजों का उपयोग करने की कोशिश की, सभी काम नहीं करते हैं:
alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(timeToTrigger, pendingIntent), pendingIntent)
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
उपरोक्त में से किसी के साथ, का संयोजन:
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) alarmManager.setWindow(AlarmManager.RTC_WAKEUP, 0, 60 * 1000L, pendingIntent)
ब्रॉडकास्टसीवर के बजाय एक सेवा का उपयोग करने की कोशिश की। एक अलग प्रक्रिया पर भी कोशिश की।
एप्लिकेशन को बैटरी ऑप्टिमाइज़ेशन से अनदेखा करने की कोशिश की गई (मदद नहीं मिली), लेकिन चूंकि अन्य ऐप्स को इसकी आवश्यकता नहीं है, इसलिए मुझे इसका उपयोग नहीं करना चाहिए।
इसका उपयोग करने की कोशिश की:
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP)
alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(timeToTrigger, pendingIntent), pendingIntent)
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
- ऐसी सेवा करने की कोशिश की जिसमें अलार्म को फिर से शेड्यूल करने के लिए onTaskRemoved का ट्रिगर होगा, लेकिन इससे भी मदद नहीं मिली (सेवा ने हालांकि ठीक काम किया)।
Google के क्लॉक ऐप के लिए, मुझे इसके बारे में कुछ विशेष नहीं दिखाई दिया, सिवाय इसके कि यह ट्रिगर होने से पहले एक सूचना दिखाता है, और मैं इसे बैटरी-ऑप्टिमाइज़ेशन सेटिंग स्क्रीन के "अनुकूलित नहीं" अनुभाग में भी नहीं देखता।
यह देखकर कि यह एक बग की तरह लगता है, मैंने इस बारे में यहां रिपोर्ट की , जिसमें नमूना परियोजना और मुद्दा दिखाने के लिए वीडियो भी शामिल है।
मैंने एमुलेटर के कई संस्करणों पर जांच की है, और ऐसा लगता है कि यह व्यवहार एपीआई 27 (एंड्रॉइड 8.1 - ओरेओ) से शुरू हुआ। डॉक्स को देखते हुए , मुझे अलार्म मैनजर का उल्लेख नहीं दिखता है, लेकिन इसके बजाय, यह विभिन्न पृष्ठभूमि के काम के बारे में लिखा गया था।
प्रश्न
आजकल हम अपेक्षाकृत सटीक समय पर कैसे ट्रिगर होते हैं?
उपरोक्त उपाय कैसे काम नहीं करते हैं? क्या मुझे कुछ याद आ रहा है? अनुमति? शायद मैं इसके बजाय एक कार्यकर्ता का उपयोग करने वाला हूं? लेकिन तब इसका मतलब यह नहीं होगा कि यह समय पर ट्रिगर नहीं हो सकता है?
Google "क्लॉक" ऐप इस सब को कैसे दूर करता है, और वैसे भी सटीक समय पर ट्रिगर करता है, हमेशा, भले ही यह सिर्फ एक मिनट पहले ट्रिगर किया गया हो? क्या यह केवल इसलिए है क्योंकि यह एक सिस्टम ऐप है? क्या होगा यदि यह एक उपयोगकर्ता ऐप के रूप में स्थापित हो जाता है, एक डिवाइस पर जो कि इसमें अंतर्निहित नहीं है?
यदि आप कहते हैं कि यह इसलिए है क्योंकि यह एक सिस्टम ऐप है, तो मुझे एक और ऐप मिला है जो 2 मिनट में दो बार अलार्म को ट्रिगर कर सकता है , हालांकि, मुझे लगता है कि यह कभी-कभी एक अग्रभूमि सेवा का उपयोग कर सकता है।
संपादित करें: यहाँ पर विचारों की कोशिश करने के लिए एक छोटा गथुब भंडार बनाया गया ।
संपादित करें: अंत में एक नमूना मिला जो दोनों खुले-खट्टे हैं और इसमें यह समस्या नहीं है। अफसोस की बात है कि यह बहुत जटिल है और मैं अभी भी यह पता लगाने की कोशिश करता हूं कि यह क्या अलग है (और क्या न्यूनतम कोड है जो मुझे अपने पीओसी में जोड़ना चाहिए) जो हाल के कार्यों से ऐप को हटाने के बाद इसके अलार्म को निर्धारित करने देता है।