web-dev-qa-db-fra.com

Détecter si un appareil Android dispose d'une connexion Internet

Je dois dire si mon appareil dispose d'une connexion Internet ou non. J'ai trouvé beaucoup de réponses comme:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
         = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;
}

(Extrait de Détecter s’il existe une connexion Internet disponible sur Android .)

Mais ce n’est pas correct. Par exemple, si _ je suis connecté à un réseau sans fil qui n’a pas accès à Internet, cette méthode retournera true… Y at-il un moyen de savoir si le périphérique dispose d’une connexion Internet et pas si c'est seulement connecté à quelque chose?

129
Buda Gavril

Tu as raison. Le code que vous avez fourni vérifie uniquement s'il existe une connexion réseau . Le meilleur moyen de vérifier si une connexion Internet est active est de tenter de vous connecter À un serveur connu via 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;
}

Bien sûr, vous pouvez remplacer l'URL http://www.google.com par tout autre serveur auquel vous souhaitez vous connecter, ou par un serveur dont vous savez qu'il a une bonne disponibilité.

Comme Tony Cho l'a également souligné dans ce commentaire ci-dessous , assurez-vous de ne pas exécuter ce code sur le thread principal, sinon vous obtiendrez une exception NetworkOnMainThread (sous Android 3.0 ou version ultérieure). Utilisez plutôt une tâche asynchrone ou une tâche exécutable.

Si vous voulez utiliser google.com, vous devriez regarder la modification de Jeshurun. Dans sa réponse il a modifié mon code et l'a rendu un peu plus efficace. Si vous vous connectez à 

HttpURLConnection urlc = (HttpURLConnection) 
            (new URL("http://clients3.google.com/generate_204")
            .openConnection());

puis vérifiez le code de réponse pour 204

return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);

alors vous n'avez pas à aller chercher la page d'accueil complète de Google en premier.

178
THelper

J'ai légèrement modifié la réponse de THelper, pour utiliser un hack connu qu'Android utilise déjà pour vérifier si le réseau WiFi connecté dispose d'un accès Internet. C’est beaucoup plus efficace de saisir toute la page d’accueil de Google. Voir ici et ici pour plus d'informations.

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;
}
84
Jeshurun
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;
}

retourne vrai si Internet est effectivement disponible 

Assurez-vous d'avoir ces deux permissions

<uses-permission Android:name="Android.permission.INTERNET"/>
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"/>
17
Bilal Shahid

Si vous ciblez Lollipop ou une version supérieure, vous pouvez utiliser la nouvelle classe NetworkCapabilities, à savoir:

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);
}
9
Johan

Vous n'avez pas nécessairement besoin d'établir une connexion HTTP complète. Vous pouvez essayer simplement d'ouvrir une connexion TCP vers un hôte connu et, le cas échéant, vous disposez d'une connexion 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;
  }
}

Ensuite, vérifiez auprès de:

boolean online = hostAvailable("www.google.com", 80);
4
Xiv

essaye celui-là

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

vous devrez ajouter l'autorisation suivante à votre fichier manifeste:

<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
<uses-permission Android:name="Android.permission.INTERNET" />

Alors appelez comme ça:

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

Sur la base des réponses acceptées, j'ai construit cette classe avec un auditeur afin que vous puissiez l'utiliser dans le fil principal:

First : Classe InterntCheck qui vérifie la connexion Internet en arrière-plan, puis appelle une méthode d'écoute avec le résultat.

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

}

Seconde : instancie une instance de la classe dans le fil principal et attend la réponse (si vous avez déjà travaillé avec Firebase api pour Android, cela vous est familier!).

new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() {

        @Override
        public void onComplete(boolean connected) {
           //proceed!
        }
    });

Maintenant, à l'intérieur de la méthode onComplete, vous obtiendrez si le périphérique est connecté à Internet ou non.

3
Aya

Vérifiez le type de wifi dans le gestionnaire de connectivité:

   //check network connection
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean hasNetworkConnection = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    System.out.println("Connection ? : " + hasNetworkConnection);
    //check wifi
    boolean hasWifiConnection = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    System.out.println("Wifi ? : " + hasWifiConnection);

La documentation Android décrit "TYPE_WIFI" comme "une connexion de données WIFI. Les appareils peuvent en supporter plusieurs. '

0
vasmos

La méthode la plus récente utilisée dans documentation consiste à utiliser la variable ConnectivityManager pour interroger le réseau actif et déterminer s'il est connecté à Internet.

public boolean hasInternetConnectivity() {
    ConnectivityManager cm =
        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return (activeNetwork != null &&
                      activeNetwork.isConnectedOrConnecting());
}

Ajoutez ces deux autorisations à votre fichier AndroidManifest.xml:

<uses-permission Android:name="Android.permission.INTERNET"/>
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"/>
0
dynamo
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;
}

J'espère que le code ci-dessus vous aide, assurez-vous également que vous disposez d'une autorisation Internet dans votre application.

0
RaghavPai