ترسل تطبيقات Android رسائل البث وتتلقّاها من نظام Android وتطبيقات Android الأخرى، على غرار نمط تصميم النشر والاشتراك. يرسل النظام والتطبيقات عادةً عمليات البث عند وقوع أحداث معيّنة. على سبيل المثال، يرسل نظام Android عمليات البث عند وقوع أحداث مختلفة في النظام، مثل بدء تشغيل النظام أو شحن الجهاز. ترسل التطبيقات أيضًا عمليات بث مخصّصة، مثلاً لإشعار التطبيقات الأخرى بشيء قد يهمّها (مثل تنزيل بيانات جديدة).
يمكن للتطبيقات التسجيل لتلقّي عمليات بث معيّنة. عند إرسال عملية بث، يوجّه النظام تلقائيًا عمليات البث إلى التطبيقات التي اشتركت في تلقّي هذا النوع تحديدًا من عمليات البث.
بوجه عام، يمكن استخدام عمليات البث كنظام مراسلة بين التطبيقات وخارج مسار المستخدم العادي. ومع ذلك، يجب توخي الحذر من إساءة استخدام فرصة الردّ على عمليات البث وتشغيل المهام في الخلفية، ما قد يساهم في بطء أداء النظام.
لمحة عن عمليات البث من النظام
يرسل النظام عمليات البث تلقائيًا عند وقوع أحداث مختلفة في النظام، مثل تبديل النظام بين "وضع الطائرة" وخارجه. تتلقّى جميع التطبيقات المشترِكة عمليات البث هذه.
يغلّف عنصر Intent الإعلان على جميع الأجهزة. تحدّد السلسلة action الحدث الذي وقع، مثل android.intent.action.AIRPLANE_MODE. قد يتضمّن الغرض أيضًا معلومات إضافية مضمّنة في حقل البيانات الإضافية.
على سبيل المثال، يتضمّن الغرض من "وضع الطائرة" بيانات إضافية منطقية تشير إلى ما إذا كان "وضع الطائرة" مفعّلاً أم لا.
لمزيد من المعلومات حول كيفية قراءة الأغراض والحصول على سلسلة الإجراءات من غرض ، يُرجى الاطّلاع على الأغراض وفلاتر الأغراض.
إجراءات البث من النظام
للاطّلاع على قائمة كاملة بإجراءات البث من النظام، يُرجى الرجوع إلى ملف BROADCAST_ACTIONS.TXT في Android SDK. لكل إجراء بث حقل ثابت مرتبط به. على سبيل المثال، قيمة الثابت
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) أو إصدار أعلى، لا يتضمّن النظام أرقام تعريف مجموعة الخدمات (SSID) أو أرقام تعريف مجموعة الخدمات الأساسية (BSSID) أو معلومات الاتصال أو نتائج الفحص في عمليات بث Wi-Fi. للحصول على هذه المعلومات، يمكنك بدلاً من ذلك استدعاء
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.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") }
يجب إنشاء مثيل من
BroadcastReceiver:Kotlin
val myBroadcastReceiver = MyBroadcastReceiver()Java
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();يجب إنشاء مثيل من
IntentFilter:Kotlin
val filter = IntentFilter("com.example.snippets.ACTION_UPDATE_DATA")Java
IntentFilter filter = new IntentFilter("com.example.snippets.ACTION_UPDATE_DATA");يجب اختيار ما إذا كان يجب تصدير جهاز استقبال البث وجعله مرئيًا للتطبيقات الأخرى على الجهاز. إذا كان جهاز الاستقبال هذا يستمع إلى عمليات البث المُرسَلة من النظام أو من تطبيقات أخرى، حتى التطبيقات الأخرى التي تملكها، استخدِم العلامة
RECEIVER_EXPORTED. إذا كان جهاز الاستقبال هذا يستمع بدلاً من ذلك إلى عمليات البث المُرسَلة من تطبيقك فقط، استخدِم العلامةRECEIVER_NOT_EXPORTED.Kotlin
val listenToBroadcastsFromOtherApps = false val receiverFlags = if (listenToBroadcastsFromOtherApps) { ContextCompat.RECEIVER_EXPORTED } else { ContextCompat.RECEIVER_NOT_EXPORTED }Java
boolean listenToBroadcastsFromOtherApps = false; int receiverFlags = listenToBroadcastsFromOtherApps ? ContextCompat.RECEIVER_EXPORTED : ContextCompat.RECEIVER_NOT_EXPORTED;يجب تسجيل جهاز الاستقبال من خلال استدعاء
registerReceiver():Kotlin
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags)Java
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, receiverFlags);لإيقاف تلقّي عمليات البث، يجب استدعاء
unregisterReceiver(android.content.BroadcastReceiver). يُرجى التأكّد من إلغاء تسجيل جهاز الاستقبال عندما لا يعود مطلوبًا أو عندما يصبح السياق غير صالح.
إلغاء تسجيل جهاز استقبال البث
أثناء تسجيل جهاز استقبال البث، يحتفظ الجهاز بمرجع إلى `Context` الذي تم تسجيله به. قد يؤدي ذلك إلى حدوث تسرّبات إذا كان النطاق المسجَّل لجهاز الاستقبال يتجاوز نطاق دورة حياة `Context`. على سبيل المثال، يمكن أن يحدث ذلك عند تسجيل جهاز استقبال في نطاق `Activity`، ولكن يتم نسيان إلغاء تسجيله عندما يدمّر النظام `Activity`. لذلك، يجب دائمًا إلغاء تسجيل جهاز استقبال البث.
Kotlin
class MyActivity : ComponentActivity() {
private val myBroadcastReceiver = MyBroadcastReceiver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags)
setContent { MyApp() }
}
override fun onDestroy() {
super.onDestroy()
// When you forget to unregister your receiver here, you're causing a leak!
this.unregisterReceiver(myBroadcastReceiver)
}
}
Java
class MyActivity extends ComponentActivity {
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
ContextCompat.registerReceiver(this, myBroadcastReceiver, filter, receiverFlags);
// Set content
}
}
تسجيل أجهزة الاستقبال في أصغر نطاق
يجب تسجيل جهاز استقبال البث فقط عندما تكون مهتمًا بالنتيجة فعليًا. يجب اختيار أصغر نطاق ممكن لجهاز الاستقبال:
LifecycleResumeEffectأو طرق دورة حياةonResume/onPauseفي النشاط: لا يتلقّى جهاز استقبال البث التحديثات إلا عندما يكون التطبيق في حالة الاستئناف.LifecycleStartEffectأو طرق دورة حياةonStart/onStopفي النشاط: لا يتلقّى جهاز استقبال البث التحديثات إلا عندما يكون التطبيق في حالة الاستئناف.DisposableEffect: لا يتلقّى مستقبِل البث التحديثات إلا عندما تكون الدالة المركّبة في شجرة التركيب. لا يرتبط هذا النطاق بنطاق مراحل النشاط. يُرجى تسجيل جهاز الاستقبال في سياق التطبيق. وذلك لأنّه من الناحية النظرية، يمكن أن تعيش الدالة المركّبة خارج نطاق مراحل النشاط وتؤدي إلى تسرّب النشاط.onCreate/onDestroyفي النشاط: يتلقّى جهاز استقبال البث التحديثات عندما يكون النشاط في حالة الإنشاء. يُرجى التأكّد من إلغاء التسجيل فيonDestroy()وليسonSaveInstanceState(Bundle)لأنّه قد لا يتم استدعاء هذا الإجراء.- نطاق مخصّص: على سبيل المثال، يمكنك تسجيل جهاز استقبال في نطاق
ViewModel، ما يجعله يبقى بعد إعادة إنشاء النشاط. يُرجى التأكّد من استخدام سياق التطبيق لتسجيل جهاز الاستقبال، لأنّ جهاز الاستقبال يمكن أن يعيش خارج نطاق دورة حياة النشاط ويؤدي إلى تسرّب النشاط.
إنشاء دالة مركّبة مع حالة ودالة مركّبة بدون حالة
تتضمّن Compose عناصر قابلة للإنشاء مع حالة وأخرى بدون حالة. يؤدي تسجيل مستقبِل البث أو إلغاء تسجيله داخل دالة مركّبة إلى جعله مع حالة. العنصر القابل للإنشاء ليس دالة حتمية تعرض المحتوى نفسه عند تمرير المعلمات نفسها. يمكن أن تتغيّر الحالة الداخلية استنادًا إلى استدعاءات جهاز استقبال البث المسجَّل.
كإحدى أفضل الممارسات في Compose، ننصحك بتقسيم العناصر القابلة للإنشاء إلى إصدارات مع حالة وأخرى بدون حالة. لذلك، ننصحك برفع عملية إنشاء جهاز استقبال البث خارج عنصر `Composable` لجعله بدون حالة:
@Composable
fun MyStatefulScreen() {
val myBroadcastReceiver = remember { MyBroadcastReceiver() }
val context = LocalContext.current
LifecycleStartEffect(true) {
// ...
ContextCompat.registerReceiver(context, myBroadcastReceiver, filter, flags)
onStopOrDispose { context.unregisterReceiver(myBroadcastReceiver) }
}
MyStatelessScreen()
}
@Composable
fun MyStatelessScreen() {
// Implement your screen
}
أجهزة الاستقبال التي تم الإعلان عنها في البيان
إذا تم الإعلان عن مستقبِل البث في البيان، سيشغّل النظام تطبيقك عند إرسال رسالة البث. إذا لم يكن التطبيق قيد التشغيل، سيشغّله النظام.
للإعلان عن جهاز استقبال البث في البيان، يُرجى اتّباع الخطوات التالية:
يجب تحديد العنصر
<receiver>في بيان تطبيقك.<!-- If this receiver listens for broadcasts sent from the system or from other apps, even other apps that you own, set android:exported to "true". --> <receiver android:name=".MyBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.example.snippets.ACTION_UPDATE_DATA" /> </intent-filter> </receiver>تحدّد فلاتر الأغراض إجراءات البث التي يشترك فيها جهاز الاستقبال.
يجب إنشاء فئة فرعية من
BroadcastReceiverوتنفيذonReceive(Context, Intent). يسجّل جهاز استقبال البث في المثال التالي محتويات البث ويعرضها:Kotlin
class MyBroadcastReceiver : BroadcastReceiver() { @Inject lateinit var dataRepository: DataRepository override fun onReceive(context: Context, intent: Intent) { if (intent.action == "com.example.snippets.ACTION_UPDATE_DATA") { val data = intent.getStringExtra("com.example.snippets.DATA") ?: "No data" // Do something with the data, for example send it to a data repository: dataRepository.updateData(data) } } }Java
public static class MyBroadcastReceiver extends BroadcastReceiver { @Inject DataRepository dataRepository; @Override public void onReceive(Context context, Intent intent) { if (Objects.equals(intent.getAction(), "com.example.snippets.ACTION_UPDATE_DATA")) { String data = intent.getStringExtra("com.example.snippets.DATA"); // Do something with the data, for example send it to a data repository: if (data != null) { dataRepository.updateData(data); } } } }
يسجّل مدير حِزم النظام جهاز الاستقبال عند تثبيت التطبيق. بعد ذلك، يصبح جهاز الاستقبال نقطة دخول منفصلة إلى تطبيقك، ما يعني أنّه يمكن للنظام بدء تشغيل التطبيق وتسليم عملية البث إذا لم يكن التطبيق قيد التشغيل.
ينشئ النظام عنصرًا جديدًا من مكوّن BroadcastReceiver للتعامل مع
كل عملية بث يتلقّاها. لا يكون هذا العنصر صالحًا إلا خلال مدة
استدعاء onReceive(Context, Intent). بعد أن يعرض الرمز البرمجي النتيجة من هذه الطريقة، يعتبر النظام أنّ المكوّن لم يعُد نشطًا.
التأثيرات في حالة العملية
يؤثر ما إذا كان BroadcastReceiver قيد التشغيل أم لا في العملية التي يتضمّنها
، ما قد يؤدي إلى تغيير احتمالية إيقاف النظام لها. تنّفذ عملية تعمل في المقدّمة
طريقة onReceive() لجهاز الاستقبال. يشغّل النظام العملية إلا في حال حدوث ضغط شديد على الذاكرة.
يوقف النظام BroadcastReceiver بعد onReceive().
تعتمد أهمية عملية المضيف لجهاز الاستقبال على مكوّنات التطبيق. إذا كانت هذه العملية تستضيف جهاز استقبال تم الإعلان عنه في البيان فقط، قد يوقفها النظام بعد onReceive() لتحرير الموارد لعمليات أخرى أكثر أهمية. ويحدث ذلك عادةً للتطبيقات التي لم يتفاعل معها المستخدم مطلقًا أو لم يتفاعل معها مؤخرًا.
لذلك، يجب ألا تبدأ أجهزة استقبال البث سلاسل تعليمات طويلة الأمد في الخلفية.
يمكن للنظام إيقاف العملية في أي لحظة بعد onReceive() لاستعادة الذاكرة، ما يؤدي إلى إنهاء سلسلة التعليمات التي تم إنشاؤها. لإبقاء العملية نشطة، يجب جدولة
JobService من جهاز الاستقبال باستخدام JobScheduler حتى يعرف
النظام أنّ العملية لا تزال قيد التشغيل. تقدّم نظرة عامة على العمل في الخلفية
مزيدًا من التفاصيل.
إرسال عمليات البث
توفّر منصة Android طريقتَين للتطبيقات لإرسال عمليات البث:
- ترسل الطريقة
sendOrderedBroadcast(Intent, String)عمليات البث إلى جهاز استقبال واحد في كل مرة. أثناء تنفيذ كل جهاز استقبال بدوره، يمكنه نشر نتيجة إلى جهاز الاستقبال التالي. يمكنه أيضًا إيقاف عملية البث تمامًا حتى لا تصل إلى أجهزة الاستقبال الأخرى. يمكنك التحكّم في ترتيب تشغيل أجهزة الاستقبال ضمن عملية التطبيق نفسها. لإجراء ذلك، استخدِم السمةandroid:priorityلفلتر الغرض المطابق. يتم تشغيل أجهزة الاستقبال التي لها الأولوية نفسها بترتيب عشوائي. - ترسل الطريقة
sendBroadcast(Intent)عمليات البث إلى جميع أجهزة الاستقبال بترتيب غير محدّد. ويُطلق على ذلك "عملية بث عادية". تكون هذه الطريقة أكثر فعالية، ولكنها تعني أنّه لا يمكن لأجهزة الاستقبال قراءة النتائج من أجهزة استقبال أخرى أو نشر البيانات الواردة من عملية البث أو إيقاف عملية البث.
يوضّح مقتطف الرمز التالي كيفية إرسال عملية بث من خلال إنشاء
Intent واستدعاء sendBroadcast(Intent).
Kotlin
val intent = Intent("com.example.snippets.ACTION_UPDATE_DATA").apply {
putExtra("com.example.snippets.DATA", newData)
setPackage("com.example.snippets")
}
context.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.snippets.ACTION_UPDATE_DATA");
intent.putExtra("com.example.snippets.DATA", newData);
intent.setPackage("com.example.snippets");
context.sendBroadcast(intent);
يتم تغليف الإعلان على جميع الأجهزة في عنصر Intent. يجب أن توفّر سلسلة action للغرض بنية اسم حزمة Java للتطبيق وتحدّد بشكل فريد حدث البث. يمكن إرفاق معلومات إضافية بالغرض باستخدام putExtra(String, Bundle). يمكن أيضًا حصر عملية البث في
مجموعة من التطبيقات في المؤسسة نفسها من خلال استدعاء setPackage(String) على
الغرض.
حظر عمليات البث باستخدام الأذونات
تسمح لك الأذونات بحصر عمليات البث في مجموعة التطبيقات التي تملك أذونات معيّنة. يمكن فرض قيود على مُرسِل عملية البث أو جهاز الاستقبال.
إرسال عمليات البث باستخدام الأذونات
عند استدعاء sendBroadcast(Intent, String) أو
sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String,
Bundle)
، يمكنك تحديد مَعلمة إذن. لا يمكن لجهاز الاستقبال تلقّي عملية البث إلا إذا طلب هذا
الإذن باستخدام العلامة <uses-permission> في البيان. إذا كان الإذن خطيرًا، يجب منحه قبل أن يتمكّن جهاز الاستقبال من تلقّي عملية البث. على سبيل المثال، يرسل الرمز التالي عملية بث باستخدام إذن:
Kotlin
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION)
Java
context.sendBroadcast(intent, android.Manifest.permission.ACCESS_COARSE_LOCATION);
لتلقّي عملية البث، يجب أن يطلب التطبيق المستلِم الإذن على النحو التالي:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
يمكنك تحديد إذن حالي من النظام، مثل
BLUETOOTH_CONNECT، أو تحديد إذن مخصّص باستخدام العنصر
<permission>. للحصول على معلومات حول الأذونات والأمان بشكل عام، يُرجى الاطّلاع على أذونات النظام.
تلقّي عمليات البث باستخدام الأذونات
إذا تم تحديد مَعلمة إذن عند تسجيل جهاز استقبال البث
(إما باستخدام
registerReceiver(BroadcastReceiver, IntentFilter, String, Handler) أو في
<receiver> العلامة في البيان)، لا يمكن للمُرسِلين الذين
طلبوا الإذن باستخدام الـ <uses-permission> العلامة في
البيان إرسال `Intent` إلى جهاز الاستقبال. إذا كان الإذن خطيرًا، يجب أيضًا منح المُرسِل الإذن.
على سبيل المثال، لنفترض أنّ تطبيق الاستقبال يتضمّن جهاز استقبال تم الإعلان عنه في البيان على النحو التالي:
<!-- 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إلا إلى أجهزة الاستقبال المسجَّلة في السياق.يُرجى عدم بث معلومات حساسة باستخدام implicit intent. يمكن لأي تطبيق قراءة المعلومات إذا سجّل لتلقّي عملية البث. هناك ثلاث طرق للتحكّم في مَن يمكنه تلقّي عمليات البث:
- يمكن تحديد إذن عند إرسال عملية بث.
- في Android 4.0 (مستوى واجهة برمجة التطبيقات 14) والإصدارات الأحدث، يمكن تحديد حزمة باستخدام
setPackage(String)عند إرسال عملية بث. يحصر النظام عملية البث في مجموعة التطبيقات التي تطابق الحزمة.
عند تسجيل جهاز استقبال، يمكن لأي تطبيق إرسال عمليات بث قد تكون ضارة إلى جهاز استقبال تطبيقك. هناك عدة طرق للحدّ من عمليات البث التي يتلقّاها تطبيقك:
- يمكن تحديد إذن عند تسجيل جهاز استقبال البث.
- بالنسبة إلى أجهزة الاستقبال التي تم الإعلان عنها في البيان، يمكن ضبط السمة android:exported على "false" في البيان. لا يتلقّى جهاز الاستقبال عمليات البث من مصادر خارج التطبيق.
مساحة الاسم لإجراءات البث هي مساحة اسم عالمية. يُرجى التأكّد من كتابة أسماء الإجراءات والسلاسل الأخرى في مساحة اسم تملكها. وإلا، قد يحدث تعارض عن غير قصد مع تطبيقات أخرى.
بما أنّ طريقة
onReceive(Context, Intent)لجهاز الاستقبال تعمل على سلسلة التعليمات الرئيسية، يجب أن يتم تنفيذها وعرض النتيجة بسرعة. إذا كان عليك تنفيذ عمل طويل الأمد، يجب توخي الحذر بشأن إنشاء سلاسل تعليمات أو بدء تشغيل خدمات في الخلفية لأنّه يمكن للنظام إيقاف العملية بأكملها بعد عرض النتيجة منonReceive(). لمزيد من المعلومات، يُرجى الاطّلاع على التأثيرات في حالة العملية لتنفيذ عمل طويل الأمد، ننصح بما يلي:- استدعاء
goAsync()في طريقةonReceive()لجهاز الاستقبال وتمريرBroadcastReceiver.PendingResultإلى سلسلة تعليمات في الخلفية. يؤدي ذلك إلى إبقاء عملية البث نشطة بعد عرض النتيجة منonReceive(). ومع ذلك، حتى مع هذا النهج، يتوقّع النظام أن يتم الانتهاء من عملية البث بسرعة كبيرة (في أقل من 10 ثوانٍ). يسمح لك ذلك بنقل العمل إلى سلسلة تعليمات أخرى لتجنُّب حدوث خلل في سلسلة التعليمات الرئيسية. - جدولة مهمة باستخدام
JobScheduler. لمزيد من المعلومات، يُرجى الاطّلاع على جدولة المهام الذكية.
- استدعاء
يُرجى عدم بدء الأنشطة من أجهزة استقبال البث لأنّ تجربة المستخدم تكون غير سلسة، خاصةً إذا كان هناك أكثر من جهاز استقبال. بدلاً من ذلك، يمكنك عرض إشعار.