Conexión de red / acceso a Internet
isConnectedOrConnecting()
(utilizado en la mayoría de las respuestas) verifica cualquier conexión de red
- Para saber si alguna de esas redes tiene acceso a Internet , use uno de los siguientes
A) Hacer ping a un servidor (fácil)
// 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;
}
+
podría ejecutarse en el hilo principal
-
no funciona en algunos dispositivos antiguos (Galays S3, etc.), bloquea un tiempo si no hay Internet disponible.
B) Conéctese a un enchufe en Internet (avanzado)
// 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; }
}
+
muy rápido (de cualquier manera), funciona en todos los dispositivos, muy confiable
-
no se puede ejecutar en el hilo de la interfaz de usuario
Esto funciona de manera muy confiable, en todos los dispositivos, y es muy rápido. Sin embargo, debe ejecutarse en una tarea separada (por ejemplo, ScheduledExecutorService
o AsyncTask
).
Posibles preguntas
¿Es realmente lo suficientemente rápido?
Sí, muy rápido ;-)
¿No hay una forma confiable de verificar Internet, aparte de probar algo en Internet?
No hasta donde yo sé, pero hágamelo saber y editaré mi respuesta.
¿Qué pasa si el DNS está caído?
Google DNS (por ejemplo 8.8.8.8
) es el DNS público más grande del mundo. A partir de 2013 atendió 130 mil millones de solicitudes por día. Digamos que su aplicación probablemente no sea la conversación del día.
¿Qué permisos se requieren?
<uses-permission android:name="android.permission.INTERNET" />
Solo acceso a Internet: sorpresa ^^ (Por cierto, ¿alguna vez has pensado en cómo algunos de los métodos sugeridos aquí podrían tener un pegamento remoto sobre el acceso a Internet, sin este permiso?)
Extra: AsyncTask
ejemplo de un disparo
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
Ejemplo de un disparo (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) ...
. Vea mi respuesta para una mejor implementación de esto. Por cierto, la respuesta aceptada (y muchas otras aquí) simplemente verifique si hay una conexión de red , no internet.