Broadcast Receiver هو مكون Android يستمع ويعالج رسائل البث النظامية، مثل تغيرات حالة الشبكة، مستوى البطارية، استلام SMS أو تثبيت التطبيقات. يقوم نظام التشغيل بتشغيله عند حدوث حدث وينفذ مهمته في الخيط الرئيسي أو عبر خدمة خلفية. وفقاً لـ Android Developer Guide, 2026، Broadcast Receiver يسمح للتطبيق بالتفاعل مع أحداث النظام العامة حتى عندما لا يكون قيد التشغيل، مما يجعله آلية رئيسية لمعالجة الأحداث في الخلفية في نظام Android البيئي.
النقاط الرئيسية
Broadcast Receiver هو مكون Android مصمم لاستقبال ومعالجة رسائل Intent الموزعة من قبل نظام التشغيل أو التطبيقات الأخرى. على عكس Activity و Service، ليس لدى Broadcast Receiver واجهة مستخدم — مهمته تنفيذ إجراء قصير عند حدوث حدث.
يعمل Broadcast Receiver من خلال آلية Intent. يرسل النظام أو التطبيق Intent عبر sendBroadcast أو sendOrderedBroadcast، ويقوم نظام التشغيل بتسليمه إلى المستقبلات المسجلة. يستقبل كل مستقبل Intent في طريقة onReceive، التي يتم تنفيذها في الخيط الرئيسي.
وفقاً لـ Android Compatibility Definition Document، يجب على Broadcast Receiver إكمال onReceive في غضون 10 ثوانٍ — وإلا يعتبره النظام معلقاً وينهي العملية. للمهام الخلفية الطويلة، استخدم JobScheduler أو WorkManager المُشغل من المستقبل.
يدعم Android نوعين رئيسيين من البث: Normal Broadcast و Ordered Broadcast. الفرق يكمن في ترتيب التسليم والقدرة على مقاطعة سلسلة المعالجة. بالإضافة إلى ذلك، ينقسم البث إلى نظامي (يُولد بواسطة نظام التشغيل) ومخصص (يُُنشأ بواسطة التطبيق).
يتم تسليم Normal Broadcast لجميع المستقبلات المسجلة بشكل غير متزامن بدون ترتيب مضمون. قد يقوم النظام بمعالجة هذه البث بالتوازي — كل مستقبل يحصل على Intent في خيطه الخاص. استدعاء abortBroadcast في Normal Broadcast ليس له تأثير: لا يمكن إلغاء التسليم للمستقبلات الأخرى.
يتم تسليم Ordered Broadcast بالتسلسل — لكل مستقبل بترتيب تنازلي للسمة android:priority (من 0 إلى 999). بعد المعالجة، يمكن للمستقبل تمرير النتيجة إلى التالي عبر setResultExtras أو مقاطعة السلسلة باستدعاء abortBroadcast. يُستخدم هذا في السيناريوهات حيث يهم ترتيب المعالجة — على سبيل المثال، مستقبلات SMS.
يولد Android العديد من بث النظام: ACTION_BOOT_COMPLETED (تشغيل الجهاز)، ACTION_BATTERY_LOW، ACTION_POWER_CONNECTED، CONNECTIVITY_ACTION، ACTION_PACKAGE_ADDED وغيرها. يحتوي كل Intent على بيانات إضافية في Extras — مستوى البطارية، نوع الاتصال، اسم الحزمة.
| نوع البث | الترتيب | abortBroadcast | الأداء |
|---|---|---|---|
| Normal | غير مضمون | لا يعمل | عالي (متوازي) |
| Ordered | حسب الأولوية | يعمل | متوسط (تسلسلي) |
| Sticky | قيمة واحدة | غير قابل للتطبيق | منخفض (مهمل منذ API 21) |
Sticky Broadcast هو نوع مهمل كان يحتفظ بآخر قيمة مرسلة. بدلاً من ذلك، استخدم LiveData أو StateFlow أو SharedPreferences مشتركة لتخزين الحالة الأخيرة.
يمكن تسجيل Broadcast Receiver بطريقتين: ثابتاً عبر AndroidManifest.xml أو ديناميكياً في الكود عبر registerReceiver. يعتمد الاختيار على السيناريو: التسجيل الثابت يعمل حتى عندما لا يكون التطبيق قيد التشغيل، التسجيل الديناميكي يعمل فقط طالما أن المكون المسجل نشط.
يُعلن التسجيل الثابت في البيان باستخدام الوسم <receiver> داخل <application>. لكل مستقبل، يتم تحديد فئة المعالج ومرشح Intent مع الإجراءات التي يجب اعتراضها. يقوم النظام بتحميل هذه المستقبلات عند حدوث بث حتى لو كان التطبيق غير قيد التشغيل.
<!-- Static Broadcast Receiver registration in manifest -->
<receiver android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
يتم التسجيل الديناميكي باستخدام طريقة registerReceiver في كود Activity أو Service أو Fragment. يعيش المستقبل فقط طالما أن المكون الذي سجله نشط. اتصل دائماً بـ unregisterReceiver في onPause أو onDestroy — وإلا يحدث تسرب للذاكرة وقد ينهي النظام العملية.
بالنسبة لـ Ordered Broadcast، يتم تحديد ترتيب التسليم بواسطة السمة android:priority. المستقبل ذو الأولوية الأعلى يحصل على Intent أولاً. إذا استدعى abortBroadcast بعد المعالجة، فإن المستقبلات ذات الأولوية الأقل لن تستقبل Intent. للمستقبلات الثابتة، يتم تعيين الأولوية في مرشح Intent في البيان.
يمكن للمستقبلات في Ordered Broadcast تمرير البيانات إلى التالي في السلسلة عبر setResultExtras أو setResultData. هذا يسمح بمعالجة خط أنابيب: المستقبل الأول يثري Intent ببيانات إضافية، الثاني يستخدمها، الثالث يكمل السلسلة. طريقة getResultExtras تقرأ البيانات التي مررها المستقبل السابق.
بالنسبة لـ Normal Broadcast، الترتيب غير مضمون، لذلك جميع المستقبلات تحصل على Intent الأصلي دون تغيير. إذا كنت بحاجة إلى تأثير المستقبلات على بعضها البعض، استخدم sendOrderedBroadcast بدلاً من sendBroadcast.
قدم Android 8 (API 26, Oreo) قيوداً كبيرة على البث في الخلفية. معظم البث الضمني — تلك غير الموجهة لتطبيق معين — لم تعد تعمل مع التسجيل الثابت. يقوم النظام بحظر المستقبلات المسجلة في البيان لإجراءات مثل CONNECTIVITY_ACTION أو ACTION_BATTERY_LOW.
حدد Google قائمة من البث التي لا تزال تعمل مع التسجيل الثابت: BOOT_COMPLETED و TIME_TICK و Alarm وتغييرات الحزمة — حوالي عشر استثناءات إجمالاً. جميع البث الضمني الأخرى تتطلب الآن تسجيلاً ديناميكياً عبر Context.registerReceiver، الذي يعمل فقط عندما يكون التطبيق في المقدمة.
للمهام الخلفية التي كانت تُعالج سابقاً عبر Broadcast Receiver، يوصي Android بـ WorkManager (مهام مؤجلة مع ضمان التنفيذ)، JobScheduler (مهام دورية مع مراعاة حالة الجهاز) و NotificationListenerService (مراقبة الإشعارات). تعمل هذه المكونات بدون قيود Android 8 ومحسنة لاستهلاك الطاقة.
لنقم بإنشاء Broadcast Receiver لتتبع اتصال الشبكة. سيلتقط المستقبل بث CONNECTIVITY_ACTION ويسجل نوع الاتصال. بالنسبة لـ Android 8+، سنقوم بتسجيله ديناميكياً لأنه بث ضمني مستبعد من التسجيل الثابت.
// Broadcast Receiver لتتبع حالة الشبكة
class NetworkReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = cm.activeNetwork
val caps = cm.getNetworkCapabilities(network)
val connectionType = when {
caps?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> "WiFi"
caps?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "Cellular"
else -> "Disconnected"
}
Log.d("NetworkReceiver", "نوع الاتصال: $connectionType")
}
}
// التسجيل الديناميكي في Activity
class MainActivity : AppCompatActivity() {
private val networkReceiver = NetworkReceiver()
override fun onStart() {
super.onStart()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
registerReceiver(networkReceiver, filter)
}
override fun onStop() {
super.onStop()
unregisterReceiver(networkReceiver)
}
}
قم دائماً بإلغاء تسجيل المستقبل في onStop — إذا انتقلت Activity إلى الخلفية ولكن بقي المستقبل مسجلاً، لا يمكن للنظام تحرير الموارد. بالنسبة لـ Service، استخدم onDestroy. في الأجزاء (fragments)، سجل المستقبل في onStart وألغِ التسجيل في onStop، متبعاً دورة حياة الجزء.
الأسئلة الشائعة
Broadcast Receiver هو مكون Android لمعالجة رسائل البث النظامية والمخصصة. يستقبل Intent في طريقة onReceive، التي تعمل في الخيط الرئيسي، ويجب أن تكتمل في غضون 10 ثوانٍ. للمهام الطويلة، استخدم WorkManager أو JobScheduler.
Normal Broadcast يُسلم لجميع المستقبلات بشكل غير متزامن ومتوازي — الترتيب غير مضمون، abortBroadcast لا يعمل. Ordered Broadcast يُسلم بالتسلسل حسب الأولوية، كل مستقبل يمكنه مقاطعة السلسلة أو تمرير البيانات إلى التالي عبر setResultExtras.
التسجيل الثابت (في البيان) يسمح للمستقبل بالعمل حتى عندما لا يكون التطبيق قيد التشغيل. التسجيل الديناميكي (عبر registerReceiver) يعمل فقط طالما أن المكون المسجل نشط. ابتداءً من Android 8، العديد من البث الضمني تتطلب تسجيلاً ديناميكياً.
Android 8 (API 26) منع التسجيل الثابت لمعظم البث الضمني، مثل CONNECTIVITY_ACTION أو ACTION_BATTERY_LOW. الاستثناءات تشمل BOOT_COMPLETED و Alarm والوقت وبعض الأخرى. للمهام الخلفية، استخدم WorkManager بدلاً من Broadcast.
استخدم LiveData أو StateFlow أو EventBus أو LocalBroadcastManager لنقل البيانات من onReceive إلى واجهة المستخدم. لا تحاول تحديث واجهة المستخدم مباشرة من onReceive — إنها تعمل في الخيط الرئيسي، لكن المستقبل لا يضمن أن Activity مرئية. LocalBroadcastManager هو خيار مهمل للاتصال الداخلي.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.