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 захтева ка стабилном ендпоинту, на пример 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", "Каптивни портал откривен")
}
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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође