मान लीजिए आपके पास एक एप्लिकेशन है जो एक स्थिर इंटरनेट कनेक्शन पर निर्भर करता है। आप चाहते हैं कि जब इंटरनेट कनेक्शन बदलता है तो आपका एप्लिकेशन सूचित हो। आप ऐसा कैसे करते हैं? एक संभावित समाधान एक सर्विस होगी जो हमेशा इंटरनेट कनेक्शन की जांच करती है। यह कार्यान्वयन विभिन्न कारणों से खराब है इसलिए हम इस पर विचार भी नहीं करेंगे। इस समस्या का समाधान एक ब्रॉडकास्ट रिसीवर है और यह उन परिवर्तनों को सुनेगा जिन्हें आप इसे बताते हैं। एक ब्रॉडकास्ट रिसीवर को हमेशा एक ब्रॉडकास्ट के बारे में सूचित किया जाएगा, आपके एप्लिकेशन की स्थिति की परवाह किए बिना। इससे कोई फर्क नहीं पड़ता कि आपका एप्लिकेशन वर्तमान में चल रहा है, बैकग्राउंड में है या बिल्कुल नहीं चल रहा है।
पृष्ठभूमि
ब्रॉडकास्ट रिसीवर्स आपके Android एप्लिकेशन में ऐसे घटक हैं जो विभिन्न स्रोतों से ब्रॉडकास्ट संदेशों (या घटनाओं) को सुनते हैं:
- अन्य एप्लिकेशन से
- सिस्टम से ही
- आपके एप्लिकेशन से
अर्थात, उन्हें तब लागू किया जाता है जब एक निश्चित कार्रवाई हुई होती है जिसे सुनने के लिए उन्हें प्रोग्राम किया गया है (यानी, एक ब्रॉडकास्ट)।
एक ब्रॉडकास्ट केवल एक इंटेंट ऑब्जेक्ट के अंदर लिपटा एक संदेश है। एक ब्रॉडकास्ट या तो इम्प्लिसिट या एक्सप्लिसिट हो सकता है।
- एक इम्प्लिसिट ब्रॉडकास्ट वह है जो विशेष रूप से आपके एप्लिकेशन को लक्षित नहीं करता है इसलिए यह आपके एप्लिकेशन के लिए विशेष नहीं है। एक के लिए पंजीकरण करने के लिए, आपको एक IntentFilter का उपयोग करने और इसे अपने मैनिफेस्ट में घोषित करने की आवश्यकता है। आपको यह सब करने की आवश्यकता है क्योंकि Android ऑपरेटिंग सिस्टम आपके मैनिफेस्ट में घोषित सभी इंटेंट फिल्टर्स को देखता है और देखता है कि क्या कोई मेल है। इस व्यवहार के कारण, इम्प्लिसिट ब्रॉडकास्ट में टारगेट एट्रिब्यूट नहीं होता है। एक इम्प्लिसिट ब्रॉडकास्ट का उदाहरण एक इनकमिंग SMS संदेश की कार्रवाई होगी।
- एक एक्सप्लिसिट ब्रॉडकास्ट वह है जो आपके एप्लिकेशन के लिए विशेष रूप से एक घटक पर लक्षित है जिसे पहले से जाना जाता है। यह टारगेट एट्रिब्यूट के कारण होता है जिसमें एप्लिकेशन का पैकेज नाम या एक घटक क्लास नाम होता है।
एक रिसीवर घोषित करने के दो तरीके हैं:
- अपने AndroidManifest.xml फ़ाइल में <receiver> टैग के साथ एक घोषित करके (जिसे स्टैटिक भी कहा जाता है)
<receiver android:name=".YourBrodcastReceiverClass" android:exported="true"> <intent-filter> <!-- The actions you wish to listen to, below is an example --> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
आप देखेंगे कि ऊपर घोषित ब्रॉडकास्ट रिसीवर में exported="true" की प्रॉपर्टी है। यह एट्रिब्यूट रिसीवर को बताता है कि यह एप्लिकेशन के दायरे के बाहर से ब्रॉडकास्ट प्राप्त कर सकता है।
2. या डायनामिक रूप से registerReceiver के साथ एक इंस्टेंस रजिस्टर करके (जिसे कॉन्टेक्स्ट रजिस्टर्ड के रूप में जाना जाता है)
public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter);
कार्यान्वयन
अपना ब्रॉडकास्ट रिसीवर बनाने के लिए, आपको पहले BroadcastReceiver पैरेंट क्लास को एक्सटेंड करना होगा और अनिवार्य मेथड, onReceive को ओवरराइड करना होगा:
public void onReceive(Context context, Intent intent) { //Implement your logic here }
इसे एक साथ रखने पर प्राप्त होता है:
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { StringBuilder sb = new StringBuilder(); sb.append("Action: " + intent.getAction() + "\n"); sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n"); String log = sb.toString(); Toast.makeText(context, log, Toast.LENGTH_LONG).show(); } }
⚠️onReceive मेथड मेन थ्रेड पर चलता है, और इस वजह से, इसका निष्पादन संक्षिप्त होना चाहिए।
यदि एक लंबी प्रक्रिया निष्पादित की जाती है, तो मेथड रिटर्न होने के बाद सिस्टम प्रक्रिया को मार सकता है। इसे रोकने के लिए, goAsync का उपयोग करने या जॉब शेड्यूल करने पर विचार करें। आप इस लेख के नीचे जॉब शेड्यूल करने के बारे में अधिक पढ़ सकते हैं।
डायनामिक पंजीकरण उदाहरण
कॉन्टेक्स्ट के साथ एक रिसीवर रजिस्टर करने के लिए, आपको पहले अपने ब्रॉडकास्ट रिसीवर का एक इंस्टेंस इंस्टेंशिएट करना होगा:
BroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
फिर, आप इसे विशिष्ट कॉन्टेक्स्ट के आधार पर रजिस्टर कर सकते हैं जिसे आप चाहते हैं:
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); this.registerReceiver(myBroadcastReceiver, filter);
जब आपको इसकी आवश्यकता न हो तो अपने ब्रॉडकास्ट रिसीवर को अनरजिस्टर करना न भूलें
@Override protected void onStop() { super.onStop(); unregisterReceiver(myBroadcastReceiver); }
एक घटना प्रसारित करना
अपने एप्लिकेशन से संदेश प्रसारित करने के पीछे का बिंदु यह है कि आपका एप्लिकेशन घटनाओं पर प्रतिक्रिया दे सके जैसे वे इसके अंदर होती हैं। एक परिदृश्य के बारे में सोचें जहां कोड के एक हिस्से में, उपयोगकर्ता एक निश्चित कार्रवाई करता है और इसके कारण, आप किसी अन्य स्थान पर आपके पास मौजूद कुछ अन्य तर्क को निष्पादित करना चाहते हैं।
ब्रॉडकास्ट भेजने के तीन तरीके हैं:
- sendOrderedBroadcast मेथड, यह सुनिश्चित करता है कि ब्रॉडकास्ट को एक समय में केवल एक रिसीवर को भेजा जाए। प्रत्येक ब्रॉडकास्ट बदले में, इसका अनुसरण करने वाले को डेटा पास कर सकता है, या उन रिसीवर्स को प्रसार रोक सकता है जो इसका अनुसरण करते हैं
- sendBroadcast ऊपर उल्लिखित मेथड के समान है, एक अंतर के साथ। सभी ब्रॉडकास्ट रिसीवर्स संदेश प्राप्त करते हैं और एक-दूसरे पर निर्भर नहीं करते
- LocalBroadcastManager.sendBroadcast मेथड केवल आपके एप्लिकेशन के अंदर परिभाषित रिसीवर्स को ब्रॉडकास्ट भेजता है और आपके एप्लिकेशन के दायरे से अधिक नहीं होता। कस्टम ब्रॉडकास्ट भेजने का उदाहरण
https://giphy.com/gifs/23gUJhHyWkXEwl7UYV/html5
गोट्चाज़ और ध्यान देने योग्य बातें
- एक इम्प्लिसिट ब्रॉडकास्ट के माध्यम से संवेदनशील डेटा न भेजें, क्योंकि कोई भी एप्लिकेशन जो इसे सुन रहा है, इसे प्राप्त करेगा। आप इसे या तो एक पैकेज निर्दिष्ट करके या ब्रॉडकास्ट से एक अनुमति जोड़कर रोक सकते हैं
- ब्रॉडकास्ट प्राप्त होने पर एक्टिविटीज शुरू न करें क्योंकि उपयोगकर्ता अनुभव की कमी है। इसके बजाय एक अधिसूचना प्रदर्शित करना चुनें।
निम्नलिखित बुलेट पॉइंट्स ब्रॉडकास्ट रिसीवर्स में परिवर्तनों को संदर्भित करते हैं जो प्रत्येक Android OS संस्करण के लिए प्रासंगिक हैं (7.0 से शुरू)। प्रत्येक संस्करण के लिए, कुछ सीमाएं लागू हुई हैं और व्यवहार भी बदल गया है। ब्रॉडकास्ट रिसीवर का उपयोग करने के बारे में सोचते समय इन सीमाओं को ध्यान में रखें।
- 7.0 और ऊपर (API लेवल 24) - दो सिस्टम ब्रॉडकास्ट अक्षम किए गए हैं, Action_New_Picture और Action_New_Video (लेकिन उन्हें Android O में रजिस्टर्ड रिसीवर्स के लिए वापस लाया गया)
- 8.0 और ऊपर (API लेवल 26) - अधिकांश इम्प्लिसिट ब्रॉडकास्ट को स्टैटिक रूप से (आपके मैनिफेस्ट में) नहीं बल्कि डायनामिक रूप से रजिस्टर करने की आवश्यकता है। आप इस लिंक में व्हाइटलिस्ट किए गए ब्रॉडकास्ट पा सकते हैं।
- 9.0 और ऊपर (API लेवल 28) - वाई-फाई सिस्टम ब्रॉडकास्ट और Network_State_Changed_Action पर कम जानकारी प्राप्त होती है।
Android O में परिवर्तन वे हैं जिनके बारे में आपको सबसे अधिक जागरूक होने की आवश्यकता है। इन परिवर्तनों को बनाने का कारण यह था कि इससे प्रदर्शन समस्याएं, बैटरी की कमी और उपयोगकर्ता अनुभव को नुकसान पहुंचा। ऐसा इसलिए हुआ क्योंकि कई एप्लिकेशन (यहां तक कि वर्तमान में नहीं चल रहे) एक सिस्टम-वाइड परिवर्तन पर सुन रहे थे और जब वह परिवर्तन हुआ, तो अराजकता हुई। कल्पना करें कि एक्शन के लिए पंजीकृत हर एप्लिकेशन यह जांचने के लिए जीवित हो गया कि क्या उसे ब्रॉडकास्ट के कारण कुछ करने की आवश्यकता है। वाई-फाई स्टेट जैसी किसी चीज को ध्यान में रखें, जो अक्सर बदलती है, और आप समझने लगेंगे कि ये परिवर्तन क्यों हुए।
ब्रॉडकास्ट रिसीवर्स के विकल्प
इन सभी प्रतिबंधों को नेविगेट करना आसान बनाने के लिए, नीचे अन्य घटकों का ब्रेकडाउन है जिनका उपयोग आप ब्रॉडकास्ट रिसीवर की अनुपस्थिति में कर सकते हैं। प्रत्येक की एक अलग जिम्मेदारी और उपयोग का मामला है, इसलिए यह मैप करने की कोशिश करें कि कौन सा आपकी आवश्यकताओं को पूरा करता है।
- LocalBroadcastManager - जैसा कि मैंने ऊपर उल्लेख किया है, यह केवल आपके एप्लिकेशन के भीतर ब्रॉडकास्ट के लिए मान्य है
- जॉब शेड्यूल करना - एक जॉब को प्राप्त सिग्नल या ट्रिगर के आधार पर चलाया जा सकता है, इसलिए आप पा सकते हैं कि जिस ब्रॉडकास्ट को आप सुन रहे थे, उसे जॉब द्वारा बदला जा सकता है। इसके अलावा, JobScheduler, यह गारंटी देगा कि आपका जॉब समाप्त हो जाएगा, लेकिन यह यह निर्धारित करने के लिए विभिन्न सिस्टम कारकों (समय और शर्तों) को ध्यान में रखेगा कि इसे कब चलना चाहिए। जॉब बनाते समय, आप onStartJob नामक एक मेथड को ओवरराइड करेंगे। यह मेथड मेन थ्रेड पर चलता है, इसलिए सुनिश्चित करें कि यह सीमित समय में अपना काम खत्म करता है। यदि आपको जटिल तर्क करने की आवश्यकता है, तो बैकग्राउंड टास्क शुरू करने पर विचार करें। इसके अलावा, इस मेथड के लिए रिटर्न मान एक बूलियन है, जहां true दर्शाता है कि कुछ क्रियाएं अभी भी की जा रही हैं, और false का अर्थ है कि जॉब पूरा हो गया है
यदि आप ब्रॉडकास्ट रिसीवर्स की खुशी और आश्चर्य का प्रत्यक्ष अनुभव करना चाहते हैं, तो आप इन लिंक्स का अनुसरण कर सकते हैं उन रिपॉजिटरीज के लिए जो मैंने सेट अप की हैं:
- कस्टम ब्रॉडकास्ट (मैनिफेस्ट घोषणा के साथ)
- ब्रॉडकास्ट रजिस्टर करना (मैनिफेस्ट में एक घोषित किए बिना)
- LocalBroadcastManager
ब्रॉडकास्ट समाप्त।