Android ऐप्लिकेशन, Android सिस्टम और अन्य Android ऐप्लिकेशन से ब्रॉडकास्ट मैसेज भेजते और पाते हैं. यह पब्लिश-सब्सक्राइब डिज़ाइन पैटर्न की तरह होता है. सिस्टम और ऐप्लिकेशन आम तौर पर कुछ इवेंट होने पर ब्रॉडकास्ट भेजते हैं. उदाहरण के लिए, Android सिस्टम अलग-अलग सिस्टम इवेंट होने पर ब्रॉडकास्ट भेजता है. जैसे, सिस्टम बूट होने या डिवाइस चार्ज होने पर. ऐप्लिकेशन, कस्टम ब्रॉडकास्ट भी भेजते हैं. उदाहरण के लिए, वे अन्य ऐप्लिकेशन को ऐसी किसी चीज़ के बारे में सूचना देते हैं जिसमें उनकी दिलचस्पी हो सकती है. जैसे, नया डेटा डाउनलोड करना.
ऐप्लिकेशन, किसी खास ब्रॉडकास्ट को पाने के लिए रजिस्टर कर सकते हैं. ब्रॉडकास्ट भेजे जाने पर, सिस्टम ब्रॉडकास्ट को उन ऐप्लिकेशन पर अपने-आप भेज देता है जिन्होंने उस तरह के ब्रॉडकास्ट पाने के लिए सदस्यता ली है.
आम तौर पर, ब्रॉडकास्ट का इस्तेमाल, ऐप्लिकेशन और उपयोगकर्ता के सामान्य फ़्लो के बाहर मैसेजिंग सिस्टम के तौर पर किया जा सकता है. हालांकि, आपको ब्रॉडकास्ट का जवाब देने और बैकग्राउंड में ऐसे टास्क चलाने के मौके का गलत इस्तेमाल नहीं करना चाहिए जिनकी वजह से सिस्टम की परफ़ॉर्मेंस धीमी हो सकती है.
सिस्टम ब्रॉडकास्ट के बारे में जानकारी
सिस्टम के अलग-अलग इवेंट होने पर, सिस्टम अपने-आप ब्रॉडकास्ट भेजता है. जैसे, जब सिस्टम हवाई जहाज़ मोड में चालू और बंद होता है. सदस्यता वाले सभी ऐप्लिकेशन को ये ब्रॉडकास्ट मिलते हैं.
Intent ऑब्जेक्ट, ब्रॉडकास्ट मैसेज को रैप करता है. action स्ट्रिंग से, हुए इवेंट की पहचान होती है. जैसे, android.intent.action.AIRPLANE_MODE. इंटेंट में, अतिरिक्त फ़ील्ड में बंडल की गई ज़्यादा जानकारी भी शामिल हो सकती है.
उदाहरण के लिए, फ़्लाइट मोड चालू करने के इंटेंट में एक बूलियन एक्स्ट्रा शामिल होता है. इससे पता चलता है कि फ़्लाइट मोड चालू है या नहीं.
इंटेंट को पढ़ने और किसी इंटेंट से ऐक्शन स्ट्रिंग पाने के तरीके के बारे में ज़्यादा जानने के लिए, इंटेंट और इंटेंट फ़िल्टर देखें.
सिस्टम ब्रॉडकास्ट से जुड़ी कार्रवाइयां
सिस्टम ब्रॉडकास्ट ऐक्शन की पूरी सूची देखने के लिए, Android SDK में मौजूद BROADCAST_ACTIONS.TXT
फ़ाइल देखें. हर ब्रॉडकास्ट ऐक्शन से एक कॉन्स्टेंट फ़ील्ड जुड़ा होता है. उदाहरण के लिए, कॉन्स्टेंट ACTION_AIRPLANE_MODE_CHANGED की वैल्यू android.intent.action.AIRPLANE_MODE है.
हर ब्रॉडकास्ट ऐक्शन के लिए दस्तावेज़, उससे जुड़े कॉन्स्टेंट फ़ील्ड में उपलब्ध होता है.
सिस्टम ब्रॉडकास्ट में किए गए बदलाव
Android प्लैटफ़ॉर्म में समय-समय पर बदलाव होते रहते हैं. इसलिए, सिस्टम ब्रॉडकास्ट के काम करने के तरीके में भी समय-समय पर बदलाव होता रहता है. Android के सभी वर्शन के साथ काम करने के लिए, इन बदलावों का ध्यान रखें.
Android 16
Android 16 में, अलग-अलग प्रोसेस में android:priority एट्रिब्यूट या IntentFilter.setPriority() का इस्तेमाल करके ब्रॉडकास्ट डिलीवरी के क्रम की गारंटी नहीं दी जाएगी. ब्रॉडकास्ट की प्राथमिकताएं, सभी प्रोसेस के बजाय सिर्फ़ एक ही ऐप्लिकेशन प्रोसेस में लागू होती हैं.
साथ ही, ब्रॉडकास्ट की प्राथमिकताएं अपने-आप इस रेंज में सीमित हो जाती हैं: (SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY - 1).
सिर्फ़ सिस्टम कॉम्पोनेंट को ब्रॉडकास्ट की प्राथमिकता के तौर पर SYSTEM_LOW_PRIORITY,
SYSTEM_HIGH_PRIORITY सेट करने की अनुमति है.
Android 14
जब ऐप्लिकेशन कैश किए गए डेटा की स्थिति में होते हैं, तब सिस्टम की परफ़ॉर्मेंस को बेहतर बनाए रखने के लिए, सिस्टम ब्रॉडकास्ट डिलीवरी को ऑप्टिमाइज़ करता है. उदाहरण के लिए, जब ऐप्लिकेशन कैश मेमोरी में सेव होता है, तब सिस्टम कम ज़रूरी सिस्टम ब्रॉडकास्ट को कुछ समय के लिए रोक देता है. जैसे, ACTION_SCREEN_ON.
जब ऐप्लिकेशन, कैश मेमोरी में सेव होने की स्थिति से ऐक्टिव प्रोसेस लाइफ़साइकल में चला जाता है, तब सिस्टम, टाले गए ब्रॉडकास्ट डिलीवर करता है.
मेनिफ़ेस्ट में बताई गई ज़रूरी ब्रॉडकास्ट के लिए, कुछ समय के लिए ऐप्लिकेशन को कैश मेमोरी में सेव की गई स्थिति से हटा दिया जाता है, ताकि उन्हें डिलीवर किया जा सके.
Android 9
Android 9 (एपीआई लेवल 28) से, NETWORK_STATE_CHANGED_ACTION ब्रॉडकास्ट को उपयोगकर्ता की जगह की जानकारी या व्यक्तिगत पहचान से जुड़ा डेटा नहीं मिलता है.
अगर आपका ऐप्लिकेशन, Android 9.0 (एपीआई लेवल 28) या उसके बाद के वर्शन वाले डिवाइस पर इंस्टॉल है, तो सिस्टम, वाई-फ़ाई ब्रॉडकास्ट में एसएसआईडी, बीएसएसआईडी, कनेक्शन की जानकारी या स्कैन के नतीजे शामिल नहीं करता है. यह जानकारी पाने के लिए, getConnectionInfo() पर कॉल करें.
Android 8.0
Android 8.0 (एपीआई लेवल 26) से, सिस्टम, मेनिफ़ेस्ट में बताए गए रिसीवर पर अतिरिक्त पाबंदियां लगाता है.
अगर आपका ऐप्लिकेशन Android 8.0 या इसके बाद के वर्शन को टारगेट करता है, तो मेनिफ़ेस्ट का इस्तेमाल करके, ज़्यादातर इंप्लिसिट ब्रॉडकास्ट (ऐसे ब्रॉडकास्ट जो खास तौर पर आपके ऐप्लिकेशन को टारगेट नहीं करते) के लिए रिसीवर का एलान नहीं किया जा सकता. जब उपयोगकर्ता आपके ऐप्लिकेशन का इस्तेमाल कर रहा हो, तब भी कॉन्टेक्स्ट-रजिस्टर्ड रिसीवर का इस्तेमाल किया जा सकता है.
Android 7.0
Android 7.0 (एपीआई लेवल 24) और इसके बाद के वर्शन पर, सिस्टम ब्रॉडकास्ट नहीं भेजे जाते:
साथ ही, Android 7.0 और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन को, CONNECTIVITY_ACTION ब्रॉडकास्ट को registerReceiver(BroadcastReceiver, IntentFilter) का इस्तेमाल करके रजिस्टर करना होगा. मेनिफ़ेस्ट में रिसीवर का एलान करने से काम नहीं चलता.
ब्रॉडकास्ट पाना
ऐप्लिकेशन को दो तरीकों से ब्रॉडकास्ट मिल सकते हैं: कॉन्टेक्स्ट-रजिस्टर्ड रिसीवर और मेनिफ़ेस्ट-डिक्लेयर्ड रिसीवर के ज़रिए.
कॉन्टेक्स्ट के हिसाब से रजिस्टर किए गए रिसीवर
कॉन्टेक्स्ट के हिसाब से रजिस्टर किए गए रिसीवर को ब्रॉडकास्ट तब तक मिलते हैं, जब तक उनका रजिस्टरिंग कॉन्टेक्स्ट मान्य होता है. आम तौर पर, यह registerReceiver और unregisterReceiver के बीच होता है. जब सिस्टम, रजिस्टर किए गए कॉन्टेक्स्ट को मिटा देता है, तब रजिस्टर किया गया कॉन्टेक्स्ट भी अमान्य हो जाता है. उदाहरण के लिए, अगर आपने Activity कॉन्टेक्स्ट में रजिस्टर किया है, तो आपको तब तक ब्रॉडकास्ट मिलते रहेंगे, जब तक गतिविधि चालू रहेगी. ऐप्लिकेशन के कॉन्टेक्स्ट के साथ रजिस्टर करने पर, ऐप्लिकेशन के चालू रहने तक आपको ब्रॉडकास्ट मिलते रहेंगे.
किसी कॉन्टेक्स्ट के साथ रिसीवर को रजिस्टर करने के लिए, यह तरीका अपनाएं:
अपने ऐप्लिकेशन की मॉड्यूल-लेवल की बिल्ड फ़ाइल में, AndroidX Core लाइब्रेरी का 1.9.0 या उसके बाद का वर्शन शामिल करें:
Groovy
dependencies { def core_version = "1.19.0" // Java language implementation implementation "androidx.core:core:$core_version" // Kotlin implementation "androidx.core:core-ktx:$core_version" // To use RoleManagerCompat implementation "androidx.core:core-role:1.1.0" // To use the Animator APIs implementation "androidx.core:core-animation:1.0.0" // To test the Animator APIs androidTestImplementation "androidx.core:core-animation-testing:1.0.0" // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation "androidx.core:core-performance:1.0.0" // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation "androidx.core:core-google-shortcuts:1.1.0" // Optional - to support backwards compatibility of RemoteViews implementation "androidx.core:core-remoteviews:1.1.0" // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation "androidx.core:core-splashscreen:1.2.0" }
Kotlin
dependencies { val core_version = "1.19.0" // Java language implementation implementation("androidx.core:core:$core_version") // Kotlin implementation("androidx.core:core-ktx:$core_version") // To use RoleManagerCompat implementation("androidx.core:core-role:1.1.0") // To use the Animator APIs implementation("androidx.core:core-animation:1.0.0") // To test the Animator APIs androidTestImplementation("androidx.core:core-animation-testing:1.0.0") // Optional - To enable APIs that query the performance characteristics of GMS devices. implementation("androidx.core:core-performance:1.0.0") // Optional - to use ShortcutManagerCompat to donate shortcuts to be used by Google implementation("androidx.core:core-google-shortcuts:1.1.0") // Optional - to support backwards compatibility of RemoteViews implementation("androidx.core:core-remoteviews:1.1.0") // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12 implementation("androidx.core:core-splashscreen:1.2.0") }
BroadcastReceiverका इंस्टेंस बनाने के लिए:Kotlin
val myBroadcastReceiver = MyBroadcastReceiver()Java
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();IntentFilterका इंस्टेंस बनाने के लिए:Kotlin
val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")Java
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");चुनें कि ब्रॉडकास्ट रिसीवर को एक्सपोर्ट किया जाना चाहिए या नहीं. साथ ही, यह भी चुनें कि वह डिवाइस पर मौजूद अन्य ऐप्लिकेशन को दिखना चाहिए या नहीं. अगर यह रिसीवर, सिस्टम या अन्य ऐप्लिकेशन से भेजे गए ब्रॉडकास्ट सुन रहा है, तो
RECEIVER_EXPORTEDफ़्लैग का इस्तेमाल करें. भले ही, वे ऐप्लिकेशन आपके हों. अगर यह रिसीवर सिर्फ़ आपके ऐप्लिकेशन से भेजे गए ब्रॉडकास्ट सुनता है, तोRECEIVER_NOT_EXPORTEDफ़्लैग का इस्तेमाल करें.Kotlin
val listenToBroadcastsFromOtherApps = false val receiverFlags = if (listenToBroadcastsFromOtherApps) { ContextCompat.RECEIVER_EXPORTED } else { ContextCompat.RECEIVER_NOT_EXPORTED }Java
boolean listenToBroadcastsFromOtherApps = false; int receiverFlags = listenToBroadcastsFromOtherApps ? ContextCompat.RECEIVER_EXPORTED : ContextCompat.RECEIVER_NOT_EXPORTED;registerReceiver()को कॉल करके, रिसीवर को रजिस्टर करें:Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);ब्रॉडकास्ट पाना बंद करने के लिए,
unregisterReceiver(android.content.BroadcastReceiver)पर कॉल करें. जब आपको रिसीवर की ज़रूरत न हो या कॉन्टेक्स्ट अब मान्य न हो, तो उसे अनरजिस्टर करना न भूलें.
ब्रॉडकास्ट रिसीवर को अनरजिस्टर करना
ब्रॉडकास्ट रिसीवर रजिस्टर होने के दौरान, यह उस कॉन्टेक्स्ट का रेफ़रंस सेव करता है जिसके साथ आपने इसे रजिस्टर किया था. अगर ईमेल पाने वाले व्यक्ति का रजिस्टर किया गया स्कोप, कॉन्टेक्स्ट लाइफ़साइकल स्कोप से ज़्यादा है, तो इससे जानकारी लीक हो सकती है. उदाहरण के लिए, ऐसा तब हो सकता है, जब आपने किसी ऐक्टिविटी के स्कोप पर रिसीवर को रजिस्टर किया हो, लेकिन सिस्टम के ऐक्टिविटी को बंद करने पर, उसे रजिस्ट्रेशन रद्द करना भूल गए हों. इसलिए, ब्रॉडकास्ट रिसीवर को हमेशा अनरजिस्टर करें.
Kotlin
class MyActivity : ComponentActivity() {
private val myBroadcastReceiver = MyBroadcastReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags)
setContent { MyApp() }
}
override fun onDestroy() {
super.onDestroy()
// When you forget to unregister your receiver here, you're causing a leak!
this.unregisterReceiver(myBroadcastReceiver)
}
}
Java
class MyActivity extends ComponentActivity {
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
// Set content
}
}
सबसे छोटे स्कोप में रिसीवर रजिस्टर करना
ब्रॉडकास्ट रिसीवर को सिर्फ़ तब रजिस्टर किया जाना चाहिए, जब आपको वाकई में नतीजे में दिलचस्पी हो. पैसे पाने वाले के लिए सबसे छोटा स्कोप चुनें:
LifecycleResumeEffectया गतिविधिonResume/onPauseलाइफ़साइकल के तरीके: ब्रॉडकास्ट रिसीवर को सिर्फ़ तब अपडेट मिलते हैं, जब ऐप्लिकेशन फिर से शुरू किया गया हो.LifecycleStartEffectया गतिविधिonStart/onStopलाइफ़साइकल के तरीके: ब्रॉडकास्ट रिसीवर को सिर्फ़ तब अपडेट मिलते हैं, जब ऐप्लिकेशन फिर से शुरू किया गया हो.DisposableEffect: ब्रॉडकास्ट रिसीवर को सिर्फ़ तब अपडेट मिलते हैं, जब कंपोज़ेबल, कंपोज़िशन ट्री में होता है. यह स्कोप, ऐक्टिविटी के लाइफ़साइकल स्कोप से अटैच नहीं है. ऐप्लिकेशन के कॉन्टेक्स्ट में, ईमेल पाने वाले व्यक्ति को रजिस्टर करें. ऐसा इसलिए होता है, क्योंकि कंपोज़ेबल, गतिविधि की लाइफ़साइकल के स्कोप से ज़्यादा समय तक चल सकता है और गतिविधि को लीक कर सकता है.- गतिविधि
onCreate/onDestroy: गतिविधि के बनाए जाने के दौरान, ब्रॉडकास्ट रिसीवर को अपडेट मिलते हैं. पक्का करें कि आपनेonDestroy()में अनरजिस्टर किया हो, न किonSaveInstanceState(Bundle)में. ऐसा इसलिए, क्योंकि हो सकता है कि इसे कॉल न किया जाए. - कस्टम स्कोप: उदाहरण के लिए, अपने
ViewModelस्कोप में किसी रिसीवर को रजिस्टर किया जा सकता है, ताकि वह गतिविधि को फिर से बनाने के बाद भी काम करता रहे. पक्का करें कि रिसीवर को रजिस्टर करने के लिए, ऐप्लिकेशन कॉन्टेक्स्ट का इस्तेमाल किया गया हो. ऐसा इसलिए, क्योंकि रिसीवर, गतिविधि के लाइफ़साइकल स्कोप से ज़्यादा समय तक चल सकता है और गतिविधि को लीक कर सकता है.
स्टेटफ़ुल और स्टेटलेस कंपोज़ेबल बनाना
Compose में स्टेटफ़ुल और स्टेटलेस कंपोज़ेबल होते हैं. किसी कंपोज़ेबल के अंदर ब्रॉडकास्ट रिसीवर को रजिस्टर या अनरजिस्टर करने से, वह स्टेटफ़ुल हो जाता है. कंपोज़ेबल, एक ऐसा फ़ंक्शन नहीं है जो एक जैसे पैरामीटर पास किए जाने पर एक जैसा कॉन्टेंट रेंडर करता है. रजिस्टर किए गए ब्रॉडकास्ट रिसीवर को किए गए कॉल के आधार पर, इंटरनल स्टेट बदल सकती है.
Compose में सबसे सही तरीके के तौर पर, हमारा सुझाव है कि आप अपने कंपोज़ेबल को स्टेटफ़ुल और स्टेटलेस वर्शन में बांटें. इसलिए, हमारा सुझाव है कि आप ब्रॉडकास्ट रिसीवर को Composable से बाहर ले जाएं, ताकि यह स्टेटलेस हो जाए:
@Composable
fun MyStatefulScreen() {
val myBroadcastReceiver = remember { MyBroadcastReceiver() }
val context = LocalContext.current
LifecycleStartEffect(true) {
// ...
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, flags)
onStopOrDispose { context.unregisterReceiver(myBroadcastReceiver) }
}
MyStatelessScreen()
}
@Composable
fun MyStatelessScreen() {
// Implement your screen
}
मेनिफ़ेस्ट में बताए गए रिसीवर
अगर आपने अपने मेनिफ़ेस्ट में ब्रॉडकास्ट रिसीवर का एलान किया है, तो ब्रॉडकास्ट भेजे जाने पर सिस्टम आपके ऐप्लिकेशन को लॉन्च करता है. अगर ऐप्लिकेशन पहले से नहीं चल रहा है, तो सिस्टम उसे लॉन्च करता है.
ब्रॉडकास्ट रिसीवर को मेनिफ़ेस्ट में शामिल करने के लिए, यह तरीका अपनाएं:
अपने ऐप्लिकेशन के मेनिफ़ेस्ट में
<receiver>एलिमेंट के बारे में बताएं.<!-- If this receiver listens for broadcasts sent from the system or from other apps, even other apps that you own, set android:exported to "true". --> <receiver android:name=".MyBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.example.snippets.ACTION_UPDATE_DATA" /> </intent-filter> </receiver>इंटेंट फ़िल्टर, ब्रॉडकास्ट ऐक्शन के बारे में बताते हैं. ये वे ऐक्शन होते हैं जिनके लिए आपका रिसीवर रजिस्टर करता है.
BroadcastReceiverको सबक्लास करें औरonReceive(Context, Intent)को लागू करें. यहां दिए गए उदाहरण में, ब्रॉडकास्ट रिसीवर, ब्रॉडकास्ट के कॉन्टेंट को लॉग करता है और उसे दिखाता है:Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var dataRepository: DataRepository override fun onReceive(context: Context, intent: Intent) { if (intent.action == "com.example.snippets.ACTION_UPDATE_DATA") { val data = intent.getStringExtra("com.example.snippets.DATA") ?: "No data" // Do something with the data, for example send it to a data repository: dataRepository.updateData(data) } } }Java
public static class MyBroadcastReceiver extends BroadcastReceiver { @Inject DataRepository dataRepository; @Override public void onReceive(Context context, Intent intent) { if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) { String data = intent.getStringExtra("com.example.snippets.DATA"); // Do something with the data, for example send it to a data repository: if (data != null) { dataRepository.updateData(data); } } } }
ऐप्लिकेशन इंस्टॉल होने पर, सिस्टम पैकेज मैनेजर, रिसीवर को रजिस्टर करता है. इसके बाद, रिसीवर आपके ऐप्लिकेशन में एक अलग एंट्री पॉइंट बन जाता है. इसका मतलब है कि अगर ऐप्लिकेशन नहीं चल रहा है, तो सिस्टम ऐप्लिकेशन को शुरू कर सकता है और ब्रॉडकास्ट डिलीवर कर सकता है.
सिस्टम, हर ब्रॉडकास्ट को हैंडल करने के लिए एक नया BroadcastReceiver कॉम्पोनेंट ऑब्जेक्ट बनाता है. यह ऑब्जेक्ट, सिर्फ़ onReceive(Context, Intent) को कॉल करने की अवधि के लिए मान्य होता है. जब आपका कोड इस तरीके से वापस आ जाता है, तो सिस्टम कॉम्पोनेंट को अब चालू नहीं मानता.
प्रोसेस की स्थिति पर असर
BroadcastReceiver के चालू या बंद होने से, इसमें मौजूद प्रोसेस पर असर पड़ता है. इससे सिस्टम के क्रैश होने की संभावना बदल सकती है. फ़ोरग्राउंड प्रोसेस, रिसीवर के onReceive() तरीके को लागू करती है. सिस्टम इस प्रोसेस को तब तक चलाता है, जब तक कि मेमोरी पर बहुत ज़्यादा दबाव न हो.
सिस्टम, onReceive() के बाद BroadcastReceiver को बंद कर देता है.
रिसीवर की होस्ट प्रोसेस की अहमियत, उसके ऐप्लिकेशन कॉम्पोनेंट पर निर्भर करती है. अगर उस प्रोसेस में सिर्फ़ मेनिफ़ेस्ट में बताया गया रिसीवर होस्ट किया जाता है, तो सिस्टम उसे onReceive() के बाद बंद कर सकता है, ताकि अन्य ज़रूरी प्रोसेस के लिए संसाधन खाली किए जा सकें. ऐसा उन ऐप्लिकेशन के लिए आम है जिनके साथ उपयोगकर्ता ने कभी इंटरैक्ट नहीं किया है या हाल ही में इंटरैक्ट नहीं किया है.
इसलिए, ब्रॉडकास्ट रिसीवर को बैकग्राउंड में लंबे समय तक चलने वाले थ्रेड शुरू नहीं करने चाहिए.
सिस्टम, onReceive() के बाद किसी भी समय प्रोसेस को रोक सकता है, ताकि मेमोरी को वापस पाया जा सके. इससे, बनाई गई थ्रेड बंद हो जाएगी. इस प्रोसेस को चालू रखने के लिए, JobScheduler का इस्तेमाल करके, पाने वाले व्यक्ति के लिए JobService शेड्यूल करें, ताकि सिस्टम को पता चल सके कि प्रोसेस अब भी काम कर रही है. बैकग्राउंड में होने वाले काम की खास जानकारी में ज़्यादा जानकारी दी गई है.
ब्रॉडकास्ट भेजें
Android, ऐप्लिकेशन को ब्रॉडकास्ट भेजने के दो तरीके उपलब्ध कराता है:
sendOrderedBroadcast(Intent, String)तरीके से, एक बार में एक ही व्यक्ति को ब्रॉडकास्ट भेजे जाते हैं. हर रिसीवर एक-एक करके काम करता है. इसलिए, यह अगले रिसीवर को नतीजे भेज सकता है. यह ब्रॉडकास्ट को पूरी तरह से बंद भी कर सकता है, ताकि यह अन्य डिवाइसों तक न पहुंचे. आपके पास यह कंट्रोल करने का विकल्प होता है कि एक ही ऐप्लिकेशन प्रोसेस में रिसीवर किस क्रम में चलें. इसके लिए, मिलते-जुलते इंटेंट-फ़िल्टर केandroid:priorityएट्रिब्यूट का इस्तेमाल करें. एक जैसी प्राथमिकता वाले रिसीवर, किसी भी क्रम में चलाए जाते हैं.sendBroadcast(Intent)तरीके से, सभी रिसीवर को ब्रॉडकास्ट भेजे जाते हैं. हालांकि, इन्हें किसी क्रम में नहीं भेजा जाता. इसे सामान्य ब्रॉडकास्ट कहा जाता है. यह ज़्यादा असरदार है, लेकिन इसका मतलब है कि डेटा पाने वाले लोग, अन्य लोगों से मिले नतीजे नहीं पढ़ सकते. साथ ही, ब्रॉडकास्ट से मिले डेटा को आगे नहीं बढ़ा सकते या ब्रॉडकास्ट को बंद नहीं कर सकते.
नीचे दिए गए कोड स्निपेट में, Intent बनाकर और sendBroadcast(Intent) को कॉल करके ब्रॉडकास्ट भेजने का तरीका बताया गया है.
Kotlin
val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
putExtra("com.example.snippets.DATA", newData)
setPackage("com.example.snippets")
}
context.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
intent.putExtra("com.example.snippets.DATA", newData);
intent.setPackage("com.example.snippets");
context.sendBroadcast(intent);
ब्रॉडकास्ट मैसेज को Intent ऑब्जेक्ट में रैप किया जाता है. इंटेंट की action स्ट्रिंग में, ऐप्लिकेशन के Java पैकेज के नाम का सिंटैक्स होना चाहिए. साथ ही, यह ब्रॉडकास्ट इवेंट की यूनीक पहचान करने वाली होनी चाहिए. putExtra(String, Bundle) का इस्तेमाल करके, इंटेंट में अतिरिक्त जानकारी अटैच की जा सकती है. इंटेंट पर setPackage(String) को कॉल करके, ब्रॉडकास्ट को एक ही संगठन के ऐप्लिकेशन के सेट तक सीमित किया जा सकता है.
अनुमतियों के ज़रिए ब्रॉडकास्ट पर पाबंदी लगाना
अनुमतियों की मदद से, ब्रॉडकास्ट को उन ऐप्लिकेशन तक सीमित किया जा सकता है जिनके पास कुछ अनुमतियां हैं. ब्रॉडकास्ट करने वाले या पाने वाले पर पाबंदियां लगाई जा सकती हैं.
अनुमतियों के साथ ब्रॉडकास्ट भेजना
sendBroadcast(Intent, String) या sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
Bundle) को कॉल करते समय, अनुमति पैरामीटर तय किया जा सकता है. सिर्फ़ वे डिवाइस ब्रॉडकास्ट पा सकते हैं जिन्होंने अपने मेनिफ़ेस्ट में <uses-permission> टैग के साथ अनुमति का अनुरोध किया है. अगर अनुमति खतरनाक है, तो ब्रॉडकास्ट पाने वाले व्यक्ति को ब्रॉडकास्ट मिलने से पहले, आपको अनुमति देनी होगी. उदाहरण के लिए, यहां दिया गया कोड अनुमति के साथ ब्रॉडकास्ट भेजता है:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
ब्रॉडकास्ट पाने के लिए, ऐप्लिकेशन को इस तरह अनुमति का अनुरोध करना होगा:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
आपके पास सिस्टम की किसी मौजूदा अनुमति को तय करने का विकल्प होता है. जैसे, BLUETOOTH_CONNECT. इसके अलावा, <permission> एलिमेंट का इस्तेमाल करके, कस्टम अनुमति तय की जा सकती है. अनुमतियों और सुरक्षा के बारे में सामान्य जानकारी के लिए, सिस्टम की अनुमतियां लेख पढ़ें.
अनुमतियों के साथ ब्रॉडकास्ट पाना
अगर ब्रॉडकास्ट रिसीवर को रजिस्टर करते समय अनुमति का पैरामीटर तय किया जाता है (मेनिफ़ेस्ट में registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) या <receiver> टैग के साथ), तो सिर्फ़ वे ब्रॉडकास्टर रिसीवर को इंटेंट भेज सकते हैं जिन्होंने मेनिफ़ेस्ट में <uses-permission> टैग के साथ अनुमति का अनुरोध किया है. अगर अनुमति खतरनाक है, तो ब्रॉडकास्टर को भी अनुमति दी जानी चाहिए.
उदाहरण के लिए, मान लें कि आपके ऐप्लिकेशन में मेनिफ़ेस्ट में बताया गया रिसीवर इस तरह है: follows:
<!-- If this receiver listens for broadcasts sent from the system or from
other apps, even other apps that you own, set android:exported to "true". -->
<receiver
android:name=".MyBroadcastReceiverWithPermission"
android:permission="android.permission.ACCESS_COARSE_LOCATION"
android:exported="true">
<intent-filter>
<action android:name="com.example.snippets.ACTION_UPDATE_DATA" />
</intent-filter>
</receiver>
इसके अलावा, आपका ऐप्लिकेशन कॉन्टेक्स्ट के हिसाब से रजिस्टर किए गए रिसीवर का इस्तेमाल करता हो. जैसे:
Kotlin
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
)
Java
ContextCompat.registerReceiver(
context, myBroadcastReceiver, filter,
android.Manifest.permission.ACCESS_COARSE_LOCATION,
null, // scheduler that defines thread, null means run on main thread
receiverFlags
);
इसके बाद, उन रिसीवर को ब्रॉडकास्ट भेजने के लिए, ब्रॉडकास्ट भेजने वाले ऐप्लिकेशन को इस तरह अनुमति का अनुरोध करना होगा:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
सुरक्षा से जुड़ी बातें
ब्रॉडकास्ट भेजने और पाने के लिए, सुरक्षा से जुड़ी कुछ बातों का ध्यान रखें:
अगर कई ऐप्लिकेशन ने अपनी मेनिफ़ेस्ट फ़ाइल में एक ही ब्रॉडकास्ट पाने के लिए रजिस्टर किया है, तो सिस्टम कई ऐप्लिकेशन लॉन्च कर सकता है. इससे डिवाइस की परफ़ॉर्मेंस और उपयोगकर्ता अनुभव, दोनों पर काफ़ी असर पड़ सकता है. इससे बचने के लिए, मेनिफ़ेस्ट के एलान के बजाय कॉन्टेक्स्ट रजिस्ट्रेशन का इस्तेमाल करें. कभी-कभी, Android सिस्टम खुद ही कॉन्टेक्स्ट-रजिस्टर्ड रिसीवर का इस्तेमाल करने के लिए कहता है. उदाहरण के लिए,
CONNECTIVITY_ACTIONब्रॉडकास्ट सिर्फ़ उन रिसीवर को डिलीवर किया जाता है जो कॉन्टेक्स्ट के साथ रजिस्टर किए गए हैं.इम्प्लिसिट इंटेंट का इस्तेमाल करके, संवेदनशील जानकारी ब्रॉडकास्ट न करें. अगर कोई ऐप्लिकेशन ब्रॉडकास्ट पाने के लिए रजिस्टर करता है, तो वह जानकारी को पढ़ सकता है. यह कंट्रोल करने के तीन तरीके हैं कि आपकी ब्रॉडकास्ट की गई पोस्ट कौन देख सकता है:
- ब्रॉडकास्ट भेजते समय, अनुमति दी जा सकती है.
- Android 4.0 (एपीआई लेवल 14) और इसके बाद के वर्शन में, ब्रॉडकास्ट भेजते समय
setPackage(String)के साथ package तय किया जा सकता है. सिस्टम, ब्रॉडकास्ट को उन ऐप्लिकेशन तक सीमित रखता है जो पैकेज से मेल खाते हैं.
किसी रिसीवर को रजिस्टर करने पर, कोई भी ऐप्लिकेशन आपके ऐप्लिकेशन के रिसीवर को संभावित रूप से नुकसान पहुंचाने वाले ब्रॉडकास्ट भेज सकता है. आपके ऐप्लिकेशन को मिलने वाले ब्रॉडकास्ट को सीमित करने के कई तरीके हैं:
- ब्रॉडकास्ट रिसीवर रजिस्टर करते समय, अनुमति दी जा सकती है.
- मेनिफ़ेस्ट में बताए गए रिसीवर के लिए, मेनिफ़ेस्ट में android:exported एट्रिब्यूट को "false" पर सेट किया जा सकता है. ब्रॉडकास्ट पाने वाले व्यक्ति को, ऐप्लिकेशन के बाहर के सोर्स से ब्रॉडकास्ट नहीं मिलते.
ब्रॉडकास्ट की जाने वाली कार्रवाइयों के लिए नेमस्पेस ग्लोबल होता है. पक्का करें कि कार्रवाई के नाम और अन्य स्ट्रिंग, आपके मालिकाना हक वाले नेमस्पेस में लिखी गई हों. ऐसा न करने पर, हो सकता है कि आपका ऐप्लिकेशन अन्य ऐप्लिकेशन के साथ काम न करे.
क्योंकि रिसीवर का
onReceive(Context, Intent)तरीका, मुख्य थ्रेड पर चलता है, इसलिए इसे तुरंत लागू होना चाहिए और तुरंत जवाब देना चाहिए. अगर आपको लंबे समय तक काम करना है, तो थ्रेड शुरू करने या बैकग्राउंड सेवाओं को शुरू करने के बारे में सावधान रहें. ऐसा इसलिए, क्योंकिonReceive()के वापस आने के बाद सिस्टम पूरी प्रोसेस को बंद कर सकता है. ज़्यादा जानकारी के लिए, प्रोसेस की स्थिति पर असर देखें. लंबे समय तक चलने वाले काम को पूरा करने के लिए, हमारा सुझाव है कि:- पाने वाले के
onReceive()तरीके मेंgoAsync()को कॉल करना औरBroadcastReceiver.PendingResultको बैकग्राउंड थ्रेड में पास करना. इससेonReceive()से वापस आने के बाद भी ब्रॉडकास्ट चालू रहता है. हालांकि, इस तरीके से भी सिस्टम को उम्मीद होती है कि आप ब्रॉडकास्ट को बहुत कम समय (10 सेकंड से कम) में खत्म कर देंगे. इससे आपको काम को किसी दूसरी थ्रेड पर ले जाने की अनुमति मिलती है, ताकि मुख्य थ्रेड में गड़बड़ी न हो. JobSchedulerकी मदद से कोई जॉब शेड्यूल करना. ज़्यादा जानकारी के लिए, इंटेलिजेंट जॉब शेड्यूलिंग देखें.
- पाने वाले के
ब्रॉडकास्ट रिसीवर से गतिविधियां शुरू न करें, क्योंकि इससे उपयोगकर्ता अनुभव खराब होता है. ऐसा तब ज़्यादा होता है, जब एक से ज़्यादा रिसीवर हों. इसके बजाय, सूचना दिखाएं.