studio - detecting internet connection android
¿Cómo comprobar el acceso a internet en Android? InetAddress nunca termina el tiempo (30)
AsyncTask
una AsyncTask
que se supone que comprueba el acceso de red a un nombre de host. Pero el doInBackground()
nunca se agota. Alguien tiene una pista?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
Conexión de red / acceso a internet
-
isConnectedOrConnecting()
(usado 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 una de las 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 rato si no hay internet disponible.
B) Conectarse a un Socket 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 lo suficientemente rápido?
Sí, muy rápido ;-)
¿No hay una forma confiable de verificar Internet, aparte de probar algo en Internet?
No lo que sé, pero házmelo saber y editaré mi respuesta.
¿Qué pasa si el DNS está fuera de servicio?
El DNS de Google (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 al día. Digamos que tu aplicación probablemente no sea la comidilla del día.¿Qué permisos se requieren?
<uses-permission android:name="android.permission.INTERNET" />
Solo acceso a Internet: sorpresa ^^ (¿Alguna vez has pensado en cómo algunos de los métodos sugeridos aquí podrían incluso tener una conexión remota con el acceso a Internet, sin este permiso?)
Extra: Ejemplo de AsyncTask
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: Ejemplo de One-shot 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 */}
Aquí está el método que utilizo:
public boolean isNetworkAvailable(final Context context) {
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}
Aún mejor, asegúrese de que esté "conectado":
public boolean isNetworkAvailable(final Context context) {
final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}
Aquí es cómo utilizar el método:
if (isNetworkAvailable(context)) {
// code here
} else {
// code
}
Permiso necesario:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
https://.com/a/16124915/950427
De todo lo que he visto hasta ahora, el camino más corto y limpio debería ser:
public final static boolean isConnected( Context context )
{
final ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
PD: Esto no hace ping a ningún host, solo comprueba el estado de la conexión, por lo que si su enrutador no tiene conexión a Internet y su dispositivo está conectado a este, este método devolverá el valor verdadero aunque no tenga Internet.
Para una prueba real, recomendaría ejecutar una solicitud de HttpHead (por ejemplo, a www.google.com) y verificar el estado, si su 200 OK está bien, su dispositivo tiene una conexión a Internet.
Echa un vistazo a la clase ConnectivityManager. Puede utilizar esta clase para obtener información sobre las conexiones activas en un host. http://developer.android.com/reference/android/net/ConnectivityManager.html
EDITAR: se puede utilizar
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
o
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
y analizar la enumeración de DetailState del objeto NetworkInfo devuelto
EDITAR EDITAR: para averiguar si puede acceder a un host, puede usar
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.requestRouteToHost(TYPE_WIFI, int hostAddress)
Obviamente, estoy usando Context.getSystemService (Context.CONNECTIVITY_SERVICE) como un proxy para decir
ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
El siguiente es el código de mi clase de Utils
:
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Encontrado en y modificado (!) Desde este link :
En su archivo manifiesto agregue al menos:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Probablemente ya tenga el permiso de INTERNET si está accediendo a él. Entonces, una función booleana que permite probar la conectividad es:
private boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected()) {
return true;
} else {
Log.v(TAG, "Internet Connection Not Present");
return false;
}
}
Estoy usando este código en lugar de InetAddress:
try {
URL url = new URL("http://"+params[0]);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "Android Application:"+Z.APP_VERSION);
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1000 * 30); // mTimeout is in seconds
urlc.connect();
if (urlc.getResponseCode() == 200) {
Main.Log("getResponseCode == 200");
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Funciona para mí. Pruébalo.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
URL url = new URL("http://.com/posts/11642475/edit" );
//URL url = new URL("http://www.nofoundwebsite.com/" );
executeReq(url);
Toast.makeText(getApplicationContext(), "Webpage is available!", Toast.LENGTH_SHORT).show();
}
catch(Exception e) {
Toast.makeText(getApplicationContext(), "oops! webpage is not available!", Toast.LENGTH_SHORT).show();
}
}
private void executeReq(URL urlObject) throws IOException
{
HttpURLConnection conn = null;
conn = (HttpURLConnection) urlObject.openConnection();
conn.setReadTimeout(30000);//milliseconds
conn.setConnectTimeout(3500);//milliseconds
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Start connect
conn.connect();
InputStream response =conn.getInputStream();
Log.d("Response:", response.toString());
}}
Funciona para mí:
Para verificar la disponibilidad de la red:
private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();}
Para verificar el acceso a internet:
public Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
Hay mas de una manera
Primero, camino más corto pero ineficiente.
Solo se necesita permiso de estado de red
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Entonces este método,
public boolean activeNetwork () {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
return isConnected;
}
Como se ve en las respuestas, ConnectivityManager
es una solución, solo lo agregué dentro de un método, este es un método simplificado que todos usan
ConnectivityManager
devuelve verdadero si hay un acceso a la red, no acceso a Internet, significa que si su WiFi está conectado a un enrutador pero el enrutador no tiene internet, devuelve verdadero, verifica la disponibilidad de la conexión
Segundo camino eficiente
Estado de la red y permisos de Internet necesarios
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Entonces esta clase,
public class CheckInternetAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private Context context;
public CheckInternetAsyncTask(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(Void... params) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
if (isConnected) {
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();
if (urlc.getResponseCode() == 204 &&
urlc.getContentLength() == 0)
return true;
} catch (IOException e) {
Log.e("TAG", "Error checking internet connection", e);
return false;
}
} else {
Log.d("TAG", "No network available!");
return false;
}
return null;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.d("TAG", "result" + result);
if(result){
// do ur code
}
}
}
Llamar a CheckInternetAsyncTask
new CheckInternetAsyncTask(getApplicationContext()).execute();
Algunas explicaciones: -
tienes que verificar Internet en
AsyncTask
, de lo contrario puede lanzarandroid.os.NetworkOnMainThreadException
en algunos casosConnectivityManager
utiliza para verificar el acceso a la red si la solicitud de envío es verdadera (Ping)La solicitud se envía a
http://clients3.google.com/generate_204
. Se sabe que esta URL conocida devuelve una página vacía con un estado HTTP 204, esto es más rápido y más eficiente quehttp://www.google.com
, lea this Si tiene un sitio web, es preferible que lo haga en lugar de Google, solo si lo usa dentro de la aplicación.Se puede cambiar el intervalo de tiempo de espera (20ms -> 2000ms), se utiliza comúnmente 1500ms
Hice este código, es el más simple y es solo un booleano. preguntando if(isOnline()){
Se obtiene si hay una conexión y si puede conectarse a una página con el código de estado 200
(conexión estable).
Asegúrese de agregar los permisos correctos de INTERNET
y ACCESS_NETWORK_STATE
.
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
Mejor enfoque:
public static boolean isOnline() {
try {
InetAddress.getByName("google.com").isReachable(3);
return true;
} catch (UnknownHostException e){
return false;
} catch (IOException e){
return false;
}
}
No es complejo verificar el estado de conectividad de red / internet de Android. La siguiente clase de DetectConnection
lo ayudará a verificar este estado:
import android.content.Context;
import android.net.ConnectivityManager;
public class DetectConnection {
public static boolean checkInternetConnection(Context context) {
ConnectivityManager con_manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (con_manager.getActiveNetworkInfo() != null
&& con_manager.getActiveNetworkInfo().isAvailable()
&& con_manager.getActiveNetworkInfo().isConnected()) {
return true;
} else {
return false;
}
}
}
Para más detalles, visite Cómo verificar el estado de la conexión / red de Android de Android
No hace falta ser complejo. La forma más sencilla y de forma marco es usar el permiso ACCESS_NETWORK_STATE
y simplemente hacer un método conectado
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
También puede usar requestRouteToHost
si tiene un host particular y un tipo de conexión (wifi / móvil) en mente.
También necesitarás:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
en su manifiesto android.
Para mí no era una buena práctica verificar el estado de conexión en la clase de actividad, porque
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
debe llamarse allí, o debe presionar su instancia de Actividad (contexto) a la clase de manejador de conexión para poder verificar el estado de la conexión allí. Cuando no hay conexión disponible (wifi, red), detecto la excepción UnknownHostException :
JSONObject jObj = null;
Boolean responded = false;
HttpGet requestForTest = new HttpGet("http://myserver.com");
try {
new DefaultHttpClient().execute(requestForTest);
responded = true;
} catch (UnknownHostException e) {
jObj = new JSONObject();
try {
jObj.put("answer_code", 1);
jObj.put("answer_text", "No available connection");
} catch (Exception e1) {}
return jObj;
} catch (IOException e) {
e.printStackTrace();
}
De esta manera puedo manejar este caso junto con los otros casos en la misma clase (mi servidor siempre responde con una cadena json)
Para que getActiveNetworkInfo()
funcione, debe agregar lo siguiente al manifiesto.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Puede recorrer todas las conexiones de red y comprobar si hay al menos una conexión disponible:
public boolean isConnected() {
boolean connected = false;
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
&& ni.isConnected() && ni.isAvailable()) {
connected = true;
}
}
}
return connected;
}
Si el dispositivo está en modo avión (o, presumiblemente, en otras situaciones donde no hay una red disponible), cm.getActiveNetworkInfo()
será null
, por lo que debe agregar una comprobación null
.
Modificado ( la solución de Eddie ) a continuación:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
También agregue el siguiente permiso al AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Otro punto pequeño, si absolutamente necesita una conexión de red en el momento dado, sería mejor usar netInfo.isConnected()
lugar de netInfo.isConnectedOrConnecting
. Sin embargo, supongo que esto depende del caso de uso individual.
Un caso de uso importante en dispositivos móviles es asegurar que exista una conexión real. Este es un problema común cuando un usuario móvil ingresa a una red Wifi con un "Portal cautivo", en el que necesita iniciar sesión. Utilizo esta función de bloqueo en segundo plano para garantizar que exista una conexión.
/*
* Not Thread safe. Blocking thread. Returns true if it
* can connect to URL, false and exception is logged.
*/
public boolean checkConnectionHttps(String url){
boolean responded = false;
HttpGet requestTest = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient client = new DefaultHttpClient(params);
try {
client.execute(requestTest);
responded = true;
} catch (ClientProtocolException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
} catch (IOException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
e.printStackTrace();
}
return responded;
}
revisa este código ... funcionó para mí :)
public static void isNetworkAvailable(final Handler handler, final int timeout) {
// ask fo message ''0'' (not connected) or ''1'' (connected) on ''handler''
// the answer must be send before before within the ''timeout'' (in milliseconds)
new Thread() {
private boolean responded = false;
@Override
public void run() {
// set ''responded'' to TRUE if is able to connect with google mobile (responds fast)
new Thread() {
@Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest); // can last...
responded = true;
}
catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while(!responded && (waited < timeout)) {
sleep(100);
if(!responded ) {
waited += 100;
}
}
}
catch(InterruptedException e) {} // do nothing
finally {
if (!responded) { handler.sendEmptyMessage(0); }
else { handler.sendEmptyMessage(1); }
}
}
}.start();
}
Luego, defino el manejador:
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
} else { // code if connected
}
}
};
... y lanzar la prueba:
isNetworkAvailable(h,2000); // get the answser within 2000 ms
Actualización 29/06/2015 Si está utilizando Xamarin.Android y desea verificar la conectividad, puede usar un paquete Nuget que le daría esta funcionalidad en múltiples plataformas. Los buenos candidatos están here y here . [Fin de la actualización]
Las respuestas anteriores son bastante buenas, pero todas están en Java, y casi todas ellas verifican la conectividad. En mi caso, necesitaba tener conectividad con un tipo específico de conexión y estoy desarrollando en Xamarin.Android. Además, no paso una referencia a mi contexto de actividades en la capa de hardware, uso el contexto de aplicación. Así que aquí está mi solución, en caso de que alguien venga aquí con requisitos similares. Sin embargo, no he realizado pruebas completas, actualizaré la respuesta una vez que haya terminado con mis pruebas
using Android.App;
using Android.Content;
using Android.Net;
namespace Leopard.Mobile.Hal.Android
{
public class AndroidNetworkHelper
{
public static AndroidNetworkStatus GetWifiConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Wifi);
}
public static AndroidNetworkStatus GetMobileConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Mobile);
}
#region Implementation
private static AndroidNetworkStatus GetConnectivityStatus(ConnectivityType connectivityType)
{
var connectivityManager = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService);
var wifiNetworkInfo = connectivityManager.GetNetworkInfo(connectivityType);
var result = GetNetworkStatus(wifiNetworkInfo);
return result;
}
private static AndroidNetworkStatus GetNetworkStatus(NetworkInfo wifiNetworkInfo)
{
var result = AndroidNetworkStatus.Unknown;
if (wifiNetworkInfo != null)
{
if (wifiNetworkInfo.IsAvailable && wifiNetworkInfo.IsConnected)
{
result = AndroidNetworkStatus.Connected;
}
else
{
result = AndroidNetworkStatus.Disconnected;
}
}
return result;
}
#endregion
}
public enum AndroidNetworkStatus
{
Connected,
Disconnected,
Unknown
}
Este método le da la opción de un método realmente rápido (para retroalimentación en tiempo real) o un método más lento (para verificaciones que requieren confiabilidad)
public boolean isNetworkAvailable(bool SlowButMoreReliable) {
bool Result = false;
try {
if(SlowButMoreReliable){
ConnectivityManager MyConnectivityManager = null;
MyConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo MyNetworkInfo = null;
MyNetworkInfo = MyConnectivityManager.getActiveNetworkInfo();
Result = MyNetworkInfo != null && MyNetworkInfo.isConnected();
} else
{
Runtime runtime = Runtime.getRuntime();
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int i = ipProcess.waitFor();
Result = i== 0;
}
} catch(Exception ex)
{
//Common.Exception(ex); //This method is one you should have that displays exceptions in your log
}
return Result;
}
He aplicado la solución provista por @Levit y he creado una función que no llamará a la Solicitud Http extra.
Solucionara el error Unable to Resolve Host
public static boolean isInternetAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null) return false;
switch (activeNetwork.getType()) {
case ConnectivityManager.TYPE_WIFI:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
case ConnectivityManager.TYPE_MOBILE:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
default:
return false;
}
return false;
}
private static boolean isInternet() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
Debug.i(exitValue + "");
return (exitValue == 0);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
Ahora llamalo como
if (!isInternetAvailable(getActivity())) {
//Show message
} else {
//Perfoem the api request
}
He revisado todas las respuestas y se me ocurre una respuesta que primero comprueba si Internet está disponible y si Internet está disponible y luego verifica si está activo o no.
He incluido todos los métodos y clases necesarios para verificar la conexión activa a Internet.
NetworkUtils.class
public class NetworkUtils {
public static final int STATUS_CONNECTED = 0 ;
public static boolean isInternetAvailable(Context ctx){
ConnectivityManager cm = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public static int isInternetActiveWithPing() {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = process.waitFor();
return exitValue;
} catch (Exception ex) {
return -1;
}
}
public static boolean isInternetActiveWithInetAddress() {
try {
InetAddress inetAddress = InetAddress.getByName("www.google.com");
return inetAddress != null && !inetAddress.toString().equals("");
} catch (Exception ex) {
return false;
}
}
public static void displayInternetConnectionMessage(Context ctx){
Toast.makeText(ctx, "Check Internet Connection", Toast.LENGTH_SHORT).show();
}
}
Puede verificar si Internet está activo usando el siguiente código:
private void checkInternetConnection() {
if (NetworkUtils.isInternetAvailable(this)) {
new Thread(new Runnable() {
@Override
public void run() {
if (NetworkUtils.isInternetActiveWithPing() == NetworkUtils.STATUS_CONNECTED) {
performNetworkingOperations();
} else {
if (NetworkUtils.isInternetActiveWithInetAddress()) {
performNetworkingOperations();
} else {
displayConnectionMessage();
}
}
}
}).start();
} else {
displayConnectionMessage();
}
}
private void performNetworkingOperations() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Internet is Available", Toast.LENGTH_SHORT).show();
}
});
}
private void displayConnectionMessage() {
runOnUiThread(new Runnable() {
@Override
public void run() {
NetworkUtils.displayInternetConnectionMessage(MainActivity.this);
}
});
}
Puedes usar este método para detectar la disponibilidad de la red.
public static boolean isDeviceOnline(Context context) {
boolean isConnectionAvail = false;
try {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo.isConnected();
} catch (Exception e) {
e.printStackTrace();
}
return isConnectionAvail;
}
Solo crea la siguiente clase que busca una conexión a internet:
public class ConnectionStatus {
private Context _context;
public ConnectionStatus(Context context) {
this._context = context;
}
public boolean isConnectionAvailable() {
ConnectivityManager connectivity = (ConnectivityManager) _context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
}
Esta clase simplemente contiene un método que devuelve el valor booleano del estado de conexión. Por lo tanto, en términos simples, si el método encuentra una conexión válida a Internet, el valor de retorno es true
, de lo contrario, false
si no se encuentra una conexión válida.
El siguiente método en MainActivity luego llama al resultado del método descrito anteriormente, y le pide al usuario que actúe en consecuencia:
public void addListenerOnWifiButton() {
Button btnWifi = (Button)findViewById(R.id.btnWifi);
iia = new ConnectionStatus(getApplicationContext());
isConnected = iia.isConnectionAvailable();
if (!isConnected) {
btnWifi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
Toast.makeText(getBaseContext(), "Please connect to a hotspot",
Toast.LENGTH_SHORT).show();
}
});
}
else {
btnWifi.setVisibility(4);
warning.setText("This app may use your mobile data to update events and get their details.");
}
}
En el código anterior, si el resultado es falso, (por lo tanto, no hay conexión a Internet, el usuario es llevado al panel de wi-fi de Android, donde se le solicita que se conecte a un punto de acceso de Wi-Fi).
Esto está cubierto en los documentos de Android http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
Las otras respuestas que usan ConnectivityManager son incorrectas porque tener una conexión de red no significa que tenga acceso a Internet. Por ejemplo, el usuario puede estar conectado al portal WiFi de una cafetería pero no puede acceder a Internet. Para comprobar que se puede acceder a Internet, debe intentar conectarse a un servidor real. Normalmente, cuando quiere hacer esto, tiene en mente un servidor específico al que desea conectarse, así que continúe y verifique si puede conectarse a ese servidor. Aquí hay un método simple para verificar la conectividad a un servidor.
private boolean isOnTheInternet() {
try {
URLConnection urlConnection = new URL("http://yourserver").openConnection();
urlConnection.setConnectTimeout(400);
urlConnection.connect();
return true;
} catch (Exception e) {
return false;
}
}
El motivo para configurar ConnectTimeout es que, de lo contrario, el tiempo de espera de TCP es el predeterminado, que puede durar muchos segundos.
Tenga en cuenta también que Android no le permitirá ejecutar esto en su hilo principal.
Muy importante para comprobar si tenemos conectividad con isAvailable() y si es posible establecer una conexión con isConnected()
private static ConnectivityManager manager;
public static boolean isOnline(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}
y puede derterminar el tipo de red activa de WiFi :
public static boolean isConnectedWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}
o Móvil :
public static boolean isConnectedMobile(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
}
No olvides los permisos:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
public class Network {
Context context;
public Network(Context context){
this.context = context;
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}