NetworkCallback — абстрактен клас в Android SDK за наблюдение на промени в състоянието на мрежата чрез ConnectivityManager. Според Android Developers Documentation (2025), използването на NetworkCallback позволява на приложението своевременно да реагира на свързване, прекъсване или промяна на характеристиките на връзката. ConnectivityManager.NetworkCallback предоставя подробна информация за типа мрежа, captive портали и загуба на интернет без постоянно запитване на системната услуга.
Основни точки
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 порталите (captive portals) — отделен случай: при свързване към публична Wi-Fi мрежа чрез портал методът onCapabilitiesChanged не показва веднага INTERNET. Първо мрежата е достъпна, но без интернет — изисква се оторизация чрез браузър. Разработчикът трябва да вземе предвид това закъснение в логиката на приложението.
Извиква се, когато системата блокира мрежовия трафик за приложението — например при включване на режим за пестене на данни или ограничаване на фоновите данни. onBlockedStatusChanged позволява на приложението да разбере, че неговите мрежови заявки са временно забранени, и да премине към локална обработка.
Нека разгледаме практическа имплементация на NetworkCallback за проследяване на достъпа до интернет и обработка на captive портали. В примера по-долу е показана проверка на 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_204.
Ако заявката върне код 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", "Открит е captive портал")
}
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, който е маркиран като deprecated в по-новите версии.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също