সম্প্রচার ওভারভিউ

অ্যান্ড্রয়েড অ্যাপগুলি অ্যান্ড্রয়েড সিস্টেম এবং অন্যান্য অ্যান্ড্রয়েড অ্যাপ থেকে সম্প্রচার বার্তা পাঠায় এবং গ্রহণ করে, প্রকাশ-সাবস্ক্রাইব ডিজাইন প্যাটার্নের মতো। সিস্টেম এবং অ্যাপগুলি সাধারণত কিছু ঘটনা ঘটলে সম্প্রচার পাঠায়। উদাহরণস্বরূপ, সিস্টেম বুট বা ডিভাইস চার্জিং এর মতো বিভিন্ন সিস্টেম ইভেন্ট ঘটলে Android সিস্টেম সম্প্রচার পাঠায়। অ্যাপগুলি কাস্টম সম্প্রচারও পাঠায়, উদাহরণস্বরূপ, অন্য অ্যাপগুলিকে তাদের আগ্রহ থাকতে পারে এমন কিছু সম্পর্কে অবহিত করতে (উদাহরণস্বরূপ, নতুন ডেটা ডাউনলোড)।

অ্যাপগুলি নির্দিষ্ট সম্প্রচার পেতে নিবন্ধন করতে পারে। যখন একটি সম্প্রচার পাঠানো হয়, সিস্টেম স্বয়ংক্রিয়ভাবে সেই বিশেষ ধরনের সম্প্রচার পাওয়ার জন্য সদস্যতা নেওয়া অ্যাপগুলিতে সম্প্রচার রুট করে।

সাধারণভাবে বলতে গেলে, অ্যাপ্লিকেশানগুলিতে এবং সাধারণ ব্যবহারকারী প্রবাহের বাইরে সম্প্রচারগুলি একটি বার্তাপ্রেরণ সিস্টেম হিসাবে ব্যবহার করা যেতে পারে। যাইহোক, আপনাকে অবশ্যই সতর্কতা অবলম্বন করতে হবে যে সম্প্রচারে প্রতিক্রিয়া জানানোর সুযোগের অপব্যবহার না করা এবং ব্যাকগ্রাউন্ডে কাজ চালানো যা ধীরগতির সিস্টেমের কর্মক্ষমতাতে অবদান রাখতে পারে।

সিস্টেম সম্প্রচার সম্পর্কে

সিস্টেম স্বয়ংক্রিয়ভাবে সম্প্রচার পাঠায় যখন বিভিন্ন সিস্টেম ইভেন্ট ঘটে, যেমন যখন সিস্টেম এয়ারপ্লেন মোডের মধ্যে এবং বাইরে চলে যায়। সমস্ত সাবস্ক্রাইব করা অ্যাপ এই সম্প্রচার গ্রহণ করে।

Intent বস্তু সম্প্রচার বার্তা মোড়ক. action স্ট্রিংটি ঘটে যাওয়া ইভেন্টটিকে চিহ্নিত করে, যেমন android.intent.action.AIRPLANE_MODE । অভিপ্রায় এছাড়াও অতিরিক্ত তথ্য অন্তর্ভুক্ত হতে পারে তার অতিরিক্ত ক্ষেত্রে বান্ডিল. উদাহরণস্বরূপ, এয়ারপ্লেন মোড অভিপ্রায় একটি বুলিয়ান অতিরিক্ত অন্তর্ভুক্ত করে যা নির্দেশ করে যে বিমান মোড চালু আছে কিনা।

কীভাবে ইন্টেন্টগুলি পড়তে হয় এবং একটি অভিপ্রায় থেকে অ্যাকশন স্ট্রিং পেতে হয় সে সম্পর্কে আরও তথ্যের জন্য, ইন্টেন্ট এবং ইনটেন্ট ফিল্টারগুলি দেখুন।

সিস্টেম সম্প্রচার কর্ম

সিস্টেম সম্প্রচার ক্রিয়াগুলির একটি সম্পূর্ণ তালিকার জন্য, Android SDK-এ BROADCAST_ACTIONS.TXT ফাইলটি দেখুন৷ প্রতিটি সম্প্রচার কর্মের সাথে একটি ধ্রুবক ক্ষেত্র যুক্ত থাকে। উদাহরণস্বরূপ, ধ্রুবক ACTION_AIRPLANE_MODE_CHANGED এর মান হল android.intent.action.AIRPLANE_MODE । প্রতিটি সম্প্রচার কর্মের জন্য ডকুমেন্টেশন তার সংশ্লিষ্ট ধ্রুবক ক্ষেত্রে উপলব্ধ।

সিস্টেম সম্প্রচারে পরিবর্তন

অ্যান্ড্রয়েড প্ল্যাটফর্ম বিকশিত হওয়ার সাথে সাথে এটি পর্যায়ক্রমে সিস্টেম সম্প্রচারের আচরণ পরিবর্তন করে। Android এর সমস্ত সংস্করণ সমর্থন করার জন্য নিম্নলিখিত পরিবর্তনগুলি মনে রাখবেন৷

অ্যান্ড্রয়েড 14

অ্যাপ্লিকেশানগুলি একটি ক্যাশে অবস্থায় থাকা অবস্থায়, সিস্টেমটি সিস্টেমের স্বাস্থ্যের জন্য সম্প্রচার বিতরণকে অপ্টিমাইজ করে৷ উদাহরণস্বরূপ, অ্যাপটি ক্যাশে থাকা অবস্থায় সিস্টেমটি কম গুরুত্বপূর্ণ সিস্টেম সম্প্রচার যেমন ACTION_SCREEN_ON স্থগিত করে। একবার অ্যাপটি ক্যাশ করা অবস্থা থেকে একটি সক্রিয় প্রক্রিয়া লাইফসাইকেলে চলে গেলে, সিস্টেমটি যেকোনো বিলম্বিত সম্প্রচার সরবরাহ করে।

ম্যানিফেস্টে ঘোষিত গুরুত্বপূর্ণ সম্প্রচারগুলি অস্থায়ীভাবে ডেলিভারির জন্য ক্যাশে করা অবস্থা থেকে অ্যাপগুলিকে সরিয়ে দেয়৷

অ্যান্ড্রয়েড 9

Android 9 (API স্তর 28) দিয়ে শুরু করে, NETWORK_STATE_CHANGED_ACTION সম্প্রচার ব্যবহারকারীর অবস্থান বা ব্যক্তিগতভাবে শনাক্তযোগ্য ডেটা সম্পর্কে তথ্য পায় না।

আপনার অ্যাপ যদি Android 9.0 (API লেভেল 28) বা উচ্চতর চলমান কোনো ডিভাইসে ইনস্টল করা থাকে, তাহলে সিস্টেমে SSID, BSSID, সংযোগের তথ্য, বা Wi-Fi সম্প্রচারে স্ক্যান ফলাফল অন্তর্ভুক্ত থাকে না। এই তথ্য পেতে, পরিবর্তে getConnectionInfo() কল করুন।

অ্যান্ড্রয়েড 8.0

অ্যান্ড্রয়েড 8.0 (API স্তর 26) দিয়ে শুরু করে, সিস্টেমটি ম্যানিফেস্ট-ঘোষিত রিসিভারের উপর অতিরিক্ত বিধিনিষেধ আরোপ করে।

যদি আপনার অ্যাপ্লিকেশানটি Android 8.0 বা উচ্চতরকে লক্ষ্য করে, আপনি সর্বাধিক অন্তর্নিহিত সম্প্রচারের জন্য একটি রিসিভার ঘোষণা করতে ম্যানিফেস্ট ব্যবহার করতে পারবেন না (সম্প্রচার যেগুলি আপনার অ্যাপকে বিশেষভাবে লক্ষ্য করে না)৷ ব্যবহারকারী যখন সক্রিয়ভাবে আপনার অ্যাপ ব্যবহার করছেন তখনও আপনি একটি প্রসঙ্গ-নিবন্ধিত রিসিভার ব্যবহার করতে পারেন।

অ্যান্ড্রয়েড 7.0

Android 7.0 (API স্তর 24) এবং উচ্চতর নিম্নলিখিত সিস্টেম সম্প্রচার পাঠায় না:

এছাড়াও, অ্যান্ড্রয়েড 7.0 এবং উচ্চতরকে লক্ষ্য করে এমন অ্যাপগুলিকে অবশ্যই CONNECTIVITY_ACTION সম্প্রচারটি registerReceiver(BroadcastReceiver, IntentFilter) ব্যবহার করে নিবন্ধন করতে হবে৷ ম্যানিফেস্টে রিসিভার ঘোষণা করা কাজ করে না।

সম্প্রচার গ্রহণ

অ্যাপ দুটি উপায়ে সম্প্রচার গ্রহণ করতে পারে: প্রসঙ্গ-নিবন্ধিত রিসিভার এবং ম্যানিফেস্ট-ঘোষিত রিসিভারের মাধ্যমে।

প্রসঙ্গ-নিবন্ধিত রিসিভার

প্রসঙ্গ-নিবন্ধিত রিসিভাররা সম্প্রচার গ্রহণ করে যতক্ষণ না তাদের নিবন্ধনের প্রসঙ্গ বৈধ থাকে। এটি সাধারণত registerReceiver এবং unregisterReceiver কলগুলির মধ্যে হয়। যখন সিস্টেম সংশ্লিষ্ট প্রসঙ্গটি ধ্বংস করে তখন নিবন্ধন প্রসঙ্গটিও অবৈধ হয়ে যায়। উদাহরণ স্বরূপ, আপনি যদি কোনো Activity প্রেক্ষাপটের মধ্যে নিবন্ধন করেন, যতক্ষণ পর্যন্ত অ্যাক্টিভিটি সক্রিয় থাকে ততক্ষণ আপনি সম্প্রচার পাবেন। আপনি যদি অ্যাপ্লিকেশন প্রসঙ্গে নিবন্ধন করেন, আপনি যতক্ষণ পর্যন্ত অ্যাপটি চলবে ততক্ষণ আপনি সম্প্রচার পাবেন।

একটি প্রসঙ্গ সহ একটি রিসিভার নিবন্ধন করতে, নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করুন:

  1. আপনার অ্যাপের মডিউল-স্তরের বিল্ড ফাইলে, AndroidX কোর লাইব্রেরির 1.9.0 বা উচ্চতর সংস্করণ অন্তর্ভুক্ত করুন:

    গ্রোভি

    dependencies {
        def core_version = "1.13.1"
    
        // 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"
    }

    কোটলিন

    dependencies {
        val core_version = "1.13.1"
    
        // 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 এর একটি উদাহরণ তৈরি করুন:

    কোটলিন

    val myBroadcastReceiver = MyBroadcastReceiver()
    

    জাভা

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    
  3. IntentFilter এর একটি উদাহরণ তৈরি করুন:

    কোটলিন

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

    জাভা

    IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");
    
  4. ব্রডকাস্ট রিসিভার রপ্তানি করা উচিত এবং ডিভাইসের অন্যান্য অ্যাপে দৃশ্যমান হবে কিনা তা বেছে নিন। যদি এই রিসিভারটি সিস্টেম থেকে বা অন্য অ্যাপ থেকে পাঠানো সম্প্রচার শুনতে থাকে-এমনকি আপনার মালিকানাধীন অন্যান্য অ্যাপও- RECEIVER_EXPORTED পতাকা ব্যবহার করুন। পরিবর্তে যদি এই রিসিভার শুধুমাত্র আপনার অ্যাপের মাধ্যমে পাঠানো সম্প্রচারের জন্য শুনছে, তাহলে RECEIVER_NOT_EXPORTED পতাকা ব্যবহার করুন।

    কোটলিন

    val listenToBroadcastsFromOtherApps = false
    val receiverFlags = if (listenToBroadcastsFromOtherApps) {
        ContextCompat.RECEIVER_EXPORTED
    } else {
        ContextCompat.RECEIVER_NOT_EXPORTED
    }
    

    জাভা

    boolean listenToBroadcastsFromOtherApps = false;
    int receiverFlags = listenToBroadcastsFromOtherApps
            ? ContextCompat.RECEIVER_EXPORTED
            : ContextCompat.RECEIVER_NOT_EXPORTED;
    
  5. registerReceiver() কল করে রিসিভার নিবন্ধন করুন:

    কোটলিন

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

    জাভা

    ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);
    
  6. সম্প্রচার গ্রহণ বন্ধ করতে, unregisterReceiver(android.content.BroadcastReceiver) কল করুন। আপনার আর প্রয়োজন না হলে বা প্রসঙ্গটি আর বৈধ না থাকলে রিসিভারটিকে নিবন্ধনমুক্ত করতে ভুলবেন না।

আপনার সম্প্রচার রিসিভার নিবন্ধনমুক্ত করুন

ব্রডকাস্ট রিসিভার নিবন্ধিত থাকাকালীন, এটি আপনার নিবন্ধিত প্রসঙ্গটির একটি রেফারেন্স ধারণ করে৷ রিসিভারের নিবন্ধিত স্কোপ কনটেক্সট লাইফসাইকেল স্কোপ অতিক্রম করলে এটি সম্ভাব্যভাবে ফাঁসের কারণ হতে পারে। উদাহরণস্বরূপ, যখন আপনি একটি অ্যাক্টিভিটি স্কোপে একটি রিসিভার নিবন্ধন করেন তখন এটি ঘটতে পারে, কিন্তু যখন সিস্টেমটি অ্যাক্টিভিটি ধ্বংস করে তখন আপনি এটিকে আনরেজিস্টার করতে ভুলে যান। অতএব, সর্বদা আপনার সম্প্রচার রিসিভার নিবন্ধনমুক্ত করুন.

কোটলিন

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)
    }
}

জাভা

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 স্কোপে একটি রিসিভার নিবন্ধন করতে পারেন, তাই এটি কার্যকলাপ বিনোদন বেঁচে থাকে। রিসিভার নিবন্ধন করার জন্য অ্যাপ্লিকেশন প্রসঙ্গটি ব্যবহার করা নিশ্চিত করুন, কারণ রিসিভার কার্যকলাপের জীবনচক্রের সুযোগের বাইরে থাকতে পারে এবং কার্যকলাপটি ফাঁস করতে পারে।

স্টেটফুল এবং স্টেটলেস কম্পোজেবল তৈরি করুন

কম্পোজে স্টেটফুল এবং স্টেটলেস কম্পোজেবল আছে। একটি কম্পোজেবলের ভিতরে একটি সম্প্রচার রিসিভার নিবন্ধন বা নিবন্ধনমুক্ত করা এটিকে রাষ্ট্রীয় করে তোলে। কম্পোজেবল একটি নির্ধারক ফাংশন নয় যা একই পরামিতি পাস করার সময় একই বিষয়বস্তু রেন্ডার করে। নিবন্ধিত ব্রডকাস্ট রিসিভারে কলের ভিত্তিতে অভ্যন্তরীণ অবস্থা পরিবর্তন হতে পারে।

রচনার সর্বোত্তম অনুশীলন হিসাবে, আমরা সুপারিশ করি যে আপনি আপনার কম্পোজেবলগুলিকে রাষ্ট্রীয় এবং রাষ্ট্রহীন সংস্করণে বিভক্ত করুন৷ অতএব, আমরা সুপারিশ করছি যে আপনি একটি কম্পোজেবল থেকে সম্প্রচার রিসিভার তৈরি করে এটিকে রাষ্ট্রহীন করে তুলতে পারেন:

@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) প্রয়োগ করুন। নিম্নলিখিত উদাহরণে সম্প্রচার রিসিভার লগ করে এবং সম্প্রচারের বিষয়বস্তু প্রদর্শন করে:

    কোটলিন

    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)
            }
        }
    }
    

    জাভা

    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) কল করে।

কোটলিন

val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
    putExtra("com.example.snippets.DATA", newData)
    setPackage("com.example.snippets")
}
context.sendBroadcast(intent)

জাভা

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 স্ট্রিংকে অবশ্যই অ্যাপের জাভা প্যাকেজ নামের সিনট্যাক্স প্রদান করতে হবে এবং সম্প্রচার ইভেন্টটিকে অনন্যভাবে সনাক্ত করতে হবে। আপনি putExtra(String, Bundle) দিয়ে অভিপ্রায়ে অতিরিক্ত তথ্য সংযুক্ত করতে পারেন। আপনি অভিপ্রায় setPackage(String) কল করে একই সংস্থার অ্যাপগুলির একটি সেটে একটি সম্প্রচার সীমাবদ্ধ করতে পারেন।

অনুমতি সহ সম্প্রচার সীমাবদ্ধ করুন

অনুমতিগুলি আপনাকে নির্দিষ্ট অনুমতি ধারণ করে এমন অ্যাপগুলির সেটে সম্প্রচার সীমাবদ্ধ করতে দেয়৷ আপনি একটি সম্প্রচারের প্রেরক বা গ্রহণকারীর উপর বিধিনিষেধ প্রয়োগ করতে পারেন৷

অনুমতি সহ সম্প্রচার পাঠান

আপনি যখন sendBroadcast(Intent, String) অথবা sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) কল করেন, আপনি একটি অনুমতি প্যারামিটার নির্দিষ্ট করতে পারেন। শুধুমাত্র প্রাপক যারা তাদের ম্যানিফেস্টে <uses-permission> ট্যাগ দিয়ে অনুমতির জন্য অনুরোধ করেছেন তারাই সম্প্রচার পেতে পারেন। অনুমতি বিপজ্জনক হলে, প্রাপক সম্প্রচার গ্রহণ করার আগে আপনাকে অবশ্যই অনুমতি দিতে হবে। উদাহরণস্বরূপ, নিম্নলিখিত কোডটি অনুমতি সহ একটি সম্প্রচার পাঠায়:

কোটলিন

context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)

জাভা

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>

অথবা আপনার গ্রহনকারী অ্যাপে নিম্নরূপ একটি প্রসঙ্গ-নিবন্ধিত রিসিভার রয়েছে:

কোটলিন

ContextCompat.registerReceiver(
    context, myBroadcastReceiver, filter,
    android.Manifest.permission.ACCESS_COARSE_LOCATION,
    null, // scheduler that defines thread, null means run on main thread
    receiverFlags
)

জাভা

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" />

নিরাপত্তা বিবেচনা

সম্প্রচার পাঠানো এবং গ্রহণ করার জন্য এখানে কিছু নিরাপত্তা বিবেচ্য বিষয় রয়েছে:

  • যদি অনেকগুলি অ্যাপ তাদের ম্যানিফেস্টে একই সম্প্রচার পাওয়ার জন্য নিবন্ধিত থাকে, তাহলে এটি সিস্টেমটিকে অনেকগুলি অ্যাপ চালু করতে পারে, যা ডিভাইসের কার্যক্ষমতা এবং ব্যবহারকারীর অভিজ্ঞতা উভয়ের উপরই যথেষ্ট প্রভাব ফেলতে পারে। এটি এড়াতে, ম্যানিফেস্ট ঘোষণার চেয়ে প্রসঙ্গ নিবন্ধন ব্যবহার করতে পছন্দ করুন। কখনও কখনও, অ্যান্ড্রয়েড সিস্টেম নিজেই প্রসঙ্গ-নিবন্ধিত রিসিভার ব্যবহার করে। উদাহরণস্বরূপ, CONNECTIVITY_ACTION সম্প্রচারটি শুধুমাত্র প্রসঙ্গ-নিবন্ধিত রিসিভারদের কাছে বিতরণ করা হয়৷

  • অন্তর্নিহিত উদ্দেশ্য ব্যবহার করে সংবেদনশীল তথ্য সম্প্রচার করবেন না। যে কোনো অ্যাপ তথ্য পড়তে পারে যদি এটি সম্প্রচার গ্রহণের জন্য নিবন্ধন করে। কারা আপনার সম্প্রচার গ্রহণ করতে পারে তা নিয়ন্ত্রণ করার তিনটি উপায় রয়েছে:

    • একটি সম্প্রচার পাঠানোর সময় আপনি একটি অনুমতি নির্দিষ্ট করতে পারেন।
    • Android 4.0 (API স্তর 14) এবং উচ্চতর, আপনি একটি সম্প্রচার পাঠানোর সময় setPackage(String) সহ একটি প্যাকেজ নির্দিষ্ট করতে পারেন৷ সিস্টেমটি প্যাকেজের সাথে মেলে এমন অ্যাপের সেটে সম্প্রচারকে সীমাবদ্ধ করে।
  • আপনি যখন একটি রিসিভার নিবন্ধন করেন, তখন যেকোনো অ্যাপ আপনার অ্যাপের রিসিভারে সম্ভাব্য দূষিত সম্প্রচার পাঠাতে পারে। আপনার অ্যাপ প্রাপ্ত সম্প্রচারগুলিকে সীমিত করার বিভিন্ন উপায় রয়েছে:

    • একটি সম্প্রচার রিসিভার নিবন্ধন করার সময় আপনি একটি অনুমতি নির্দিষ্ট করতে পারেন।
    • ম্যানিফেস্ট-ঘোষিত রিসিভারের জন্য, আপনি ম্যানিফেস্টে android:exported বৈশিষ্ট্যটিকে "false"-এ সেট করতে পারেন। রিসিভার অ্যাপের বাইরের উৎস থেকে সম্প্রচার গ্রহণ করে না।
  • সম্প্রচার কর্মের জন্য নামস্থান বিশ্বব্যাপী। কর্মের নাম এবং অন্যান্য স্ট্রিংগুলি আপনার মালিকানাধীন একটি নামস্থানে লেখা আছে তা নিশ্চিত করুন৷ অন্যথায়, আপনি অসাবধানতাবশত অন্যান্য অ্যাপের সাথে বিরোধ করতে পারেন।

  • যেহেতু একটি রিসিভারের onReceive(Context, Intent) পদ্ধতিটি মূল থ্রেডে চলে তাই এটি কার্যকর করা উচিত এবং দ্রুত ফিরে আসা উচিত। আপনার যদি দীর্ঘমেয়াদী কাজ সম্পাদন করতে হয়, তাহলে থ্রেড তৈরি করা বা ব্যাকগ্রাউন্ড পরিষেবা শুরু করার বিষয়ে সতর্ক থাকুন কারণ onReceive() রিটার্নের পরে সিস্টেমটি সম্পূর্ণ প্রক্রিয়াটিকে মেরে ফেলতে পারে। আরও তথ্যের জন্য, প্রসেস স্টেটের উপর প্রভাব দেখুন দীর্ঘ সময় ধরে চলমান কাজ সম্পাদন করতে, আমরা সুপারিশ করি:

    • আপনার রিসিভারের onReceive() পদ্ধতিতে goAsync() কল করা এবং একটি পটভূমি থ্রেডে BroadcastReceiver.PendingResult পাস করা। এটি onReceive() থেকে ফিরে আসার পরে সম্প্রচার সক্রিয় রাখে। যাইহোক, এমনকি এই পদ্ধতির সাথেও সিস্টেম আশা করে যে আপনি খুব দ্রুত সম্প্রচার শেষ করবেন (10 সেকেন্ডের কম)। এটি আপনাকে মূল থ্রেডের সমস্যা এড়াতে অন্য থ্রেডে কাজ সরানোর অনুমতি দেয়।
    • JobScheduler সাথে একটি কাজের সময় নির্ধারণ করা। আরও তথ্যের জন্য, ইন্টেলিজেন্ট জব শিডিউলিং দেখুন।
  • ব্রডকাস্ট রিসিভার থেকে ক্রিয়াকলাপ শুরু করবেন না কারণ ব্যবহারকারীর অভিজ্ঞতা বিরক্তিকর; বিশেষ করে যদি একাধিক রিসিভার থাকে। পরিবর্তে, একটি বিজ্ঞপ্তি প্রদর্শন বিবেচনা করুন৷