نظرة عامة على عمليات البث

يمكن لتطبيقات Android إرسال رسائل بث أو تلقّيها من نظام Android وتطبيقات Android الأخرى، على غرار نمط التصميم publish-subscribe. يتم إرسال عمليات البث هذه عند وقوع حدث مهم. على سبيل المثال، يرسل نظام Android عمليات بث عند وقوع أحداث مختلفة للنظام، مثل بدء تشغيل النظام أو بدء شحن الجهاز. يمكن للتطبيقات أيضًا إرسال عمليات بث مخصّصة، مثل إشعار التطبيقات الأخرى بأشياء قد تهمّها (على سبيل المثال، تم تنزيل بعض البيانات الجديدة).

يحسّن النظام إرسال عمليات البث من أجل الحفاظ على الحالة الأمثل للنظام. لذلك، فإن أوقات تسليم عمليات البث ليست مضمونة. على التطبيقات التي تحتاج إلى التواصل البيني للعمليات بوقت استجابة سريع التفكير في الخدمات المرتبطة.

يمكن للتطبيقات التسجيل لتلقّي عمليات بث محدّدة. عند إرسال بث، يوجه النظام عمليات البث تلقائيًا إلى التطبيقات التي اشتركت في تلقّي هذا النوع المعيّن من البث.

بشكل عام، يمكن استخدام عمليات البث كنظام مراسلة في التطبيقات وخارج المسار العادي للمستخدم. ومع ذلك، يجب الحرص على عدم إساءة استخدام فرصة الاستجابة لرسائل البث وتشغيل المهام في الخلفية التي يمكن أن تساهم في بطء أداء النظام.

لمحة عن عمليات بث النظام

يرسل النظام تلقائيًا عمليات البث عند وقوع أحداث مختلفة للنظام، مثلاً عند دخول النظام إلى وضع الطيران وخروجه منه. تُرسَل بثات النظام إلى جميع التطبيقات التي مشترِك فيها لتلقّي الحدث.

تكون رسالة البث نفسها مضمَّنة في كائن Intent تحدِّد سلسلة إجراءاته الحدث الذي وقع (مثلاً android.intent.action.AIRPLANE_MODE). وقد يتضمّن الغرض أيضًا معلومات إضافية مجمّعة في الحقل الإضافي الخاص بها. على سبيل المثال، يتضمن الغرض من وضع الطائرة قيمة إضافية منطقية تشير إلى ما إذا كان "وضع الطيران" مفعَّلاً أم لا.

ولمزيد من المعلومات عن كيفية قراءة الأغراض والحصول على سلسلة الإجراء من سمة intent، يمكنك الاطّلاع على فلاتر الأهداف والغايات.

للحصول على قائمة كاملة بإجراءات بث النظام، يُرجى الاطّلاع على ملف BROADCAST_ACTIONS.TXT في حزمة تطوير البرامج (SDK) لنظام التشغيل Android. يتضمن كل إجراء بث حقلاً ثابتًا مرتبطًا به. على سبيل المثال، قيمة الثابت ACTION_AIRPLANE_MODE_CHANGED هي android.intent.action.AIRPLANE_MODE. تتوفر وثائق لكل إجراء بث في الحقل الثابت المرتبط به.

التغييرات التي تطرأ على عمليات بث النظام

مع تطور نظام Android الأساسي، يغير النظام الأساسي بشكل دوري سلوك عمليات البث. يُرجى الأخذ بعين الاعتبار التغييرات التالية لإتاحة جميع إصدارات Android.

Android 14

عندما تكون التطبيقات في حالة التخزين المؤقت، يتم تحسين إرسال البث للحفاظ على سلامة النظام. على سبيل المثال، يتم تأجيل عمليات بث النظام الأقل أهمية، مثل ACTION_SCREEN_ON، عندما يكون التطبيق في حالة ذاكرة التخزين المؤقت. بمجرد انتقال التطبيق من حالة التخزين المؤقت إلى دورة حياة عملية نشطة، يعرض النظام أي عمليات بث مؤجلة.

إنّ عمليات البث المهمة التي يتم توضيحها في البيان تؤدي إلى إزالة التطبيقات مؤقتًا من حالة التخزين المؤقت لعرضها.

الإصدار 9 من نظام التشغيل Android

بدءًا من نظام التشغيل Android 9 (المستوى 28 من واجهة برمجة التطبيقات)، لا يتلقّى البث NETWORK_STATE_CHANGED_ACTION معلومات عن الموقع الجغرافي للمستخدم أو بيانات تحديد الهوية الشخصية.

بالإضافة إلى ذلك، إذا كان تطبيقك مثبّتًا على جهاز يعمل بالإصدار 9 من نظام التشغيل Android أو إصدار أحدث، لن تتضمّن عمليات بث النظام من شبكة Wi-Fi معرِّفات مجموعة الخدمات الأساسية (SSID) أو معرِّفات مجموعة الخدمات الأساسية (BSSID) أو معلومات الاتصال أو نتائج الفحص. للحصول على هذه المعلومات، اتصل بـ getConnectionInfo() بدلاً من ذلك.

Android 8.0

بدايةً من Android 8.0 (المستوى 26 من واجهة برمجة التطبيقات)، يفرض النظام قيودًا إضافية على أجهزة الاستقبال المضمّنة في البيان.

إذا كان تطبيقك يستهدف الإصدار Android 8.0 أو إصدارًا أحدث، لا يمكنك استخدام ملف البيان لتعريف جهاز استقبال لمعظم عمليات البث الضمنية (أي عمليات البث التي لا تستهدف تطبيقك على وجه التحديد). لا يزال بإمكانك استخدام جهاز استقبال مسجَّل بالسياق عندما يستخدم المستخدم تطبيقك بنشاط.

الإصدار 7.0 من نظام التشغيل Android

لا يُرسِل الإصدار 7.0 من نظام التشغيل Android (المستوى 24 من واجهة برمجة التطبيقات) والإصدارات الأحدث عمليات بث النظام التالية:

ويجب أيضًا على التطبيقات التي تستهدف الإصدار 7.0 من نظام التشغيل Android والإصدارات الأحدث أن تسجّل بث CONNECTIVITY_ACTION باستخدام registerReceiver(BroadcastReceiver, IntentFilter). لا يعمل بيان جهاز الاستقبال في البيان.

استلام رسائل البث

يمكن للتطبيقات تلقّي أحداث البث بطريقتين: من خلال أجهزة الاستقبال المضمّنة في بيان البيان وتلك المسجّلة في السياق.

المُستلِمون الواردون من البيان

إذا أعلنت عن جهاز استقبال بث في البيان، سيفتح النظام تطبيقك (إذا لم يكن قيد التشغيل) عند إرسال البث.

للإعلان عن جهاز استقبال البث في البيان، نفِّذ الخطوات التالية:

  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="APP_SPECIFIC_BROADCAST" />
        </intent-filter>
    </receiver>
    

    تحدد فلاتر الأهداف إجراءات البث التي يشترك فيها المستلِم.

  2. الفئة الفرعية BroadcastReceiver وتنفيذ onReceive(Context, Intent). يسجل جهاز استقبال البث في الأمثلة التالية محتويات البث ويعرض محتوياتها:

    Kotlin

    private const val TAG = "MyBroadcastReceiver"
    
    class MyBroadcastReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            StringBuilder().apply {
                append("Action: ${intent.action}\n")
                append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
                toString().also { log ->
                    Log.d(TAG, log)
    
                    val binding = ActivityNameBinding.inflate(layoutInflater)
                    val view = binding.root
                    setContentView(view)
    
                    Snackbar.make(view, log, Snackbar.LENGTH_LONG).show()
                }
            }
        }
    }
    

    Java

    public class MyBroadcastReceiver extends BroadcastReceiver {
            private static final String TAG = "MyBroadcastReceiver";
            @Override
            public void onReceive(Context context, Intent intent) {
                StringBuilder sb = new StringBuilder();
                sb.append("Action: " + intent.getAction() + "\n");
                sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                String log = sb.toString();
                Log.d(TAG, log);
    
                ActivityNameBinding binding =
                        ActivityNameBinding.inflate(layoutInflater);
                val view = binding.root;
                setContentView(view);
    
                Snackbar.make(view, log, Snackbar.LENGTH_LONG).show();
            }
        }
    

    لتفعيل ربط العرض، يجب ضبط viewمنصّات الربط في ملف Builder.gradle على مستوى الوحدة.

يسجِّل مدير حزم النظام المتلقي عند تثبيت التطبيق. يصبح جهاز الاستقبال بعد ذلك نقطة دخول منفصلة إلى تطبيقك، ما يعني أن بإمكان النظام بدء التطبيق وإرسال البث في حال عدم تشغيل التطبيق حاليًا.

ينشئ النظام كائنًا جديدًا من مكونات BroadcastReceiver لمعالجة كل بث يتلقاه. هذا الكائن صالح فقط طوال مدة استدعاء onReceive(Context, Intent). بمجرد إرجاع التعليمة البرمجية من هذه الطريقة، يعتبر النظام المكون لم يعد نشطًا.

المستلِمون المسجَّلون بالسياق

يتلقى المُستلِمون المسجَّلون في السياق عمليات البث طالما أنّ سياق التسجيل لديهم صحيح. على سبيل المثال، إذا سجّلت المحتوى ضمن Activity سياق، ستتلقّى عمليات بث طالما لم يتم إتلاف النشاط. إذا سجّلت في سياق التطبيق، ستتلقّى عمليات البث طالما أنّ التطبيق قيد التشغيل.

لتسجيل جهاز استقبال مع سياق، نفذ الخطوات التالية:

  1. في ملف الإصدار على مستوى الوحدة في تطبيقك، ضمِّن الإصدار 1.9.0 أو الإصدارات الأحدث من مكتبة AndroidX Core:

    رائع

    dependencies {
        def core_version = "1.13.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-rc01"
        // To test the Animator APIs
        androidTestImplementation "androidx.core:core-animation-testing:1.0.0-rc01"
    
        // 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-beta02"
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation "androidx.core:core-splashscreen:1.2.0-alpha01"
    }
    

    Kotlin

    dependencies {
        val core_version = "1.13.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-rc01")
        // To test the Animator APIs
        androidTestImplementation("androidx.core:core-animation-testing:1.0.0-rc01")
    
        // 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-beta02")
    
        // Optional - APIs for SplashScreen, including compatibility helpers on devices prior Android 12
        implementation("androidx.core:core-splashscreen:1.2.0-alpha01")
    }
    
  2. إنشاء مثيل لـ BroadcastReceiver:

    Kotlin

    val br: BroadcastReceiver = MyBroadcastReceiver()
    

    Java

    BroadcastReceiver br = new MyBroadcastReceiver();
    
  3. إنشاء مثيل لـ IntentFilter:

    Kotlin

    val filter = IntentFilter(APP_SPECIFIC_BROADCAST)
    

    Java

    IntentFilter filter = new IntentFilter(APP_SPECIFIC_BROADCAST);
    
  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;
    if (listenToBroadcastsFromOtherApps) {
        receiverFlags = ContextCompat.RECEIVER_EXPORTED;
    } else {
        receiverFlags = ContextCompat.RECEIVER_NOT_EXPORTED;
    }
    
  5. سجِّل المستلِم عبر الاتصال بـ registerReceiver():

    Kotlin

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

    Java

    ContextCompat.registerReceiver(context, br, filter, receiverFlags);
    
  6. لإيقاف تلقّي عمليات البث، اتصل برقم unregisterReceiver(android.content.BroadcastReceiver). احرص على إلغاء تسجيل المُستلِم في حال لم تعُد بحاجة إليه أو إذا لم يعُد السياق صالحًا.

    يُرجى الانتباه إلى المكان الذي تُسجِّل فيه المُستلِم وتلغي تسجيله. على سبيل المثال، إذا سجّلت مستلِمًا في onCreate(Bundle) باستخدام سياق النشاط، عليك إلغاء تسجيله في onDestroy() لمنع تسريب المُستلِم خارج سياق النشاط. إذا سجّلت جهاز استقبال في onResume()، يجب إلغاء تسجيله في onPause() لمنع تسجيله عدة مرات (إذا كنت لا تريد تلقّي عمليات البث عند إيقاف البث مؤقتًا، يمكن أن يؤدي ذلك إلى تقليل أعباء النظام غير الضرورية). لا تلغِ التسجيل في onSaveInstanceState(Bundle)، لأنّ هذا الإجراء لا يتم استدعاؤه إذا عاد المستخدم إلى حزمة السجلّ.

التأثيرات على حالة العملية

ويؤثر ما إذا كان BroadcastReceiver يعمل أو لا يؤثر في العملية المضمَّنة، ما قد يغيّر احتمالية إتلاف النظام. وتنفِّذ العملية التي تعمل في المقدّمة طريقة onReceive() للمستلِم. ويجري النظام العملية إلا في حال الضغط الشديد على الذاكرة.

يتم إيقاف BroadcastReceivedr بعد onReceive(). لا تقل أهمية عملية المضيف للمستلم عن أهمية مكونات التطبيق. إذا كانت هذه العملية تستضيف مستقبِلًا معرَّفًا في البيان فقط (وهو حدث متكرّر في التطبيقات التي لم يتفاعل معها المستخدم مطلقًا أو لم يتفاعل معها مؤخرًا)، قد يوقفها النظام بعد onReceive() لإتاحة الموارد للعمليات الأخرى الأكثر أهمية.

وبالتالي، يجب ألا تبدأ أجهزة استقبال البث تشغيل سلاسل محادثات في الخلفية طويلة المدى. ويمكن للنظام إيقاف العملية في أي وقت بعد onReceive() لاسترداد الذاكرة، ما يؤدي إلى إنهاء سلسلة المحادثات التي تم إنشاؤها. للحفاظ على سير العملية، حدِّد موعدًا JobService من جهاز الاستقبال باستخدام JobScheduler حتى يعرف النظام أنّ العملية لا تزال تعمل. توفّر نظرة عامة على العمل في الخلفية المزيد من التفاصيل.

إرسال رسائل البث

يوفر Android ثلاث طرق يمكن للتطبيقات من خلالها إرسال البث:

  • ترسل الطريقة sendOrderedBroadcast(Intent, String) رسائل البث إلى جهاز استقبال واحد في كل مرة. وعندما ينفّذ كل جهاز استقبال بدوره يمكنه نشر النتيجة إلى المتلقّي التالي أو يمكنه إلغاء البث تمامًا حتى لا يتم تمريره إلى مستلِمين آخرين. يمكن التحكّم في الترتيب الذي يشغّله مستلمو الاستقبال باستخدام السمة android:priority لفلتر intent للمطابقة. سيتم تنفيذ أجهزة الاستقبال التي لها الأولوية نفسها بترتيب عشوائي.
  • ترسل الطريقة sendBroadcast(Intent) البثات إلى جميع أجهزة الاستقبال بترتيب غير محدّد. ويُعرف هذا الإجراء بالبث العادي. يُعد هذا الإجراء أكثر فاعلية، ولكنه يعني أن أجهزة الاستقبال لا يمكنها قراءة النتائج الواردة من أجهزة استقبال أخرى أو نشر البيانات الواردة من البث أو إلغاء عملية البث.

يوضح مقتطف الرمز التالي كيفية إرسال بث من خلال إنشاء Intent واستدعاء sendBroadcast(Intent).

Kotlin

Intent().also { intent ->
    intent.setAction("com.example.broadcast.MY_NOTIFICATION")
    intent.putExtra("data", "Nothing to see here, move along.")
    sendBroadcast(intent)
}

Java

Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data", "Nothing to see here, move along.");
sendBroadcast(intent);

يتم تضمين رسالة البث في عنصر Intent. يجب أن توفر سلسلة إجراء الغرض بنية اسم حزمة Java للتطبيق وأن تحدِّد حدث البث بشكل فريد. يمكنك إرفاق معلومات إضافية بالغرض باستخدام السمة putExtra(String, Bundle). يمكنك أيضًا حصر عملية البث بمجموعة من التطبيقات في المؤسسة نفسها من خلال استخدام ميزة "setPackage(String)" على جهاز intent.

فرض قيود على عمليات البث من خلال الأذونات

تتيح لك الأذونات حصر عمليات البث على مجموعة من التطبيقات التي تمتلك أذونات معيّنة. يمكنك فرض قيود على مرسل البث أو مستلمه.

الإرسال باستخدام الأذونات

عند طلب الرمز sendBroadcast(Intent, String) أو sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)، يمكنك تحديد مَعلمة إذن. يمكن فقط للمستلمين الذين طلبوا هذا الإذن من خلال علامة في البيان (وبالتالي منحهم الإذن إذا كان خطيرًا) تلقّي البث. على سبيل المثال، يرسل الرمز التالي بثًا:

Kotlin

sendBroadcast(Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

Java

sendBroadcast(new Intent(BluetoothDevice.ACTION_FOUND),
              Manifest.permission.BLUETOOTH_CONNECT)

لاستقبال البث، يجب أن يطلب التطبيق المُستلِم الإذن كما هو موضّح أدناه:

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

يمكنك تحديد إذن نظام حالي، مثل BLUETOOTH_CONNECT أو تحديد إذن مخصّص باستخدام العنصر <permission>. للحصول على معلومات حول الأذونات والأمان بشكل عام، يمكنك الاطّلاع على أذونات النظام.

الاستلام بأذونات

إذا حددت مَعلمة إذن عند تسجيل جهاز استقبال البث (إما باستخدام علامة registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) أو في علامة <receiver> في البيان)، حينئذٍ فقط شركات البث التي طلبت الإذن من خلال علامة <uses-permission> في ملف البيان (وبعد ذلك تم منحها الإذن إذا كان الخطر خطيرًا) يمكنها إرسال Intent إلى المُستلِم.

على سبيل المثال، لنفترض أنّ تطبيق المستلِم يحتوي على جهاز استقبال معرَّف في البيان كما هو موضّح أدناه:

<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.BLUETOOTH_CONNECT">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_FOUND"/>
    </intent-filter>
</receiver>

أو يحتوي تطبيقك المستلِم على مستلِم مسجَّل حسب السياق كما هو موضّح أدناه:

Kotlin

var filter = IntentFilter(Intent.ACTION_FOUND)
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null )

Java

IntentFilter filter = new IntentFilter(Intent.ACTION_FOUND);
registerReceiver(receiver, filter, Manifest.permission.BLUETOOTH_CONNECT, null );

لتتمكن بعد ذلك من إرسال رسائل بث إلى أجهزة الاستقبال هؤلاء، يجب أن يطلب تطبيق الإرسال الإذن كما هو موضح أدناه:

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

اعتبارات الأمان وأفضل الممارسات

في ما يلي بعض الاعتبارات الأمنية وأفضل الممارسات لإرسال مجموعات البث واستلامها:

  • إذا تم تسجيل العديد من التطبيقات لتلقي البث نفسه في بيانها، يمكن أن يتسبب ذلك في تشغيل الكثير من التطبيقات في النظام، ما ينتج عنه تأثير كبير في أداء الجهاز وتجربة المستخدم. ولتجنّب ذلك، ننصحك باستخدام تسجيل السياق بدلاً من تعريف البيان. في بعض الأحيان، يفرض نظام Android نفسه استخدام المستلمين المسجَّلين استنادًا إلى سياقهم. على سبيل المثال، لا يتم إرسال بث CONNECTIVITY_ACTION إلا إلى أجهزة الاستقبال المسجّلة السياق.

  • يجب عدم بث معلومات حسّاسة لغرض ضمني. يمكن لأي تطبيق يُسجّل لتلقّي البثّ على قراءة المعلومات. هناك ثلاث طرق للتحكم في الأشخاص الذين يمكنهم تلقّي أحداث البثّ:

    • يمكنك تحديد إذن عند إرسال بث.
    • في Android 4.0 والإصدارات الأحدث، يمكنك تحديد حزمة مع setPackage(String) عند إرسال بث. يقصر النظام البث على مجموعة التطبيقات التي تطابق الحزمة.
  • عند تسجيل جهاز استقبال، يمكن لأي تطبيق إرسال إعلانات بث من المحتمل أن تكون ضارة إلى مستقبِل التطبيق. هناك عدّة طرق للحدّ من عمليات البث التي يتلقّاها تطبيقك:

    • يمكنك تحديد إذن عند تسجيل جهاز استقبال بث.
    • بالنسبة إلى المستلمين المحدَّدين في البيان، يمكنك ضبط السمة android:exported على "false" في البيان. لا يستقبل المُستلِم البث من مصادر خارج التطبيق.
  • مساحة الاسم لإجراءات البث عامة. تأكَّد من كتابة أسماء الإجراءات والسلاسل الأخرى في مساحة اسم تملكها، وإلا قد تتعارض عن غير قصد مع تطبيقات أخرى.

  • بما أنّ طريقة onReceive(Context, Intent) للمستلِم تعمل على سلسلة التعليمات الرئيسية، من المفترض أن يتم تنفيذها والعودة بسرعة. إذا كنت بحاجة إلى تنفيذ عمل طويل الأمد، عليك توخي الحذر بشأن إنشاء سلاسل المحادثات أو بدء الخدمات التي تعمل في الخلفية لأنّ النظام قد يوقف العملية بأكملها بعد إرجاع onReceive(). لمزيد من المعلومات، يُرجى الاطّلاع على التأثير على حالة العملية لإجراء عمل طويل الأمد، ننصحك بما يلي:

    • يتم الاتصال بـ goAsync() بطريقة onReceive() للمُستلِم وتمرير BroadcastReceiver.PendingResult إلى سلسلة محادثات في الخلفية. يؤدي ذلك إلى إبقاء البث نشطًا بعد العودة من onReceive(). ومع ذلك، حتى مع هذا النهج، يتوقّع النظام منك إنهاء البث بسرعة كبيرة (أقل من 10 ثوانٍ). وهو يسمح لك بنقل العمل إلى سلسلة محادثات أخرى لتجنب خلل سلسلة التعليمات الرئيسية.
    • تحديد موعد للمهمة من خلال "JobScheduler" لمزيد من المعلومات، يُرجى الاطّلاع على جدولة الوظائف الذكية.
  • لا تبدأ الأنشطة من أجهزة استقبال البث لأن تجربة المستخدم مزعجة، خاصةً إذا كان هناك أكثر من جهاز استقبال واحد. يمكنك بدلاً من ذلك عرض إشعار.