ネットワーク接続/インターネットアクセス
isConnectedOrConnecting()
(ほとんどの回答で使用)ネットワーク接続をチェックします
- これらのネットワークのいずれかがインターネットにアクセスできるかどうかを知るには、次のいずれかを使用します
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)インターネット上のソケットに接続する(高度な)
// 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; }
}
+
非常に高速(どちらの方法でも)、すべてのデバイスで動作し、非常に信頼性が高い
-
UIスレッドで実行できません
これは、すべてのデバイスで非常に確実に機能し、非常に高速です。ただし、別のタスクで実行する必要があります(例ScheduledExecutorService
またはAsyncTask
)。
考えられる質問
本当に十分速いですか?
はい、非常に高速です;-)
インターネット上で何かをテストする以外に、インターネットをチェックする信頼できる方法はありませんか?
私の知る限りではありませんが、私に知らせてください。答えを編集します。
DNSがダウンしている場合はどうなりますか?
Google DNS(eg 8.8.8.8
)は、世界最大のパブリックDNSです。2018年の時点で、1日に1兆件を超えるクエリを処理しました[ 1 ]。たとえば、あなたのアプリはおそらくその日の話題ではないでしょう。
どの権限が必要ですか?
<uses-permission android:name="android.permission.INTERNET" />
ただのインターネットアクセス-驚き^^(ところで、ここで提案された方法のいくつかは、この許可なしにインターネットアクセスについてリモートの接着剤を持つことができる方法について考えたことがありますか?)
追加:ワンショットのRxJava/RxAndroid
例(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 */}
追加:ワンショットのRxJava/RxAndroid
例(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 {
}
});
追加:ワンショットのAsyncTask
例
注意:これは、リクエストを実行する方法の別の例を示しています。ただし、AsyncTask
は非推奨であるため、アプリのスレッドスケジューリング、Kotlinコルーチン、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 */ });