Detecta si el dispositivo Android tiene conexión a Internet

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?

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.

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 aquí y aquí 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; } 
 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

   

Si tiene como objective 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); } 

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:

   

Entonces llame así:

 if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){ Log.d("internet status","Internet Access"); }else{ Log.d("internet status","no Internet Access"); } 

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); 

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 { 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.

 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.