ब्रॉडकास्ट की खास जानकारी

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 कॉन्टेक्स्ट में रजिस्टर किया है, तो आपको तब तक ब्रॉडकास्ट मिलते रहेंगे, जब तक गतिविधि चालू रहेगी. अगर आपने ऐप्लिकेशन कॉन्टेक्स्ट के साथ रजिस्टर किया है, तो आपको तब तक ब्रॉडकास्ट मिलते रहेंगे, जब तक ऐप्लिकेशन चलता रहेगा.

किसी कॉन्टेक्स्ट के साथ रिसीवर रजिस्टर करने के लिए, यह तरीका अपनाएं:

  1. अपने ऐप्लिकेशन के मॉड्यूल-लेवल की बिल्ड फ़ाइल में, AndroidX Core लाइब्रेरी का 1.9.0 या इसके बाद का वर्शन शामिल करें: AndroidX Core लाइब्रेरी:

    Groovy

    dependencies {
        def core_version = "1.18.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.18.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")
    }
  2. BroadcastReceiver का इंस्टेंस बनाएं:

    Kotlin

    val myBroadcastReceiver = MyBroadcastReceiver()
    

    Java

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    
  3. IntentFilter का इंस्टेंस बनाएं:

    Kotlin

    val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")
    

    Java

    IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
    
  4. चुनें कि ब्रॉडकास्ट रिसीवर को एक्सपोर्ट किया जाना चाहिए या नहीं. साथ ही, यह भी चुनें कि यह डिवाइस पर मौजूद अन्य ऐप्लिकेशन को दिखना चाहिए या नहीं. अगर यह रिसीवर, सिस्टम या अन्य ऐप्लिकेशन से भेजे गए ब्रॉडकास्ट को सुन रहा है, तो 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;
    
  5. registerReceiver() को कॉल करके, रिसीवर रजिस्टर करें:

    Kotlin

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)
    

    Java

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
    
  6. ब्रॉडकास्ट पाना बंद करने के लिए, कॉल करें 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
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
}

मेनिफ़ेस्ट में बताए गए रिसीवर

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

मेनिफ़ेस्ट में ब्रॉडकास्ट रिसीवर का एलान करने के लिए, यह तरीका अपनाएं:

  1. अपने ऐप्लिकेशन के मेनिफ़ेस्ट में, <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>
    

    इंटेंट फ़िल्टर, उन ब्रॉडकास्ट ऐक्शन की जानकारी देते हैं जिनके लिए आपका रिसीवर सदस्यता लेता है.

  2. 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() के बाद किसी भी समय प्रोसेस को बंद कर सकता है. इससे, बनाई गई थ्रेड खत्म हो जाती है. प्रोसेस को चालू रखने के लिए, रिसीवर से JobService शेड्यूल करें, ताकि JobScheduler सिस्टम को पता चले कि प्रोसेस अब भी काम कर रही है. ज़्यादा जानकारी के लिए, बैकग्राउंड में काम करने की सुविधा की खास जानकारी देखें.

ब्रॉडकास्ट भेजना

Android, ऐप्लिकेशन को ब्रॉडकास्ट भेजने के दो तरीके उपलब्ध कराता है:

  • The sendOrderedBroadcast(Intent, String) तरीका, एक बार में एक रिसीवर को ब्रॉडकास्ट भेजता है. हर रिसीवर बारी-बारी से काम करता है. इसलिए, यह नतीजे को अगले रिसीवर तक पहुंचा सकता है. यह ब्रॉडकास्ट को पूरी तरह से रद्द भी कर सकता है, ताकि यह अन्य रिसीवर तक न पहुंचे. आपके पास एक ही ऐप्लिकेशन प्रोसेस में, रिसीवर के चलने के क्रम को कंट्रोल करने का विकल्प होता है. ऐसा करने के लिए, मैचिंग इंटेंट-फ़िल्टर के android:priority एट्रिब्यूट का इस्तेमाल करें. एक ही प्राथमिकता वाले रिसीवर, किसी भी क्रम में चलते हैं.
  • The sendBroadcast(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> टैग के साथ अनुमति का अनुरोध किया है. अगर अनुमति खतरनाक है, तो ब्रॉडकास्टर को भी अनुमति दी जानी चाहिए.

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

<!-- 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) और इसके बाद के वर्शन में, ब्रॉडकास्ट भेजते समय, a पैकेज को setPackage(String) के साथ तय किया जा सकता है. सिस्टम, ब्रॉडकास्ट को उन ऐप्लिकेशन के सेट तक सीमित करता है जो पैकेज से मैच करते हैं.
  • रिसीवर रजिस्टर करने पर, कोई भी ऐप्लिकेशन आपके ऐप्लिकेशन के रिसीवर को संभावित तौर पर नुकसान पहुंचाने वाले ब्रॉडकास्ट भेज सकता है. आपके ऐप्लिकेशन को मिलने वाले ब्रॉडकास्ट को सीमित करने के कई तरीके हैं:

    • ब्रॉडकास्ट रिसीवर रजिस्टर करते समय, अनुमति तय की जा सकती है.
    • मेनिफ़ेस्ट में बताए गए रिसीवर के लिए, मेनिफ़ेस्ट में android:exported एट्रिब्यूट को "false" पर सेट किया जा सकता है. रिसीवर को ऐप्लिकेशन के बाहर के सोर्स से ब्रॉडकास्ट नहीं मिलते.
  • ब्रॉडकास्ट ऐक्शन के लिए नेमस्पेस ग्लोबल होता है. पक्का करें कि ऐक्शन के नाम और अन्य स्ट्रिंग, आपके मालिकाना हक वाले नेमस्पेस में लिखी गई हों. ऐसा न करने पर, अन्य ऐप्लिकेशन के साथ अनजाने में टकराव हो सकता है.

  • रिसीवर का onReceive(Context, Intent) तरीका, मुख्य थ्रेड पर चलता है. इसलिए, इसे तेज़ी से चलना और वापस आना चाहिए. अगर आपको लंबे समय तक चलने वाला काम करना है, तो थ्रेड स्पॉन करने या बैकग्राउंड में सेवाएं शुरू करने के बारे में सावधानी बरतें, क्योंकि सिस्टम, onReceive() के वापस आने के बाद पूरी प्रोसेस को बंद कर सकता है. ज़्यादा जानकारी के लिए, प्रोसेस की स्थिति पर असर देखें. लंबे समय तक चलने वाला काम करने के लिए, हमारा सुझाव है कि:

    • अपने रिसीवर के onReceive() तरीके में goAsync() को कॉल करें और BroadcastReceiver.PendingResult को बैकग्राउंड थ्रेड में पास करें. इससे, onReceive() से वापस आने के बाद भी ब्रॉडकास्ट चालू रहता है. हालांकि, इस तरीके से भी सिस्टम आपसे ब्रॉडकास्ट को बहुत तेज़ी से (10 सेकंड के अंदर) खत्म करने की उम्मीद करता है. यह आपको मुख्य थ्रेड में गड़बड़ी से बचने के लिए, काम को दूसरी थ्रेड में ले जाने की अनुमति देता है.
    • JobScheduler के साथ जॉब शेड्यूल करना. ज़्यादा जानकारी के लिए, देखें स्मार्ट तरीके से जॉब शेड्यूल करना.
  • ब्रॉडकास्ट रिसीवर से गतिविधियां शुरू न करें, क्योंकि इससे उपयोगकर्ता अनुभव खराब होता है. खास तौर पर, अगर एक से ज़्यादा रिसीवर हों. इसके बजाय, सूचना दिखाने पर विचार करें.