Network connection / Internet access
isConnectedOrConnecting()
(在大多数答案中使用)判断任何network连接
- 要知道这些网络是否有internet个访问权限,请使用以下选项之一
a)Ping服务器(简单)
// 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;
}
+
可以在主线程上运行
-
在一些旧设备(Galays S3等)上不工作,如果没有可用的互联网,它会阻塞一段时间.
B) 连接到Internet上的插座(高级)
// 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; }
}
+
速度非常快(无论采用哪种方式),可在所有设备上运行,very可靠
-
无法在UI线程上运行
这在每一台设备上都能非常可靠地工作,而且速度非常快.不过,它需要在单独的任务中运行(例如,ScheduledExecutorService
或AsyncTask
).
可能的问题
它真的够快吗?
Yes, very fast ;-)
除了在网上测试之外,有没有可靠的方式来判断互联网?
Not as far as I know, but let me know, and I will edit my answer.
如果DNS关闭了怎么办?
Google DNS (e.g. 101) is the largest public DNS in the world. As of 2018 it handled over a trillion queries a day [100]. Let 's just say, your app would probably not be the talk of the day.
需要哪些权限?
<uses-permission android:name="android.permission.INTERNET" />
Just internet access - surprise ^^ (Btw have you ever thought about, how some of the methods suggested here could even have a remote glue about internet access, without this permission?)个
Extra: One-shot RxJava/RxAndroid
Example (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
Example (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
Example
Caution:这显示了另一个如何处理请求的示例.然而,由于AsyncTask
已经被弃用,它应该被你的应用程序的线程调度取代,Kotlin Coroutines,Rx,.
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 */ });