validar - Detecta si el dispositivo Android tiene conexión a Internet
validar si tengo internet android studio (8)
Necesito saber si mi dispositivo tiene conexión a Internet o no. Encontré muchas respuestas como:
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
(Tomado de Detectar si hay una conexión a Internet disponible en Android ).
Pero esto no está bien, por ejemplo, si estoy conectado a una red inalámbrica que no tiene acceso a Internet , este método volverá a ser cierto ... ¿Hay alguna manera de saber si el dispositivo tiene conexión a Internet y no si solo está conectado? ¿a algo?
En base a las respuestas aceptadas, construí esta clase con un oyente para que pueda usarla en el hilo principal:
Primero : la clase InterntCheck que verifica la conexión a Internet en segundo plano y luego llama al método de escucha con el resultado.
public class InternetCheck extends AsyncTask<Void, Void, Void> {
private Activity activity;
private InternetCheckListener listener;
public InternetCheck(Activity x){
activity= x;
}
@Override
protected Void doInBackground(Void... params) {
boolean b = hasInternetAccess();
listener.onComplete(b);
return null;
}
public void isInternetConnectionAvailable(InternetCheckListener x){
listener=x;
execute();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) activity.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
private boolean hasInternetAccess() {
if (isNetworkAvailable()) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://clients3.google.com/generate_204").openConnection());
urlc.setRequestProperty("User-Agent", "Android");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 204 &&
urlc.getContentLength() == 0);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.d("TAG", "No network available!");
}
return false;
}
public interface InternetCheckListener{
void onComplete(boolean connected);
}
}
Segundo : cree una instancia de la clase en el hilo principal y espere la respuesta (si ha trabajado con Firebase api para android antes de que esto le resulte familiar).
new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() {
@Override
public void onComplete(boolean connected) {
//proceed!
}
});
Ahora dentro de métodoCompleto obtendrá si el dispositivo está conectado a Internet o no.
He modificado ligeramente la respuesta de THelper, para usar un hack conocido que ya usa Android para verificar si la red WiFi conectada tiene acceso a Internet. Esto es mucho más eficiente que obtener toda la página de inicio de Google. Mira here y here para más información.
public static boolean hasInternetAccess(Context context) {
if (isNetworkAvailable(context)) {
try {
HttpURLConnection urlc = (HttpURLConnection)
(new URL("http://clients3.google.com/generate_204")
.openConnection());
urlc.setRequestProperty("User-Agent", "Android");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 204 &&
urlc.getContentLength() == 0);
} catch (IOException e) {
Log.e(TAG, "Error checking internet connection", e);
}
} else {
Log.d(TAG, "No network available!");
}
return false;
}
No es necesario que hagas una conexión HTTP completa. Podría intentar simplemente abrir una conexión TCP a un host conocido y, si tiene éxito, tendrá conectividad a Internet.
public boolean hostAvailable(String host, int port) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), 2000);
return true;
} catch (IOException e) {
// Either we have a timeout or unreachable host or failed DNS lookup
System.out.println(e);
return false;
}
}
Luego solo verifique con:
boolean online = hostAvailable("www.google.com", 80);
Si tiene como objetivo Lollipop o superior, es posible usar la nueva clase NetworkCapabilities, es decir:
public static boolean hasInternetConnection(final Context context) {
final ConnectivityManager connectivityManager = (ConnectivityManager)context.
getSystemService(Context.CONNECTIVITY_SERVICE);
final Network network = connectivityManager.getActiveNetwork();
final NetworkCapabilities capabilities = connectivityManager
.getNetworkCapabilities(network);
return capabilities != null
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
Tienes razón. El código que ha proporcionado solo verifica si hay una conexión de red. La mejor forma de comprobar si hay una conexión a Internet activa es intentar y conectarse a un servidor conocido a través de http.
public static boolean hasActiveInternetConnection(Context context) {
if (isNetworkAvailable(context)) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1500);
urlc.connect();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
Log.e(LOG_TAG, "Error checking internet connection", e);
}
} else {
Log.d(LOG_TAG, "No network available!");
}
return false;
}
Por supuesto, puede sustituir la URL http://www.google.com
por cualquier otro servidor al que desee conectarse o un servidor que sepa que tiene un buen tiempo de actividad.
Como Tony Cho también señaló en este comentario a continuación , asegúrese de no ejecutar este código en el hilo principal, de lo contrario obtendrá una excepción NetworkOnMainThread (en Android 3.0 o posterior). Use una AsyncTask o Runnable en su lugar.
Si desea utilizar google.com, debe ver la modificación de Jeshurun. En su respuesta , modificó mi código y lo hizo un poco más eficiente. Si te conectas a
HttpURLConnection urlc = (HttpURLConnection)
(new URL("http://clients3.google.com/generate_204")
.openConnection());
y luego verifique el código de respuesta para 204
return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);
entonces no tiene que buscar primero toda la página de inicio de google.
prueba este
public class ConnectionDetector {
private Context _context;
public ConnectionDetector(Context context) {
this._context = context;
}
public boolean isConnectingToInternet() {
if (networkConnectivity()) {
try {
HttpURLConnection urlc = (HttpURLConnection) (new URL(
"http://www.google.com").openConnection());
urlc.setRequestProperty("User-Agent", "Test");
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(3000);
urlc.setReadTimeout(4000);
urlc.connect();
// networkcode2 = urlc.getResponseCode();
return (urlc.getResponseCode() == 200);
} catch (IOException e) {
return (false);
}
} else
return false;
}
private boolean networkConnectivity() {
ConnectivityManager cm = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
}
Deberá agregar el siguiente permiso a su archivo de manifiesto:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Entonces llame así:
if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){
Log.d("internet status","Internet Access");
}else{
Log.d("internet status","no Internet Access");
}
private static NetworkUtil mInstance;
private volatile boolean mIsOnline;
private NetworkUtil() {
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
boolean reachable = false;
try {
Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = process.waitFor();
reachable = (returnVal==0);
} catch (Exception e) {
e.printStackTrace();
}
mIsOnline = reachable;
}
}, 0, 5, TimeUnit.SECONDS);
}
public static NetworkUtil getInstance() {
if (mInstance == null) {
synchronized (NetworkUtil.class) {
if (mInstance == null) {
mInstance = new NetworkUtil();
}
}
}
return mInstance;
}
public boolean isOnline() {
return mIsOnline;
}
Espero que el código anterior te ayude, también asegúrate de tener permiso de Internet en tu aplicación.
public boolean isInternetWorking() {
boolean success = false;
try {
URL url = new URL("https://google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.connect();
success = connection.getResponseCode() == 200;
} catch (IOException e) {
e.printStackTrace();
}
return success;
}
devuelve cierto si internet está realmente disponible
Asegúrate de tener estos dos permisos
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>