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 را فراخوانی میکند. این کار نیاز به پرس و جوی دورهای (polling) وضعیت شبکه را از بین میبرد و در مصرف باتری و پردازنده صرفهجویی میکند.
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", "موجود: ${network}")
}
override fun onLost(network: Network) {
Log.d("Network", "از دست رفت: ${network}")
}
}
fun register() {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(), callback
)
}
fun unregister() {
connectivityManager.unregisterNetworkCallback(callback)
}
}
توصیه میشود NetworkCallback را زمانی که برنامه در پیشزمینه است ثبت کنید و هنگام رفتن به پسزمینه لغو کنید. در Activity استفاده از onStart و onStop برای مدیریت چرخه حیات callback راحت است. در Fragment — onResume و onPause.
برای سادهسازی مدیریت ثبت میتوان از کامپوننتهای Lifecycle-aware استفاده کرد. کتابخانه 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 — عدم رومینگ. همچنین میتوان تأخیر سیگنال و پهنای باند را فهمید.
پورتالهای اسیر (captive portals) — مورد جداگانه: هنگام اتصال به شبکه 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", "داده همراه متصل شد")
hasInternet ->
Log.d("Network", "Wi-Fi متصل شد")
else ->
Log.d("Network", "دسترسی به اینترنت وجود ندارد")
}
}
override fun onLost(network: Network) {
Log.d("Network", "اتصال از دست رفت: ${network}")
// توقف درخواستهای شبکه
}
}
هنگام اتصال به شبکه عمومی با احراز هویت (کافه، فرودگاه)، سیستم ابتدا onAvailable را گزارش میکند، اما onCapabilitiesChanged ممکن است INTERNET را نشان ندهد. در چنین مواردی بررسی اضافی از طریق درخواست HTTP به یک endpoint پایدار، مثلاً https://www.google.com/generate_308، لازم است.
اگر درخواست کد 204 را برگرداند — اینترنت وجود دارد. اگر تغییر مسیر (301, 302, 307) — احراز هویت از طریق مرورگر لازم است. در این صورت میتوان WebView یا Intent را به URL تغییر مسیر برای احراز هویت در پورتال باز کرد.
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", "اینترنت در دسترس است")
in HttpURLConnection.HTTP_MOVED_PERM
..HttpURLConnection.HTTP_TEMP_REDIRECT ->
Log.d("Network", "پورتال اسیر شناسایی شد")
}
connection.disconnect()
} catch (e: Exception) {
Log.e("Network", "اعتبارسنجی ناموفق بود: ${e.message}")
}
}
}
پیش از NetworkCallback روش اصلی مانیتورینگ شبکه BroadcastReceiver با فیلتر android.net.conn.CONNECTIVITY_CHANGE بود. این رویکرد معایب قابل توجهی داشت: تأخیر چند ثانیهای، عدم اطلاعات درباره نوع رابط، مصرف انرژی بالا به دلیل بیدار شدن مداوم دستگاه.
جایگزین مدرن — LiveData یا StateFlow در ترکیب با NetworkCallback. الگو شامل پیچیدن callback در یک جریان واکنشی است که به طور خودکار UI را از تغییر وضعیت مطلع میکند. مثلاً 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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید