NetworkCallback هي فئة مجردة في Android SDK لمراقبة تغييرات حالة الشبكة عبر ConnectivityManager. وفقاً لـ Android Developers Documentation (2025)، يتيح استخدام NetworkCallback لتطبيقك الاستجابة في الوقت المناسب للاتصال أو قطع الاتصال أو تغيير خصائص الاتصال. ConnectivityManager.NetworkCallback يوفر معلومات مفصلة حول نوع الشبكة والبوابات المقيدة وفقدان الإنترنت دون استقصاء مستمر لخدمة النظام.
النقاط الرئيسية
NetworkCallback هي فئة مجردة من حزمة android.net، وهي جزء من Android SDK. وهي مصممة لتلقي الإشعارات حول تغييرات حالة اتصال الشبكة عبر خدمة النظام ConnectivityManager.
قبل NetworkCallback، كان المطورون يستخدمون BroadcastReceiver لتتبع تغييرات الشبكة. كان هذا النهج يتطلب تسجيلاً مستمراً في البيان، ويعمل مع تأخير، ولم يوفر معلومات مفصلة عن خصائص الاتصال. Android 5.0 (API 21) قدم NetworkCallback كبديل أكثر مرونة وأداءً.
يعمل callback بشكل غير متزامن: يشترك التطبيق في الأحداث عبر ConnectivityManager، ويقوم النظام باستدعاء طرق callback عندما تتغير حالة الشبكة. هذا يلغي الحاجة إلى الاستقصاء الدوري لحالة الشبكة، مما يوفر موارد البطارية والمعالج.
ConnectivityManager يدير جميع واجهات الشبكة على الجهاز — Wi-Fi، البيانات المحمولة، Ethernet، VPN. عندما تتغير أي من هذه الواجهات، يقوم النظام بإنشاء كائن Network ويمره إلى الطريقة المقابلة من callback المسجل. كل Network له معرّف فريد يتغير عند إعادة الاتصال.
callback غير مرتبط بنوع شبكة محدد — يمكنه تتبع جميع الواجهات المتاحة في وقت واحد. لتصفية أنواع الاتصال، يتم استخدام فئة NetworkRequest، التي تحدد بروتوكولات النقل المطلوبة (Wi-Fi، البيانات الخلوية، Ethernet) وإمكانيات الشبكة.
يتم تسجيل NetworkCallback عبر طريقة ConnectivityManager.registerNetworkCallback. المعامل الأول هو NetworkRequest.Builder الذي يصف متطلبات الشبكة، والثاني هو مثيل callback. مطلوب الإذن ACCESS_NETWORK_STATE في البيان.
class NetworkMonitor(private val context: Context) {
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
private val callback =
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("Network", "Available: ${network}")
}
override fun onLost(network: Network) {
Log.d("Network", "Lost: ${network}")
}
}
fun register() {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(), callback
)
}
fun unregister() {
connectivityManager.unregisterNetworkCallback(callback)
}
}
يُوصى بتسجيل NetworkCallback عندما يكون التطبيق في المقدمة وإلغاؤه عند الانتقال إلى الخلفية. في Activity، استخدم onStart و onStop لإدارة دورة حياة callback. في Fragment، استخدم onResume و onPause.
لتبسيط إدارة التسجيل، يمكنك استخدام المكونات الحساسة لدورة الحياة. مكتبة AndroidX Lifecycle تسمح بإنشاء LifecycleObserver مخصص يقوم تلقائياً بتسجيل وإلغاء callback عند تغيير حالة دورة الحياة.
للمهام الخلفية، يتم التسجيل في Service أو WorkManager. لاحظ أنه في Android 8+، الخدمات الخلفية لها قيود على التشغيل. WorkManager مع NetworkType هو طريقة أكثر موثوقية لتنفيذ المهام تحت حالة شبكة محددة، حيث يتكامل مع API التوافق ويحترم وضع Doze.
يوفر NetworkCallback مجموعة من الطرق التي تُستدعى عند تغيير حالة الشبكة. ليست كل الطرق بحاجة إلى إعادة تعريف — نفذ فقط تلك التي تحتاجها لمهمة تطبيقك. onAvailable و onLost هما الحد الأدنى المطلوب للمراقبة الأساسية للاتصال.
| الطريقة | متى تُستدعى | المعاملات |
|---|---|---|
| onAvailable | الشبكة متاحة للاستخدام | Network — كائن الشبكة |
| onLost | الشبكة مفقودة أو غير متصلة | Network — كائن الشبكة |
| onCapabilitiesChanged | تغيرت إمكانيات الشبكة | Network, NetworkCapabilities |
| onBlockedStatusChanged | تغيرت حالة الحظر | Network, Boolean |
| onNetworkSuspended | الشبكة معلقة من قبل النظام | Network |
| onNetworkResumed | الشبكة مستأنفة بعد التعليق | Network |
هذه الطريقة هي المفتاح للحصول على معلومات مفصلة عن الشبكة. معامل NetworkCapabilities يحتوي على علامات: NET_CAPABILITY_INTERNET — وجود وصول إلى الإنترنت، NET_CAPABILITY_NOT_METERED — اتصال غير محدود، NET_CAPABILITY_NOT_ROAMING — عدم وجود تجوال. يمكن أيضاً معرفة زمن استجابة الإشارة وعرض النطاق الترددي.
البوابات المقيدة هي حالة خاصة: عند الاتصال بشبكة Wi-Fi عامة عبر بوابة، طريقة onCapabilitiesChanged لا تظهر INTERNET فوراً. الشبكة متاحة في البداية ولكن بدون إنترنت — مطلوب تفويض عبر المتصفح. يحتاج المطورون إلى أخذ هذا التأخير في الاعتبار في منطق التطبيق.
تُستدعى عندما يحجب النظام حركة مرور الشبكة للتطبيق — على سبيل المثال، عند تفعيل وضع توفير البيانات أو تقييد البيانات الخلفية. onBlockedStatusChanged تتيح للتطبيق معرفة أن طلبات الشبكة الخاصة به ممنوعة مؤقتاً والتبديل إلى المعالجة المحلية.
لنلقِ نظرة على تنفيذ عملي لـ NetworkCallback لمراقبة الوصول إلى الإنترنت ومعالجة البوابات المقيدة. المثال أدناه يوضح التحقق من NET_CAPABILITY_INTERNET والتحقق من صحة الاتصال عبر طلب HTTP لخادم Google.
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
caps: NetworkCapabilities
) {
val hasInternet = caps.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET
)
val isMetered = caps.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED
).not()
when {
hasInternet && isMetered ->
Log.d("Network", "Mobile data connected")
hasInternet ->
Log.d("Network", "Wi-Fi connected")
else ->
Log.d("Network", "No internet access")
}
}
override fun onLost(network: Network) {
Log.d("Network", "Connection lost: ${network}")
// إيقاف طلبات الشبكة
}
}
عند الاتصال بشبكة عامة مع تفويض (مقهى، مطار)، النظام يُعلم أولاً بـ onAvailable، لكن onCapabilitiesChanged قد لا تظهر INTERNET. في هذه الحالات، مطلوب تحقق إضافي عبر طلب HTTP إلى نقطة نهاية مستقرة، مثل https://www.google.com/generate_204.
إذا أعاد الطلب الرمز 204 — الإنترنت متاح. إذا كان هناك إعادة توجيه (301, 302, 307) — مطلوب تفويض عبر المتصفح. في هذه الحالة، يمكنك فتح WebView أو Intent مع رابط إعادة التوجيه لإكمال المصادقة على البوابة.
fun Context.validateInternet(network: Network) {
CoroutineScope(Dispatchers.IO).launch {
try {
val url = URL("https://www.google.com/generate_204")
val connection =
network.openConnection(url) as HttpURLConnection
connection.instanceFollowRedirects = false
connection.connect()
when (connection.responseCode) {
HttpURLConnection.HTTP_NO_CONTENT ->
Log.d("Network", "Internet is available")
in HttpURLConnection.HTTP_MOVED_PERM
..HttpURLConnection.HTTP_TEMP_REDIRECT ->
Log.d("Network", "Captive portal detected")
}
connection.disconnect()
} catch (e: Exception) {
Log.e("Network", "Validation failed: ${e.message}")
}
}
}
قبل NetworkCallback، كانت الطريقة الأساسية لمراقبة الشبكة هي BroadcastReceiver مع مرشح android.net.conn.CONNECTIVITY_CHANGE. كان لهذا النهج عيوب كبيرة: تأخير لعدة ثوانٍ، عدم وجود معلومات عن نوع الواجهة، وزيادة استهلاك الطاقة بسبب الاستيقاظ المستمر للجهاز.
البديل الحديث هو LiveData أو StateFlow المقترن بـ NetworkCallback. النمط يتضمن تغليف callback في تيار تفاعلي يُخطر واجهة المستخدم تلقائياً بتغييرات الحالة. على سبيل المثال، MutableStateFlow بنوع NetworkStatus يتم تحديثه داخل طرق callback، و ViewCollector يشترك في التغييرات.
| الطريقة | API Level | زمن الاستجابة | مستوى التفاصيل | استهلاك الطاقة |
|---|---|---|---|---|
| BroadcastReceiver | 1+ | مرتفع | منخفض | مرتفع |
| NetworkCallback | 21+ | منخفض | مرتفع | منخفض |
| ConnectivityManager.getActiveNetwork | 23+ | فوري | متوسط | صفر |
| NWPathMonitor (iOS) | iOS 12+ | منخفض | مرتفع | منخفض |
بدءاً من Android 10، قيود الخلفية أصبحت أكثر صرامة، وقد لا يتم استدعاء NetworkCallback عندما يكون التطبيق في الخلفية. للمهام الحرجة — مثل تحميل البيانات عند توفر الشبكة — استخدم WorkManager مع قيد NetworkType.CONNECTED. WorkManager يضمن تنفيذ المهمة عند استيفاء شروط الشبكة.
في Android 12+، هناك قيود على تسجيل البيان لـ BroadcastReceiver لـ CONNECTIVITY_ACTION. يجب على المطورين الترحيل إلى NetworkCallback أو استخدام WorkManager. سياسة Google Play منذ أغسطس 2022 تتطلب إزالة تسجيل البيان لهذا الإجراء.
الأسئلة الشائعة
BroadcastReceiver مع CONNECTIVITY_CHANGE يوفر فقط حقيقة تغير الشبكة دون تفاصيل وبتأخير يصل إلى عدة ثوانٍ. NetworkCallback يعمل بشكل غير متزامن، يوفر كائن Network ونوع الواجهة وإمكانيات الاتصال ولا يتطلب تسجيل بيان، وهو محظور في Android 12+.
في Android 10+، قيود الخلفية قد تؤخر أو تمنع استدعاء NetworkCallback. للمهام الخلفية، استخدم WorkManager مع قيد NetworkType — يضمن تنفيذ المهمة عند استيفاء الشروط بغض النظر عن وضع توفير الطاقة.
استدعِ طريقة unregisterNetworkCallback في ConnectivityManager، مرراً نفس مثيل callback الذي استخدمته عند التسجيل. قد يتسبب callback غير ملغى في تسرب الذاكرة لأن النظام يحتفظ بمرجع له. قم دائماً بالإلغاء في onStop أو onDestroy.
NetworkCallback متاح بدءاً من API Level 21 (Android 5.0 Lollipop). للأجهزة ذات الإصدارات الأقدم، استخدم BroadcastReceiver أو مكتبات التوافق مثل AndroidX Activity NetworkCallback، التي تغلف API لدعم أوسع.
استخدم ConnectivityManager.getActiveNetwork (API 23+) مع getNetworkCapabilities. الطريقة تعيد الشبكة النشطة الحالية بشكل متزامن، دون الاشتراك في التغييرات. لـ API 21-22، استخدم getActiveNetworkInfo، الذي تم وضع علامة مهملة عليه في الإصدارات الأحدث.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.