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 як більш гнучку та продуктивну альтернативу.
Колбек працює асинхронно: додаток підписується на події через ConnectivityManager, і система викликає методи колбека при зміні стану мережі. Це виключає необхідність періодичного опитування мережевого статусу, економлячи ресурси батареї та процесора.
ConnectivityManager керує всіма мережевими інтерфейсами пристрою — Wi-Fi, мобільними даними, Ethernet, VPN. При зміні будь-якого з цих інтерфейсів система формує об'єкт Network і передає його у відповідний метод зареєстрованого колбека. Кожен Network має унікальний ідентифікатор, який змінюється при перепідключенні.
Колбек не прив'язаний до конкретного типу мережі — він може відстежувати всі доступні інтерфейси одночасно. Для фільтрації типів з'єднань використовується клас NetworkRequest, де вказуються необхідні транспортні протоколи (Wi-Fi, стільникові дані, Ethernet) та можливості мережі.
Реєстрація NetworkCallback виконується через метод ConnectivityManager.registerNetworkCallback. Першим параметром передається NetworkRequest.Builder, що описує вимоги до мережі, другим — екземпляр колбека. Для роботи потрібен дозвіл 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 для керування життєвим циклом колбека. У Fragment — onResume та onPause.
Для спрощення керування реєстрацією можна використовувати Lifecycle-сумісні компоненти. Бібліотека AndroidX Lifecycle дозволяє створити власний LifecycleObserver, який автоматично реєструє та скасовує колбек при зміні стану життєвого циклу.
Для фонових завдань реєстрація виконується в 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", "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 на 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", "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. Патерн полягає в обгортці колбека в реактивний стрим, який автоматично сповіщає UI про зміну стану. Наприклад, MutableStateFlow з типом NetworkStatus оновлюється всередині методів колбека, а 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, передавши той самий екземпляр колбека, який використовували при реєстрації. Нескасований колбек може викликати витік пам'яті, оскільки система зберігає посилання на нього. Завжди скасовуйте в 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також