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

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 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 और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन को, registerReceiver(BroadcastReceiver, IntentFilter) का इस्तेमाल करके CONNECTIVITY_ACTION ब्रॉडकास्ट को रजिस्टर करना होगा. मेनिफ़ेस्ट में रिसीवर का एलान करने से काम नहीं चलता.

ब्रॉडकास्ट पाना

ऐप्लिकेशन को ब्रॉडकास्ट दो तरीकों से मिल सकते हैं: कॉन्टेक्स्ट के हिसाब से रजिस्टर किए गए रिसीवर और मेनिफ़ेस्ट में बताए गए रिसीवर के ज़रिए.

कॉन्टेक्स्ट के हिसाब से रजिस्टर किए गए ईमेल पाने वाले लोग

संदर्भ के हिसाब से रजिस्टर किए गए रिसीवर को तब तक ब्रॉडकास्ट मिलते हैं, जब तक उनका रजिस्टर किया गया संदर्भ मान्य होता है. आम तौर पर, यह registerReceiver और unregisterReceiver के बीच होता है. जब सिस्टम उस कॉन्टेक्स्ट को मिटा देता है जिसे रजिस्टर किया जा रहा है, तो रजिस्टर किया जा रहा कॉन्टेक्स्ट भी अमान्य हो जाता है. उदाहरण के लिए, अगर आपने Activity कॉन्टेक्स्ट में रजिस्टर किया है, तो गतिविधि के चालू रहने तक आपको ब्रॉडकास्ट मिलते रहेंगे. ऐप्लिकेशन कॉन्टेक्स्ट के साथ रजिस्टर करने पर, ऐप्लिकेशन के चलने तक आपको ब्रॉडकास्ट मिलते रहेंगे.

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

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

    Groovy

    dependencies {
        def core_version = "1.15.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.0.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-alpha02"
    }

    Kotlin

    dependencies {
        val core_version = "1.15.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.0.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-alpha02")
    }
  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) में, क्योंकि हो सकता है कि 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
}

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

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

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

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

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

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

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

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

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

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