Netzwerkanschluss / Internetzugang
isConnectedOrConnecting()
(wird in den meisten Antworten verwendet) prüft auf alle Netzwerk Verbindung
- Um zu erfahren, ob eines dieser Netze Internet Zugang, verwenden Sie eine der folgenden Möglichkeiten
A) Einen Server anpingen (einfach)
// ICMP
public boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
catch (IOException e) { e.printStackTrace(); }
catch (InterruptedException e) { e.printStackTrace(); }
return false;
}
+
könnte auf dem Hauptthread laufen
-
funktioniert nicht auf einigen alten Geräten (Galays S3, etc.), es blockiert eine Weile, wenn kein Internet verfügbar ist.
B) Verbindung mit einem Socket im Internet (fortgeschritten)
// TCP/HTTP/DNS (depending on the port, 53=DNS, 80=HTTP, etc.)
public boolean isOnline() {
try {
int timeoutMs = 1500;
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
sock.connect(sockaddr, timeoutMs);
sock.close();
return true;
} catch (IOException e) { return false; }
}
+
sehr schnell (so oder so), funktioniert auf allen Geräten, sehr zuverlässig
-
kann nicht auf dem UI-Thread ausgeführt werden
Das funktioniert sehr zuverlässig, auf jedem Gerät, und ist sehr schnell. Es muss allerdings in einem separaten Task laufen (z.B. ScheduledExecutorService
o AsyncTask
).
Mögliche Fragen
-
Ist es wirklich schnell genug?
Ja, sehr schnell ;-)
-
Gibt es keine andere zuverlässige Möglichkeit, das Internet zu überprüfen, als etwas im Internet zu testen?
Soweit ich weiß, nicht, aber lassen Sie es mich wissen, und ich werde meine Antwort ändern.
-
Was ist, wenn der DNS nicht funktioniert?
Google DNS (z.B.. 8.8.8.8
) ist das größte öffentliche DNS der Welt. Im Jahr 2018 bearbeitete es über eine Billion Anfragen pro Tag [ 1 ]. Sagen wir einfach, Ihre App wäre wahrscheinlich nicht das Tagesgespräch.
-
Welche Berechtigungen sind erforderlich?
<uses-permission android:name="android.permission.INTERNET" />
Nur Internetzugang - Überraschung ^^ (Btw, hast du schon mal darüber nachgedacht, dass einige der hier vorgeschlagenen Methoden auch ohne diese Erlaubnis einen Fernkleber über den Internetzugang haben könnten?)
Extra: One-shot RxJava/RxAndroid
Beispiel (Kotlin)
fun hasInternetConnection(): Single<Boolean> {
return Single.fromCallable {
try {
// Connect to Google DNS to check for connection
val timeoutMs = 1500
val socket = Socket()
val socketAddress = InetSocketAddress("8.8.8.8", 53)
socket.connect(socketAddress, timeoutMs)
socket.close()
true
} catch (e: IOException) {
false
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
hasInternetConnection().subscribe { hasInternet -> /* do something */}
Extra: One-shot RxJava/RxAndroid
Beispiel (Java)
public static Single<Boolean> hasInternetConnection() {
return Single.fromCallable(() -> {
try {
// Connect to Google DNS to check for connection
int timeoutMs = 1500;
Socket socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress("8.8.8.8", 53);
socket.connect(socketAddress, timeoutMs);
socket.close();
return true;
} catch (IOException e) {
return false;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
hasInternetConnection().subscribe((hasInternet) -> {
if(hasInternet) {
}else {
}
});
Extra: One-shot AsyncTask
例
Vorsicht! Dies ist ein weiteres Beispiel dafür, wie die Anfrage gestellt werden kann. Da jedoch AsyncTask
ist veraltet und sollte durch das Thread-Scheduling Ihrer App, Kotlin Coroutines, Rx, ... ersetzt werden.
class InternetCheck extends AsyncTask<Void,Void,Boolean> {
private Consumer mConsumer;
public interface Consumer { void accept(Boolean internet); }
public InternetCheck(Consumer consumer) { mConsumer = consumer; execute(); }
@Override protected Boolean doInBackground(Void... voids) { try {
Socket sock = new Socket();
sock.connect(new InetSocketAddress("8.8.8.8", 53), 1500);
sock.close();
return true;
} catch (IOException e) { return false; } }
@Override protected void onPostExecute(Boolean internet) { mConsumer.accept(internet); }
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
new InternetCheck(internet -> { /* do something with boolean response */ });
7 Stimmen
Um zu prüfen, ob eine Internetverbindung besteht, ist es wahrscheinlich am zuverlässigsten, einen der großen Nameserver anzupingen, z. B. mit
if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) ...
. Siehe meine Antwort für eine schönere Implementierung dieser Funktion. Btw die akzeptierte Antwort (und viele andere hier) einfach nach einem Netzanschluss und nicht das Internet.0 Stimmen
Siehe-> stackoverflow.com/a/4239019/1815624
4 Stimmen
Verwenden Sie nicht die Ping-Methode, sondern eine HTTP-Überprüfung. ICMP wird in einigen Netzen blockiert, so dass Ping nicht funktioniert. Beispiel: Bei mir zu Hause funktioniert es einwandfrei, aber nicht, wenn ich mobile Daten im Netz von Vodafone (in Ungarn) verwende. Sie können die beiden Methoden auch kombinieren, aber seien Sie vorsichtig, denn waitFor() wartet etwa 20 Sekunden, auch wenn -w oder -W verwendet wird.
0 Stimmen
getAllNetworkInfo()
ist in API Stufe 29 veraltet