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 dieNetwork
verwenden als Schlüssel, um Informationen über das Netzwerk mitConnectivityManager
oder Sockets im Netzwerk zu binden. Wenn das Netzwerk getrennt wird, kann dasNetwork
-Objekt nicht mehr verwendet werden. Auch wenn das Gerät später eine Verbindung zur selben Appliance herstellt, steht ein neuesNetwork
-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 sieheNET_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:
Wenn die App
registerNetworkCallback()
aufruft, wird der Callback sofort gesendet. erhält Anrufe vononAvailable()
,onNetworkCapabilitiesChanged()
undonLinkPropertiesChanged()
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.
Abbildung 1: App-Status nach dem Aufruf vonregisterNetworkCallback()
.Anschließend ruft die App
registerDefaultNetworkCallback()
auf. Das Standardnetzwerk Rückruf empfängtonAvailable()
-Anrufe,onNetworkCapabilitiesChanged()
undonLinkPropertiesChanged()
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.
Abbildung 2: App-Status nach der Registrierung eines Standardnetzwerks.Später stellt das Gerät eine Verbindung zu einem (kostenlosen) WLAN her. Die normale Der Netzwerk-Callback empfängt Anrufe an
onAvailable()
,onNetworkCapabilitiesChanged()
undonLinkPropertiesChanged()
für das WLAN.
Abbildung 3: App-Status nach dem Verbinden mit einem nicht getakteten WLANAn 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ähigkeitNET_CAPABILITY_VALIDATED
. Nach einem erhält er einen Anruf anonNetworkCapabilitiesChanged()
, wo Zu den neuen Funktionen gehörenNET_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()
undonLinkPropertiesChanged()
für das WLAN. Über das Mobilfunknetz in den Hintergrund verschoben und der reguläre Netzwerk-Callback empfängt einen Anruf anonLosing()
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()
.
Abbildung 4: App-Status nach Validierung des WLAN-Netzwerks.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 anonAvailable()
,onNetworkCapabilitiesChanged()
undonLinkPropertiesChanged()
für das Mobilfunknetz.
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.