NetworkCallback — abstrakcyjna klasa w Android SDK do monitorowania zmian stanu sieci przez ConnectivityManager. Według Android Developers Documentation (2025), użycie NetworkCallback pozwala aplikacji na szybkie reagowanie na podłączenie, odłączenie lub zmianę charakterystyki połączenia. ConnectivityManager.NetworkCallback dostarcza szczegółowych informacji o typie sieci, portalach captyw i utracie internetu bez ciągłego odpytywania usługi systemowej.
Najważniejsze
NetworkCallback — to abstrakcyjna klasa z pakietu android.net, wchodząca w skład Android SDK. Jest przeznaczona do otrzymywania powiadomień o zmianach stanu połączenia sieciowego przez usługę systemową ConnectivityManager.
Przed pojawieniem się NetworkCallback programiści używali odbiorników rozgłoszeniowych BroadcastReceiver do śledzenia sieci. Takie podejście wymagało stałej rejestracji w manifeście, działało z opóźnieniem i nie dostarczało szczegółowych informacji o charakterystyce połączenia. Android 5.0 (API 21) wprowadził NetworkCallback jako bardziej elastyczną i wydajną alternatywę.
Callback działa asynchronicznie: aplikacja subskrybuje zdarzenia przez ConnectivityManager, a system wywołuje metody callback przy zmianie stanu sieci. Eliminuje to konieczność okresowego odpytywania (polling) stanu sieci, oszczędzając zasoby baterii i procesora.
ConnectivityManager zarządza wszystkimi interfejsami sieciowymi urządzenia — Wi-Fi, danymi mobilnymi, Ethernet, VPN. Przy zmianie dowolnego z tych interfejsów system tworzy obiekt Network i przekazuje go do odpowiedniej metody zarejestrowanego callback. Każdy Network ma unikalny identyfikator, który zmienia się przy ponownym połączeniu.
Callback nie jest przypisany do konkretnego typu sieci — może śledzić wszystkie dostępne interfejsy jednocześnie. Do filtrowania typów połączeń używana jest klasa NetworkRequest, w której określa się wymagane protokoły transportowe (Wi-Fi, dane komórkowe, Ethernet) i możliwości sieci.
Rejestracja NetworkCallback odbywa się przez metodę ConnectivityManager.registerNetworkCallback. Pierwszym parametrem przekazywany jest NetworkRequest.Builder opisujący wymagania dotyczące sieci, drugim — instancja callback. Do działania wymagane jest uprawnienie ACCESS_NETWORK_STATE w manifeście.
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("Sieć", "Dostępna: ${network}")
}
override fun onLost(network: Network) {
Log.d("Sieć", "Utracona: ${network}")
}
}
fun register() {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(), callback
)
}
fun unregister() {
connectivityManager.unregisterNetworkCallback(callback)
}
}
Zaleca się rejestrowanie NetworkCallback w momencie, gdy aplikacja jest na pierwszym planie, i anulowanie przy przejściu w tło. W Activity wygodnie jest użyć onStart i onStop do zarządzania cyklem życia callback. We Fragment — onResume i onPause.
Aby uprościć zarządzanie rejestracją, można użyć komponentów Lifecycle-aware. Biblioteka AndroidX Lifecycle umożliwia utworzenie własnego LifecycleObserver, który automatycznie rejestruje i anuluje callback przy zmianie stanu cyklu życia.
Do zadań w tle rejestracja odbywa się w Service lub WorkManager. Należy pamiętać, że w Android 8+ usługi w tle mają ograniczenia dotyczące uruchamiania. WorkManager z NetworkType — bardziej niezawodny sposób na wykonywanie zadań przy określonym stanie sieci, ponieważ jest zintegrowany z API kompatybilności i uwzględnia tryb Doze.
NetworkCallback udostępnia zestaw metod wywoływanych przy zmianie stanu sieci. Nie wszystkie metody muszą być nadpisywane — wystarczy zaimplementować tylko te, które są potrzebne do konkretnego zadania aplikacji. onAvailable i onLost są minimalnie wymagane do podstawowego monitorowania połączenia.
| Metoda | Kiedy wywoływana | Parametry |
|---|---|---|
| onAvailable | Sieć jest dostępna do użycia | Network — obiekt sieci |
| onLost | Sieć utracona lub odłączona | Network — obiekt sieci |
| onCapabilitiesChanged | Zmieniły się możliwości sieci | Network, NetworkCapabilities |
| onBlockedStatusChanged | Status blokady uległ zmianie | Network, Boolean |
| onNetworkSuspended | Sieć zawieszona przez system | Network |
| onNetworkResumed | Sieć wznowiona po zawieszeniu | Network |
Ta metoda jest kluczowa do uzyskania szczegółowych informacji o sieci. Parametr NetworkCapabilities zawiera flagi: NET_CAPABILITY_INTERNET — dostęp do internetu, NET_CAPABILITY_NOT_METERED — połączenie bez limitu, NET_CAPABILITY_NOT_ROAMING — brak roamingu. Można również sprawdzić opóźnienie sygnału i przepustowość.
Portale captyw (captive portals) — osobny przypadek: przy podłączeniu do publicznej sieci Wi-Fi przez portal metoda onCapabilitiesChanged nie od razu pokazuje INTERNET. Najpierw sieć jest dostępna, ale bez internetu — wymagana jest autoryzacja przez przeglądarkę. Programista musi uwzględnić to opóźnienie w logice aplikacji.
Wywoływana, gdy system blokuje ruch sieciowy dla aplikacji — na przykład przy włączeniu trybu oszczędzania danych lub ograniczeniu danych w tle. onBlockedStatusChanged pozwala aplikacji dowiedzieć się, że jej żądania sieciowe są tymczasowo zabronione, i przełączyć się na lokalne przetwarzanie.
Rozważmy praktyczną implementację NetworkCallback do śledzenia dostępu do internetu i obsługi portali captyw. W przykładzie poniżej pokazano sprawdzanie NET_CAPABILITY_INTERNET i walidację połączenia przez żądanie HTTP do serwera 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("Sieć", "Połączono z danymi mobilnymi")
hasInternet ->
Log.d("Sieć", "Połączono z Wi-Fi")
else ->
Log.d("Sieć", "Brak dostępu do Internetu")
}
}
override fun onLost(network: Network) {
Log.d("Sieć", "Połączenie utracone: ${network}")
// Zatrzymaj żądania sieciowe
}
}
Przy podłączeniu do publicznej sieci z autoryzacją (kawiarnia, lotnisko) system najpierw informuje onAvailable, ale onCapabilitiesChanged może nie pokazywać INTERNET. W takich przypadkach wymagane jest dodatkowe sprawdzenie przez żądanie HTTP do stabilnego endpointu, na przykład https://www.google.com/generate_204.
Jeśli żądanie zwraca kod 204 — internet jest dostępny. Jeśli przekierowanie (301, 302, 307) — wymagana jest autoryzacja przez przeglądarkę. W takim przypadku można otworzyć WebView lub Intent na URL przekierowania w celu przeprowadzenia uwierzytelnienia na portalu.
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("Sieć", "Internet jest dostępny")
in HttpURLConnection.HTTP_MOVED_PERM
..HttpURLConnection.HTTP_TEMP_REDIRECT ->
Log.d("Sieć", "Wykryto portal captyw")
}
connection.disconnect()
} catch (e: Exception) {
Log.e("Sieć", "Walidacja nie powiodła się: ${e.message}")
}
}
}
Przed NetworkCallback głównym sposobem monitorowania sieci był BroadcastReceiver z filtrem android.net.conn.CONNECTIVITY_CHANGE. To podejście miało istotne wady: opóźnienie kilku sekund, brak informacji o typie interfejsu, zwiększone zużycie energii z powodu ciągłego budzenia urządzenia.
Nowoczesna alternatywa — LiveData lub StateFlow w parze z NetworkCallback. Wzorzec polega na opakowaniu callback w reaktywny strumień, który automatycznie powiadamia UI o zmianie stanu. Na przykład MutableStateFlow z typem NetworkStatus jest aktualizowany wewnątrz metod callback, a ViewCollector subskrybuje zmiany.
| Metoda | API Level | Opóźnienie | Szczegółowość | Zużycie energii |
|---|---|---|---|---|
| BroadcastReceiver | 1+ | wysokie | niska | wysokie |
| NetworkCallback | 21+ | niskie | wysoka | niskie |
| ConnectivityManager.getActiveNetwork | 23+ | natychmiastowe | średnia | zerowe |
| NWPathMonitor (iOS) | iOS 12+ | niskie | wysoka | niskie |
Począwszy od Android 10 poziom ograniczeń w tle został zaostrzony i NetworkCallback może nie być wywoływany, gdy aplikacja jest w tle. Do krytycznie ważnych zadań — na przykład ładowania danych po pojawieniu się sieci — używaj WorkManager z ograniczeniem NetworkType.CONNECTED. WorkManager gwarantuje wykonanie zadania przy spełnieniu warunków sieci.
W Android 12+ pojawiło się ograniczenie dotyczące rejestracji w manifeście BroadcastReceiver dla CONNECTIVITY_ACTION. Programiści są zobowiązani do migracji na NetworkCallback lub użycia WorkManager. Polityka Google Play od sierpnia 2022 wymaga usunięcia rejestracji w manifeście dla tej akcji.
Często zadawane pytania
BroadcastReceiver z CONNECTIVITY_CHANGE dostarcza tylko fakt zmiany sieci bez szczegółów i z opóźnieniem do kilku sekund. NetworkCallback działa asynchronicznie, udostępnia obiekt Network, typ interfejsu, możliwości połączenia i nie wymaga rejestracji w manifeście, która jest zabroniona w Android 12+.
W Android 10+ ograniczenia w tle mogą opóźniać lub nie wywoływać NetworkCallback. Do zadań w tle używaj WorkManager z ograniczeniem NetworkType — gwarantuje on wykonanie pracy przy spełnieniu warunków niezależnie od trybu oszczędzania energii.
Wywołaj metodę unregisterNetworkCallback na ConnectivityManager, przekazując tę samą instancję callback, której użyto przy rejestracji. Nieanulowany callback może spowodować wyciek pamięci, ponieważ system przechowuje do niego referencję. Zawsze anuluj w onStop lub onDestroy.
NetworkCallback jest dostępny od API Level 21 (Android 5.0 Lollipop). Dla urządzeń ze starszymi wersjami używaj BroadcastReceiver lub bibliotek kompatybilności, takich jak AndroidX Activity NetworkCallback, które opakowują API dla szerszego wsparcia.
Użyj ConnectivityManager.getActiveNetwork (API 23+) wraz z getNetworkCapabilities. Metoda zwraca bieżącą aktywną sieć synchronicznie, bez subskrypcji zmian. Dla API 21-22 użyj getActiveNetworkInfo, który jest oznaczony jako deprecated w nowszych wersjach.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również