Odczytywanie stanu sieci

Android umożliwia aplikacjom zapamiętywanie informacji o dynamicznych zmianach w łączności. Użyj następujących klas do śledzenia zmian w połączeniach i reagowania na nie:

  • ConnectivityManager informuje aplikację o stanie łączności w systemie.
  • Klasa Network reprezentuje jedną z funkcji sieci, z którymi urządzenie jest połączone. Za pomocą usługi Network jako klucz do gromadzenia informacji o sieci z ConnectivityManager lub do powiązania gniazd w sieci. Gdy sieć rozłączy się, obiekt Network przestanie być użyteczny. Nawet jeśli później urządzenie ponownie połączy się z tym samym urządzeniem, nowy obiekt Network reprezentuje w nowej sieci.
  • Obiekt LinkProperties zawiera informacje o połączeniu z siecią, takie jak lista DNS serwerów, lokalnych adresów IP i tras sieciowych zainstalowanych dla danej sieci.
  • NetworkCapabilities zawiera informacje o właściwościach sieci, takie jak (Wi-Fi, komórkowe, Bluetooth) i funkcje obsługujące tę sieć. Można na przykład wysłać zapytanie do obiektu, aby sprawdzić, czy sieć jest może wysyłać MMS-y, znajduje się za portalem przechwytującym lub ma pomiar.

Aplikacje zainteresowane natychmiastowym stanem połączenia mogą Wywołaj metody ConnectivityManager, aby dowiedzieć się, jakiego rodzaju jest sieć i dostępności informacji. Metody te przydadzą się podczas debugowania i od czasu do czasu sprawdzaj podsumowanie połączeń dostępnych w danym momencie.

Jednak synchroniczne ConnectivityManager metod nie informuje aplikacji o niczym, co się dzieje po rozmowie, więc nie możesz zmienić interfejsu użytkownika. Nie mogą też dostosować aplikacji zachowanie w zależności od odłączenia sieci lub możliwości sieci .

Połączenie może się w każdej chwili zmienić, a większość aplikacji musi mieć zawsze aktualny i aktualny stan sieci na urządzeniu. Aplikacje mogą zarejestrować wywołanie zwrotne w ConnectivityManager, aby otrzymywać powiadomienia o zmianach, które na których Ci zależy. Dzięki wywołaniu zwrotnemu aplikacja może natychmiast zareagować istotne zmiany w połączeniach bez konieczności uciekania się do kosztownych ankiet które mogą przegapić szybkie aktualizacje.

Korzystanie z NetworkCallback i innych sposobów uzyskiwania informacji o stan połączenia urządzenia nie wymaga żadnych uprawnień. Niektóre sieci wymagają jednak określonych uprawnień. Dla: na przykład mogą istnieć sieci z ograniczeniami niedostępne dla aplikacji. Powiązanie z sieć w tle wymaga uprawnienia CHANGE_NETWORK_STATE. I kilka mogą wymagać określonych uprawnień do uruchomienia. Więcej informacji dokumentację dotyczącą każdej rozmowy.

Uzyskaj natychmiastowy stan

Urządzenie z Androidem może obsługiwać wiele połączeń jednocześnie. Aby uzyskać informacje o bieżącym stanie sieci, najpierw uzyskaj wystąpienie ConnectivityManager:

Kotlin

val connectivityManager = getSystemService(ConnectivityManager::class.java)

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

Następnie użyj tej instancji, aby uzyskać odniesienie do bieżącej sieci domyślnej dla aplikacja:

Kotlin

val currentNetwork = connectivityManager.getActiveNetwork()

Java

Network currentNetwork = connectivityManager.getActiveNetwork();

Dzięki odniesienia do sieci aplikacja może prosić o informacje na jej temat:

Kotlin

val caps = connectivityManager.getNetworkCapabilities(currentNetwork)
val linkProperties = connectivityManager.getLinkProperties(currentNetwork)

Java

NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(currentNetwork);
LinkProperties linkProperties = connectivityManager.getLinkProperties(currentNetwork);

Aby uzyskać dostęp do bardziej przydatnych funkcji, zarejestruj NetworkCallback Więcej informacji o rejestrowaniu wywołań zwrotnych sieci znajdziesz w artykule Odsłuchiwanie zdarzeń sieciowych.

Funkcjonalność sieci i właściwości linku

Obiekty NetworkCapabilities i LinkProperties dostarczają informacji o wszystkie atrybuty sieci, które system zna.

LinkProperties obiekt zna trasy, adresy linków, nazwę interfejsu, informacje o serwerze proxy (jeśli dowolne) i serwery DNS. Wywołaj odpowiednią metodę w obiekcie LinkProperties aby uzyskać potrzebne informacje.

Obiekt NetworkCapabilities zawiera informacje o sieciowych transportach i ich możliwościach.

Transport to abstrakcja ośrodka fizycznego, w którym sieć działalności firmy. Typowe przykłady sieci transportu to Ethernet, Wi-Fi i sieć komórkowa. Mogą to być również sieci VPN oraz sieci Wi-Fi typu peer-to-peer. Na Androidzie sieć może mieć wiele transportów jednocześnie. Przykład sieci VPN działającej zarówno przez Wi-Fi, jak i sieci komórkowe. Sieć VPN ma Transport Wi-Fi, komórkowy i VPN. Aby dowiedzieć się, czy ma określony transport, użyj funkcji NetworkCapabilities.hasTransport(int) ze stałą NetworkCapabilities.TRANSPORT_*.

Zdolność opisuje właściwość sieci. Przykładowe możliwości: MMS, NOT_METERED i INTERNET. Sieć, w której możesz wysyłać MMS-y, i otrzymywać wiadomości przy użyciu usługi przesyłania wiadomości multimedialnych, a także sieć bez tego których nie da się zrobić. Sieć, która obsługuje NOT_METERED, nie nalicza opłat za użytkownika. Aplikacja może sprawdzić odpowiednie możliwości za pomocą NetworkCapabilities.hasCapability(int) ze stałą NetworkCapabilities.NET_CAPABILITY_*.

Najbardziej przydatne stałe NET_CAPABILITY_* to:

  • NET_CAPABILITY_INTERNET: wskazuje, że sieć jest skonfigurowana dostęp do internetu. Chodzi o konfigurację, a nie o rzeczywistość. brak dostępu do serwerów publicznych. Możesz na przykład skonfigurować sieć tak, nie mają dostępu do internetu, ale podlegają portalowi przechwytującego.

    Sieć komórkowa operatora zwykle ma funkcję INTERNET, a w lokalnej sieci Wi-Fi P2P zazwyczaj nie działa. Aby sprawdzić rzeczywiste połączenia, zobacz NET_CAPABILITY_VALIDATED

  • NET_CAPABILITY_NOT_METERED: oznacza, że sieć nie jest objęta pomiarem. Sieć jest jest klasyfikowany jako z pomiarem użycia danych, jeśli użytkownik jest wrażliwy na duże obciążenie połączenia ze względu na koszty finansowe, ograniczenia danych lub wydajność baterii problemów.

  • NET_CAPABILITY_NOT_VPN: wskazuje, że sieć nie jest wirtualną siecią prywatną.

  • NET_CAPABILITY_VALIDATED: wskazuje, że sieć zapewnia rzeczywisty dostęp do publicznego internetu, gdy zostanie zbadane. Sieć za przechwytującą lub w sieci, która nie obsługuje rozpoznawania nazw domen, nie ma tę funkcję. Jest to najbliższa wartość sieci, jaką system może wykryć nawet gdy zweryfikowana sieć może nie mogą podlegać filtrowaniu opartemu na adresie IP lub doświadczyć nagłej utraty z powodu problemów takich jak słaby sygnał.

  • NET_CAPABILITY_CAPTIVE_PORTAL: wskazuje, że sieć ma portal przechwytujący, gdy jest sondowana.

Istnieją też inne możliwości, którymi mogą być zainteresowane bardziej specjalistyczne aplikacje. Aby dowiedzieć się więcej, zapoznaj się z definicjami parametrów w NetworkCapabilities.hasCapability(int)

Możliwości sieci mogą się zmienić w każdej chwili. Gdy system wykryje portalu przechwytującego, wyświetla powiadomienie z prośbą o zalogowanie się użytkownika. Choć w tym roku w toku, sieć ma NET_CAPABILITY_INTERNET i NET_CAPABILITY_CAPTIVE_PORTAL, ale nie Możliwości: NET_CAPABILITY_VALIDATED.

Gdy użytkownik wykona działanie i zaloguje się stronę portalu przechwytującego, urządzenie może uzyskać dostęp do publicznego internetu a sieć uzyska możliwość NET_CAPABILITY_VALIDATED i straci Funkcja NET_CAPABILITY_CAPTIVE_PORTAL.

Transport w sieci również może się dynamicznie zmieniać. Na przykład sieć VPN może się zmienić tak, aby używać szybszej sieci, na przykład z mobilnej na Wi-Fi ze swoją bazową siecią. W tym przypadku sieć traci TRANSPORT_CELLULAR transportuje i pozyskuje transport TRANSPORT_WIFI, zachowując jednocześnie Transport: TRANSPORT_VPN.

Nasłuchuj zdarzeń sieciowych

Aby dowiedzieć się więcej o zdarzeniach sieciowych, skorzystaj z NetworkCallback zajęcia razem z ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback) oraz ConnectivityManager.registerNetworkCallback(NetworkCallback). Te dwie metody radzą sobie z w celach informacyjnych.

Wszystkie aplikacje na Androida mają sieć domyślną, która jest określana przez system. System zazwyczaj preferuje sieci bez pomiaru z sieciami z pomiarem użycia danych i szybszymi – do wolniejszych.

Gdy aplikacja wysyła żądanie sieciowe, na przykład HttpsURLConnection, w odpowiedzi na to żądanie, używając sieci domyślnej. Aplikacje mogą wysyłać ruch również w innych sieciach. Więcej informacji można znaleźć w sekcji dotyczącej dodatkowych .

Sieć ustawiona jako sieć domyślna może się zmienić w dowolnym momencie od początku istnienia aplikacji. Typowym przykładem jest to, że urządzenie znajduje się w zasięgu znany, aktywny, niepomiarowy i szybszy niż komórkowy punkt dostępu Wi-Fi. urządzenie łączy się z tym punktem dostępu i przełącza sieć domyślną dla wszystkich z aplikacjami do nowej sieci Wi-Fi.

Gdy nowa sieć stanie się siecią domyślną, każde nowe połączenie otwierane przez aplikację będzie używane w tej sieci. W późniejszym czasie wszystkie pozostałe połączenia na poprzednim sieć domyślna jest wymuszana. Jeśli ważne jest, aby aplikacja Jeśli sieć domyślna się zmieni, zostanie zarejestrowana oddzwanianie w następujący sposób:

Kotlin

connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network : Network) {
        Log.e(TAG, "The default network is now: " + network)
    }

    override fun onLost(network : Network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network)
    }

    override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities)
    }

    override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties)
    }
})

Java

connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        Log.e(TAG, "The default network is now: " + network);
    }

    @Override
    public void onLost(Network network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network);
    }

    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities);
    }

    @Override
    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties);
    }
});

Gdy nowa sieć stanie się siecią domyślną, aplikacja odbiera wywołanie onAvailable(Network) dla nowej sieci. Wdrażaj onCapabilitiesChanged(Network,NetworkCapabilities) onLinkPropertiesChanged(Network,LinkProperties), lub oba te tryby, aby odpowiednio reagować na zmiany w łączności.

W przypadku wywołania zwrotnego zarejestrowanego w registerDefaultNetworkCallback(), onLost() oznacza, że sieć utraciła status sieci domyślnej. Może być odłączone.

Mimo że możesz dowiedzieć się więcej o środkach transportu, z których korzysta sieć domyślna, zapytania NetworkCapabilities.hasTransport(int) oznacza słaby serwer proxy, jeśli chodzi o przepustowość lub użycie danych w sieci. Twoja aplikacja nie może zakładać, że sieć Wi-Fi jest zawsze bez pomiaru i zawsze zapewnia lepszą przepustowość. niż w przypadku urządzeń mobilnych.

Zamiast tego użyj NetworkCapabilities.getLinkDownstreamBandwidthKbps() do pomiaru przepustowości; NetworkCapabilites.hasCapability(int) z NET_CAPABILITY_NOT_METERED aby określić pomiar wykorzystania. Więcej informacji można znaleźć w sekcji na temat NetworkCapabilities and LinkWłaściwości.

Domyślnie metody wywołania zwrotnego są wywoływane w wątku połączenia Twojej aplikacji, która jest oddzielnym wątkiem używanym przez aplikację ConnectivityManager. Jeśli że implementacja wywołań zwrotnych musi przestać działać, wywołaj je oddzielny wątek instancji roboczej przy użyciu wariantu ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler)

Wyrejestruj połączenie zwrotne, gdy nie jest już używane, pod numerem ConnectivityManager.unregisterNetworkCallback(NetworkCallback) onPause() w Twojej głównej aktywności to dobry sposób, by to zrobić, zwłaszcza jeśli rejestrujesz wywołanie zwrotne onResume()

Dodatkowe sieci

Mimo że sieć domyślna to jedyna sieć w przypadku większości aplikacji, niektóre aplikacje być może zainteresują Cię inne dostępne sieci. Aplikacje tworzy NetworkRequest pasujące do potrzeby i telefon ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback)

Proces ten jest podobny do słuchania z siecią domyślną. Jednak chociaż może to być tylko jeden domyślnej sieci używanej w danej aplikacji w danym momencie, ta wersja może jednocześnie wyświetlać wszystkie dostępne sieci. Zadzwoń pod numer onLost(Network) oznacza, że sieć została odłączona na dobre, nie że nie jest to sieć domyślna już więcej.

Aplikacja tworzy NetworkRequest, aby wskazać ConnectivityManager sieci, w których chce ją słuchać. Poniższy przykład pokazuje, jak utworzyć NetworkRequest w przypadku aplikacji, która interesuje tylko internet bez pomiaru użycia danych. połączenia:

Kotlin

val request = NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
  .build()

connectivityManager.registerNetworkCallback(request, myNetworkCallback)

Java

NetworkRequest request = new NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
  .build();

connectivityManager.registerNetworkCallback(request, myNetworkCallback);

Oznacza to, że aplikacja będzie otrzymywać informacje o wszelkich zmianach dotyczących sieć równorzędna w systemie.

Jeśli chodzi o domyślne wywołanie zwrotne sieci, dostępna jest wersja registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) , który akceptuje Handler, dzięki czemu nie wczytuje wątku Connectivity Twojego .

Zadzwoń do nas ConnectivityManager.unregisterNetworkCallback(NetworkCallback) gdy wywołanie zwrotne nie jest już istotne. Aplikacja może jednocześnie rejestrować wiele wywołań zwrotnych sieci.

Dla wygody Obiekt NetworkRequest zawiera typowe funkcje, których potrzebuje większość aplikacji, w tym:

Pisząc aplikację, sprawdź ustawienia domyślne, aby zobaczyć, czy pasują przypadki użycia i wyczyść je, jeśli chcesz otrzymywać powiadomienia o sieciach które nie mają tych funkcji. Z drugiej strony dodaj uniknąć wywołania w przypadku zmiany połączenia w sieciach, której aplikacja nie wchodzi w interakcję.

Jeśli na przykład aplikacja musi wysyłać MMS-y, dodaj NET_CAPABILITY_MMS w sieci NetworkRequest, aby uniknąć informowania Cię o wszystkich sieciach, które nie mogą wysyłania MMS-ów. Dodaj TRANSPORT_WIFI_AWARE jeśli Twoja aplikacja potrzebuje tylko łączności Wi-Fi P2P. NET_CAPABILITY_INTERNET i NET_CAPABILITY_VALIDATED. są przydatne, jeśli interesuje Cię możliwość przesyłania danych za pomocą serwera w internecie.

Przykładowa sekwencja wywołania zwrotnego

W tej sekcji opisujemy sekwencję wywołań zwrotnych, które aplikacja może otrzymać, jeśli rejestruje zarówno domyślne wywołanie zwrotne, jak i zwykłe wywołanie zwrotne na urządzeniu, które ma łączność komórkową. W tym przykładzie urządzenie łączy się z dobrego punktu dostępu Wi-Fi, a następnie się od niego rozłącza. W przykładzie założono też na urządzeniu ma włączoną opcję Mobilna transmisja danych zawsze włączona.

Harmonogram wygląda tak:

  1. Gdy aplikacja wywołuje registerNetworkCallback(), połączenie zwrotne jest wykonywane natychmiast. odbiera połączenia od: onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged() dla sieci komórkowej, ponieważ tylko ona jest dostępna. Jeśli dostępna jest inna sieć, aplikacja otrzymuje też wywołania zwrotne dla innej sieci.


    (Diagram stanu przedstawiający zarejestrowanie zdarzenia wywołania zwrotnego sieci i wywołań zwrotnych wywołane przez to zdarzenie) Rysunek 1. Stan aplikacji po wywołaniu aplikacji registerNetworkCallback().

  2. Następnie aplikacja wywołuje metodę registerDefaultNetworkCallback(). Sieć domyślna oddzwanianie zacznie odbierać połączenia z numerem onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged() dla Sieć komórkowa, bo sieć komórkowa jest siecią domyślną. Jeśli czy inna, sieć inna niż domyślna działa, aplikacja nie może odbierać dla sieci innej niż domyślna.


    (Diagram stanu pokazujący rejestrowanie zdarzenia domyślnego wywołania zwrotnego sieci oraz
wywołania zwrotne aktywowane przez zdarzenie) Rysunek 2. Stan aplikacji po zarejestrowaniu sieci domyślnej.

  3. Następnie urządzenie łączy się z siecią Wi-Fi (bez pomiaru). Standardowe wywołanie zwrotne sieci odbiera połączenia z numerem onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged() dla Sieć Wi-Fi.


    (Diagram stanu przedstawiający wywołania zwrotne aktywowane, gdy aplikacja łączy się z
nowa sieć) Rysunek 3. Stan aplikacji po połączeniu się z siecią Wi-Fi bez pomiaru.

  4. W tym momencie może minąć trochę czasu, zanim sieć Wi-Fi zweryfikuje się. W w tym przypadku, onNetworkCapabilitiesChanged() wywołuje zwykłą sieć wywołanie zwrotne nie zawiera możliwości NET_CAPABILITY_VALIDATED. Po w krótkim czasie otrzymuje połączenie z numerem onNetworkCapabilitiesChanged(), gdzie nowe możliwości obejmują NET_CAPABILITY_VALIDATED. W większości przypadków weryfikacja przebiegnie bardzo szybko.

    Jeśli sieć Wi-Fi zostanie sprawdzona, system da pierwszeństwo sieci komórkowej głównie dlatego, że nie jest mierzona. Sieć Wi-Fi staje się przez sieć domyślną, więc domyślne wywołanie zwrotne sieci otrzymuje wywołanie pod adresem onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged() w przypadku sieci Wi-Fi. Sieć komórkowa przechodzi w tle, a zwykłe wywołanie zwrotne sieci otrzymuje wywołanie pod numerem onLosing() w przypadku sieci komórkowej.

    W tym przykładzie założono, że komórkowa transmisja danych jest zawsze włączona na urządzeniu, sieć komórkowa nigdy się nie rozłącza. Jeśli to ustawienie jest wyłączone, po gdy nastąpi rozłączenie sieci komórkowej, oraz zwykłe wywołanie zwrotne sieci odbiera połączenie z numerem onLost().


    (Diagram stanu przedstawiający wywołania zwrotne aktywowane po połączeniu z siecią Wi-Fi
sprawdzenie połączenia) Rysunek 4. Stan aplikacji po zweryfikowaniu sieci Wi-Fi.

  5. Po jakimś czasie urządzenie nagle rozłącza się z Wi-Fi, ponieważ zostało wyłączone ma zasięg. Połączenie Wi-Fi zostaje przerwane, więc zwykłe wywołanie zwrotne sieci otrzymuje Zadzwoń pod numer onLost(), by uzyskać dostęp do Wi-Fi. Urządzenia mobilne to nowa sieć domyślna, domyślne wywołanie zwrotne sieci otrzymuje wywołania onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged() dla przez sieć komórkową.


    (Diagram stanu przedstawiający wywołania zwrotne aktywowane po połączeniu z siecią Wi-Fi
połączenie zostało zerwane) Rysunek 5. Stan aplikacji po odłączeniu od sieci Wi-Fi.

Jeśli ustawienie Mobilna transmisja danych jest zawsze włączone, rozłącza urządzenie, próbując ponownie nawiązać połączenie z siecią komórkową. Zdjęcie jest podobny, ale z krótkim dodatkowym opóźnieniem w przypadku połączeń onAvailable() i zwykłe wywołanie zwrotne sieci również otrzymuje wywołania onAvailable(), onNetworkCapabilitiesChanged() i onLinkPropertiesChanged(), ponieważ na komórki.

Ograniczenia dotyczące korzystania z sieci do przesyłania danych

To, że widzisz sieć z wywołaniem zwrotnym, nie oznacza, że aplikacja może będzie używać sieci do przesyłania danych. Niektóre sieci nie zapewniają dostępu do internetu i niektóre sieci mogą być ograniczone do aplikacji z podwyższonymi uprawnieniami. Aby sprawdzić połączenie z internetem, zobacz NET_CAPABILITY_INTERNET oraz NET_CAPABILITY_VALIDATED

Korzystanie z sieci działających w tle podlega również sprawdzaniu uprawnień. Jeśli Twoja aplikacja chce korzystać z sieci w tle, CHANGE_NETWORK_STATE uprawnienia.

Aplikacje z tymi uprawnieniami pozwalają systemowi spróbować aby połączyć się z siecią, która nie działa, np. z siecią komórkową. gdy urządzenie jest połączone z siecią Wi-Fi. Taka aplikacja wywołuje ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback) z funkcją NetworkCallback, która ma zostać wywołana po uruchomieniu sieci.