Connexion réseau / accès Internet
isConnectedOrConnecting()
(utilisé dans la plupart des réponses) vérifie toute connexion réseau
- Pour savoir si l'un de ces réseaux dispose d' un accès à Internet , utilisez l'une des méthodes suivantes
A) Ping un serveur (facile)
// 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;
}
+
pourrait fonctionner sur le thread principal
-
ne fonctionne pas sur certains appareils anciens (Galays S3, etc.), il bloque un certain temps si aucune connexion Internet n'est disponible.
B) Se connecter à un socket sur Internet (avancé)
// 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; }
}
+
très rapide (de toute façon), fonctionne sur tous les appareils, très fiable
-
ne peut pas fonctionner sur le thread d'interface utilisateur
Cela fonctionne de manière très fiable, sur tous les appareils, et est très rapide. Il doit cependant être exécuté dans une tâche distincte (par exemple ScheduledExecutorService
ou AsyncTask
).
Questions possibles
Est-ce vraiment assez rapide?
Oui, très vite ;-)
Existe-t-il un moyen fiable de vérifier Internet, autre que de tester quelque chose sur Internet?
Pas autant que je sache, mais faites-le moi savoir et je modifierai ma réponse.
Et si le DNS est en panne?
Le DNS de Google (par exemple 8.8.8.8
) est le plus grand DNS public au monde. En 2013, il traitait 130 milliards de demandes par jour. Disons simplement que votre application ne sera probablement pas le sujet du jour.
Quelles autorisations sont nécessaires?
<uses-permission android:name="android.permission.INTERNET" />
Juste un accès Internet - surprise ^^ (Au fait, avez-vous déjà pensé à la façon dont certaines des méthodes suggérées ici pourraient même avoir une colle à distance sur l'accès à Internet, sans cette autorisation?)
Extra: AsyncTask
Exemple ponctuel
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 */ });
Extra: RxJava/RxAndroid
Exemple ponctuel (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 */}
if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) ...
. Voir ma réponse pour une meilleure mise en œuvre de cela. Btw la réponse acceptée (et bien d'autres ici) vérifie simplement une connexion réseau , pas Internet.