Netzwerkstatus lesen

Mit Android können Apps dynamische Veränderungen bei der Konnektivität erkennen. Verwenden Sie die Methode folgenden Klassen verwenden, um Verbindungsänderungen zu verfolgen und darauf zu reagieren:

  • ConnectivityManager informiert Ihre App über den Status der Konnektivität im System.
  • Die Klasse Network repräsentiert eine der Netzwerke, mit denen das Gerät verbunden ist. Sie können die Network verwenden als Schlüssel, um Informationen über das Netzwerk mit ConnectivityManager oder Sockets im Netzwerk zu binden. Wenn das Netzwerk getrennt wird, kann das Network-Objekt nicht mehr verwendet werden. Auch wenn das Gerät später eine Verbindung zur selben Appliance herstellt, steht ein neues Network-Objekt für die neuen Senders.
  • LinkProperties-Objekt enthält Informationen zum Link für ein Netzwerk, z. B. die Liste der DNS- Server, lokalen IP-Adressen und Netzwerkrouten, die für das Netzwerk installiert sind.
  • Die NetworkCapabilities enthält Informationen zu den Eigenschaften eines Netzwerks, z. B. (WLAN, mobile Daten, Bluetooth) und was das Netzwerk unterstützt. Sie können z. B. das Objekt abfragen, um festzustellen, ob das Netzwerk die MMS senden können, sich hinter einem Captive Portal befindet oder mit einem Messtool verbunden sind.

Apps, die an der unmittelbaren Verbindung zu einem bestimmten Zeitpunkt interessiert sind, können ConnectivityManager-Methoden aufrufen, um herauszufinden, was für ein Netzwerk verfügbar. Diese Methoden sind hilfreich für das Debugging und zur gelegentlichen Überprüfung eines Momentaufnahme der Verbindung, die zu einem bestimmten Zeitpunkt verfügbar ist.

Die synchrone Mit ConnectivityManager-Methoden erfährst du in deiner App nichts, was passiert nach einem Anruf, sodass Sie Ihre Benutzeroberfläche nicht aktualisieren können. Außerdem können sie die App je nachdem, ob die Verbindung zum Netzwerk getrennt oder ändern können.

Die Konnektivität kann sich jederzeit ändern und die meisten Apps benötigen eine immer aktuelle, aktuelle Ansicht des Netzwerkstatus auf dem Gerät. Apps können einen Callback mit ConnectivityManager registrieren, um über Änderungen informiert zu werden, App interessiert. Mit dem Callback kann Ihre App sofort auf jede Änderungen der Konnektivität vornehmen, ohne auf kostspielige Umfragen bei denen schnelle Updates übersehen werden.

Mit NetworkCallback und anderen Möglichkeiten, mehr über die für den Verbindungsstatus des Geräts keine bestimmte Berechtigung erforderlich ist. Einige Netzwerke unterliegen jedoch bestimmten Berechtigungen. Für Es kann beispielsweise sein, dass eingeschränkte Netzwerke für Apps nicht verfügbar sind. Bindung an eine Hintergrundnetzwerk die Berechtigung CHANGE_NETWORK_STATE benötigt. Und einige für die Ausführung möglicherweise bestimmte Berechtigungen erforderlich sind. Weitere Informationen finden Sie in der Dokumentation zu jedem Aufruf.

Aktuellen Status abrufen

Ein Android-Gerät kann viele Verbindungen gleichzeitig aufrechterhalten. Um Informationen zum aktuellen Netzwerkstatus zu erhalten, rufen Sie Eine Instanz von ConnectivityManager:

Kotlin

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

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

Verwenden Sie diese Instanz als Nächstes, um einen Verweis auf das aktuelle Standardnetzwerk für Ihr App:

Kotlin

val currentNetwork = connectivityManager.getActiveNetwork()

Java

Network currentNetwork = connectivityManager.getActiveNetwork();

Mit Bezug auf ein Netzwerk kann Ihre App Informationen zu diesem Netzwerk anfordern:

Kotlin

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

Java

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

Registrieren Sie ein NetworkCallback Weitere Informationen zum Registrieren von Netzwerk-Callbacks finden Sie unter Auf Netzwerkereignisse achten:

NetworkCapabilities und LinkProperties

Die Objekte NetworkCapabilities und LinkProperties liefern Informationen über alle Attribute, die das System über ein Netzwerk kennt.

Das LinkProperties die Routen, die Linkadressen, den Schnittstellennamen, die Proxy-Informationen (wenn beliebige) und DNS-Server. Rufen Sie die entsprechende Methode für das LinkProperties-Objekt auf. um die benötigten Informationen zu erhalten.

NetworkCapabilities-Objekt kapselt Informationen über das Netzwerk transports und seine Funktionen ein.

Ein Transport ist eine Abstraktion eines physischen Mediums, über das ein Netzwerk funktioniert. Gängige Beispiele für Übertragungen sind Ethernet, WLAN und Mobilgeräte. VPNs und Peer-to-Peer-WLAN können ebenfalls Übertragungen sein. Auf Android-Geräten können für ein Netzwerk mehrere Übertragungen gleichzeitig ausgeführt werden. Beispiel ein VPN, das sowohl über WLAN als auch über Mobilfunknetze funktioniert. Das VPN hat die WLAN-, Mobilfunk- und VPN-Übertragungen Um herauszufinden, ob ein ein bestimmtes Transportsystem hat, verwenden Sie NetworkCapabilities.hasTransport(int) mit einer der NetworkCapabilities.TRANSPORT_*-Konstanten an.

Eine Capability beschreibt eine Eigenschaft des Netzwerks. Beispiele für Funktionen: MMS, NOT_METERED und INTERNET. Ein Netzwerk mit MMS-Funktion kann und empfangen Sie Multimedia Messaging Service-Nachrichten und ein Netzwerk ohne diese nicht möglich ist. Ein Netzwerk mit der Funktion NOT_METERED berechnet nicht den Nutzer*innen nach Daten. Ihre App kann mithilfe des NetworkCapabilities.hasCapability(int) mit einer der NetworkCapabilities.NET_CAPABILITY_*-Konstanten an.

Die nützlichsten NET_CAPABILITY_*-Konstanten sind:

  • NET_CAPABILITY_INTERNET: zeigt an, dass das Netzwerk eingerichtet ist, um auf das Internet zuzugreifen. Es geht um die Einrichtung, nicht um die eigentliche Fähigkeit, öffentliche Server zu erreichen. Ein Netzwerk kann beispielsweise so eingerichtet werden, auf das Internet zugreifen können, aber einem Zugangsportal unterliegen.

    Das Mobilfunknetz eines Mobilfunkanbieters verfügt in der Regel über die INTERNET-Funktion, während ein lokalen P2P-WLAN-Netzwerke nicht. Informationen zur tatsächlichen Verbindung siehe NET_CAPABILITY_VALIDATED

  • NET_CAPABILITY_NOT_METERED: bedeutet, dass das Netzwerk nicht kostenpflichtig ist. Ein Netzwerk ist als „kostenpflichtig“ klassifiziert, wenn der Nutzer empfindlich auf eine hohe Datennutzung reagiert. Internetnutzung aufgrund von finanziellen Kosten, Einschränkungen bei der Datennutzung oder Akkuleistung Probleme.

  • NET_CAPABILITY_NOT_VPN: gibt an, dass das Netzwerk kein virtuelles privates Netzwerk ist.

  • NET_CAPABILITY_VALIDATED: gibt an, dass das Netzwerk tatsächlichen Zugriff an das öffentliche Internet übertragen, wenn es geprüft wird. Ein Netzwerk hinter einem Gefangenen oder ein Netzwerk, das keine Auflösung von Domainnamen anbietet, diese Fähigkeit nutzen können. Dies ist der nächste, der das System über ein Netzwerk informieren kann auch wenn ein geprüftes Netzwerk immer noch Zugriff hat, sind grundsätzlich IP-basierter Filterung möglich oder es treten plötzliche Verluste Konnektivität aufgrund von Problemen wie schlechtem Empfang.

  • NET_CAPABILITY_CAPTIVE_PORTAL: zeigt an, dass das Netzwerk bei seiner Prüfung ein Captive Portal hat.

Es gibt noch andere Funktionen, die für speziellere Apps interessant sein könnten. Weitere Informationen finden Sie in den Parameterdefinitionen in NetworkCapabilities.hasCapability(int)

Die Funktionen eines Netzwerks können sich jederzeit ändern. Wenn das System eine Captive Portal aktiviert, wird eine Benachrichtigung angezeigt, in der der Nutzer aufgefordert wird, sich anzumelden. Während dies aktiv ist, hat das Netzwerk die NET_CAPABILITY_INTERNET und NET_CAPABILITY_CAPTIVE_PORTAL-Funktionen, aber nicht die NET_CAPABILITY_VALIDATED-Funktion.

Wenn der Nutzer eine Aktion durchführt und sich anmeldet Captive Portal-Seite aktiviert wird, kann das Gerät auf das öffentliche Internet zugreifen Das Netzwerk erhält die NET_CAPABILITY_VALIDATED-Kapazität und verliert die NET_CAPABILITY_CAPTIVE_PORTAL-Funktion.

Ebenso können sich die Transporte eines Netzwerks dynamisch ändern. Beispielsweise kann ein VPN neu konfiguriert werden, ein schnelleres Netzwerk, das neu erstellt wurde, mit seinem zugrunde liegenden Netzwerk. In diesem Fall verliert das Netzwerk den TRANSPORT_CELLULAR und erhält den TRANSPORT_WIFI Transport, während die TRANSPORT_VPN Transport.

Auf Netzwerkereignisse warten

Informationen über Netzwerkereignisse erhalten Sie mit dem NetworkCallback Klasse zusammen mit ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback) und ConnectivityManager.registerNetworkCallback(NetworkCallback) Diese beiden Methoden dienen unterschiedlichen zu verstehen.

Alle Android-Apps haben ein Standardnetzwerk, das vom System bestimmt wird. Das System bevorzugt kostenlose Netzwerke von schnelleren Netzwerken zu langsameren Netzwerken.

Wenn eine App eine Netzwerkanfrage ausgibt, z. B. mit HttpsURLConnection, der diese Anforderung mithilfe des Standardnetzwerks erfüllt. Apps können Traffic senden auch in anderen Netzwerken. Weitere Informationen finden Sie im Abschnitt über zusätzliche Netzwerken

Das als Standardnetzwerk festgelegte Netzwerk kann sich während der der Lebensdauer einer App. Ein typisches Beispiel ist ein Gerät, das sich einen bekannten, aktiven, nicht getakteten und schnelleren WLAN-Zugangspunkt als mobile Daten. Die Gerät stellt eine Verbindung zu diesem Zugangspunkt her und wechselt das Standardnetzwerk mit dem neuen WLAN verbinden können.

Wenn ein neues Netzwerk zum Standard wird, verwendet jede neue Verbindung, die die App öffnet, in diesem Netzwerk. Irgendwann werden alle verbleibenden Verbindungen auf der vorherigen wird die Beendigung des Standardnetzwerks erzwungen. Wenn es für die App wichtig ist, und wissen, wann sich das Standardnetzwerk ändert, wird ein Standardnetzwerk registriert. -Callbacks folgendermaßen aussehen:

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);
    }
});

Wenn ein neues Netzwerk zum Standard wird, empfängt die App einen Aufruf an onAvailable(Network) für das neue Netzwerk aus. Implementieren onCapabilitiesChanged(Network,NetworkCapabilities), onLinkPropertiesChanged(Network,LinkProperties), oder beides, um angemessen auf Verbindungsänderungen zu reagieren.

Für einen bei registerDefaultNetworkCallback() registrierten Callback onLost() bedeutet, dass das Netzwerk den Status als Standardnetzwerk verloren hat. Möglicherweise ist die Verbindung getrennt.

Weitere Informationen zu den Transporten, die das Standardnetzwerk verwendet, Abfrage NetworkCapabilities.hasTransport(int), ist dies ein schlechter Indikator für die Bandbreite oder den Messbereich des Netzwerks. Ihre App Wir können nicht davon ausgehen, dass das WLAN immer gebührenfrei ist und immer eine bessere Bandbreite liefert. als auf Mobilgeräten.

Verwenden Sie stattdessen NetworkCapabilities.getLinkDownstreamBandwidthKbps() zum Messen der Bandbreite und NetworkCapabilites.hasCapability(int) mit NET_CAPABILITY_NOT_METERED um die Messung des Messergebnisses zu bestimmen. Weitere Informationen finden Sie im Abschnitt über NetworkCapabilities und LinkProperties.

Standardmäßig werden die Callback-Methoden im Verbindungs-Thread der Ihre Anwendung. Dies ist ein separater Thread, der von ConnectivityManager verwendet wird. Wenn Ihr die Implementierung der Callbacks nicht mehr funktionieren muss, separate Worker-Threads mithilfe der Variante ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler)

Heben Sie die Registrierung Ihres Callbacks auf, wenn Sie ihn nicht mehr verwenden. Rufen Sie dazu ConnectivityManager.unregisterNetworkCallback(NetworkCallback) onPause() deiner Hauptaktivität ist hierfür gut geeignet, insbesondere wenn Sie den Callback in onResume()

Zusätzliche Netzwerke

Für die meisten Apps ist das Standardnetzwerk zwar das einzige relevante Netzwerk, einige Apps sind vielleicht an anderen verfügbaren Netzwerken interessiert. Um mehr darüber zu erfahren, eine NetworkRequest erstellen, die ihrem und rufen Sie ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback)

Der Prozess ähnelt dem Zuhören mit einem Standardnetzwerk. Auch wenn es möglicherweise nur eine das für eine App zu einem bestimmten Zeitpunkt gilt, können Sie mit dieser Version alle verfügbaren Netzwerke gleichzeitig sehen, sodass ein Aufruf an onLost(Network) Das Netzwerk wurde dauerhaft getrennt. nicht mehr.

Die App erstellt eine NetworkRequest, um ConnectivityManager darüber zu informieren, welche Art von die er hören möchte. Das folgende Beispiel zeigt, wie ein NetworkRequest für eine App, die nur an einem kostenlosen Internetzugang interessiert ist Verbindungen:

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);

Das bedeutet, dass Ihre App über alle Änderungen in Bezug auf nicht getaktete Netzwerk im System.

Für den Standard-Netzwerk-Callback gibt es eine Version von registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) akzeptiert Handler, sodass der Connectivity-Thread Ihres

Anruf ConnectivityManager.unregisterNetworkCallback(NetworkCallback) wenn der Callback nicht mehr relevant ist. Eine Anwendung kann gleichzeitig registriert werden. Netzwerk-Callbacks angegeben werden.

Der Einfachheit halber enthält der NetworkRequest-Objekt enthält den Funktionen, die die meisten Apps benötigen, darunter:

Überprüfen Sie beim Schreiben Ihrer App die Standardeinstellungen, um zu sehen, ob sie mit Ihren und lösche sie, wenn deine App über Netzwerke benachrichtigt werden soll die diese Funktionen nicht haben. Fügen Sie jedoch Funktionen, um zu vermeiden, dass in Netzwerken, nicht mit der App interagiert.

Wenn Ihre App beispielsweise MMS senden muss, fügen Sie NET_CAPABILITY_MMS an den NetworkRequest, damit Sie nicht über die Netzwerke informiert werden, MMS senden Hinzufügen TRANSPORT_WIFI_AWARE wenn Ihre App nur an P2P-WLAN-Verbindungen interessiert ist. NET_CAPABILITY_INTERNET und NET_CAPABILITY_VALIDATED sind hilfreich, wenn Sie daran interessiert sind, Daten mit einem Server im Internet.

Beispiel für eine Callback-Sequenz

In diesem Abschnitt wird die Abfolge von Callbacks beschrieben, die eine App erhalten kann, wenn sie registriert sowohl einen Standard-Callback als auch einen regulären Callback auf einem Gerät, das verfügt über eine Mobilfunkverbindung. In diesem Beispiel stellt das Gerät eine Verbindung zu einem WLAN-Zugangspunkt und wird dann getrennt. In diesem Beispiel wird auch angenommen, dass die Einstellung Mobile Daten immer aktiviert aktiviert hat.

Der Zeitplan sieht so aus:

  1. Wenn die App registerNetworkCallback() aufruft, wird der Callback sofort gesendet. erhält Anrufe von onAvailable(), onNetworkCapabilitiesChanged() und onLinkPropertiesChanged() für das Mobilfunknetz, weil nur diese Netzwerk verfügbar ist. Wenn ein anderes Netzwerk verfügbar ist, erhält auch Callbacks für das andere Netzwerk.

    Statusdiagramm, das das Callback-Ereignis für das Registernetzwerk und die durch das Ereignis ausgelösten Callbacks zeigt
    Abbildung 1: App-Status nach dem Aufruf von registerNetworkCallback().

  2. Anschließend ruft die App registerDefaultNetworkCallback() auf. Das Standardnetzwerk Rückruf empfängt onAvailable()-Anrufe, onNetworkCapabilitiesChanged() und onLinkPropertiesChanged() für das Mobilfunknetz, da das Mobilfunknetz das Standardnetzwerk ist. Wenn ein anderes, nicht standardmäßiges Netzwerk aktiv ist, kann die App für das nicht-Standardnetzwerk abgerufen.

    Zustandsdiagramm, das die Registrierung des standardmäßigen Netzwerk-Callback-Ereignisses und die
durch das Ereignis ausgelöste Callbacks
    Abbildung 2: App-Status nach der Registrierung eines Standardnetzwerks.

  3. Später stellt das Gerät eine Verbindung zu einem (kostenlosen) WLAN her. Die normale Der Netzwerk-Callback empfängt Anrufe an onAvailable(), onNetworkCapabilitiesChanged() und onLinkPropertiesChanged() für das WLAN.

    Zustandsdiagramm, das die Callbacks zeigt, die ausgelöst werden, wenn die App eine Verbindung zu einem
neues Netzwerk
    Abbildung 3: App-Status nach dem Verbinden mit einem nicht getakteten WLAN

  4. An dieser Stelle kann es eine Weile dauern, bis das WLAN validiert ist. In In diesem Fall ruft onNetworkCapabilitiesChanged() das reguläre Netzwerk auf Callback enthält nicht die Fähigkeit NET_CAPABILITY_VALIDATED. Nach einem erhält er einen Anruf an onNetworkCapabilitiesChanged(), wo Zu den neuen Funktionen gehören NET_CAPABILITY_VALIDATED. In den meisten Fällen geht die Validierung sehr schnell.

    Wenn das WLAN validiert wird, bevorzugt das System es gegenüber dem Mobilgerät. weil sie nicht getaktet ist. Das WLAN wird zum Standardnetzwerk, sodass der Standardnetzwerk-Callback einen Aufruf an onAvailable(), onNetworkCapabilitiesChanged() und onLinkPropertiesChanged() für das WLAN. Über das Mobilfunknetz in den Hintergrund verschoben und der reguläre Netzwerk-Callback empfängt einen Anruf an onLosing() für das Mobilfunknetz.

    Da in diesem Beispiel angenommen wird, dass mobile Daten für dieses Gerät immer aktiviert sind, ist der Verbindung zum Mobilfunknetz nie getrennt. Ist die Einstellung deaktiviert, während die Verbindung zum Mobilfunknetz getrennt wird, erhält einen Anruf an onLost().

    Statusdiagramm, das die Callbacks zeigt, die ausgelöst werden, wenn ein WLAN-Netzwerk
Verbindung validiert
    Abbildung 4: App-Status nach Validierung des WLAN-Netzwerks.

  5. Später wird das Gerät immer noch plötzlich vom WLAN getrennt, weil es ausging. des Bereichs. Da die WLAN-Verbindung getrennt wird, erhält ein onLost() für WLAN anrufen. Da Mobilgeräte das neue Standardnetzwerk sind, empfängt der Standard-Netzwerk-Callback Aufrufe an onAvailable(), onNetworkCapabilitiesChanged() und onLinkPropertiesChanged() für das Mobilfunknetz.

    Statusdiagramm, das die Callbacks zeigt, die ausgelöst werden, wenn ein WLAN-Netzwerk
Verbindung unterbrochen
    Abbildung 5: App-Status nach dem Trennen der Verbindung zum WLAN.

Wenn die Einstellung Mobile Daten immer aktiviert deaktiviert ist, geschieht Folgendes: wird die Verbindung zum Gerät getrennt. Das Bild ist ähnlich, aber mit einer kurzen zusätzlichen Verzögerung für die onAvailable()-Aufrufe und erhält der reguläre Netzwerk-Callback auch onAvailable()-Aufrufe, onNetworkCapabilitiesChanged() und onLinkPropertiesChanged(), weil verfügbar wird.

Einschränkungen für die Nutzung des Netzwerks für die Datenübertragung

Wenn du ein Netzwerk mit einem Netzwerk-Callback sehen kannst, bedeutet das nicht, dass deine App das Netzwerk für die Datenübertragung nutzen. Einige Netzwerke bieten kein Internet und einige Netzwerke sind möglicherweise auf privilegierten Apps. Informationen zum Prüfen der Internetverbindung findest du unter NET_CAPABILITY_INTERNET und NET_CAPABILITY_VALIDATED

Bei der Verwendung von Hintergrundnetzwerken müssen auch Berechtigungsprüfungen durchgeführt werden. Wenn Ihre App ein Hintergrundnetzwerk nutzen möchte, benötigt es CHANGE_NETWORK_STATE Berechtigung.

Apps mit dieser Berechtigung erlauben es dem System, um ein Netzwerk aufzurufen, das nicht verfügbar ist, z. B. das Mobilfunknetz wenn das Gerät mit einem WLAN verbunden ist. Eine solche App ruft ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback) mit einer NetworkCallback, die beim Aufrufen des Netzwerks aufgerufen wird.