Comment vérifier l'accès à Internet sur Android? InetAddress n'expire jamais


658

J'ai obtenu un AsyncTaskqui est censé vérifier l'accès réseau à un nom d'hôte. Mais le doInBackground()n'est jamais expiré. Quelqu'un a une idée?

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

5
Pour vérifier une connexion Internet, le moyen le plus fiable serait probablement d'envoyer un ping à l'un des principaux serveurs de noms, cela pourrait être fait par exemple avec if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) .... Voir ma réponse pour une meilleure mise en œuvre de cela. Btw la réponse acceptée (et bien d'autres ici) vérifie simplement une connexion réseau , pas Internet.
Lévite


4
N'utilisez pas la méthode ping, utilisez plutôt une vérification HTTP. ICMP est bloqué sur certains réseaux, donc le ping ne fonctionnera pas. Par exemple: cela fonctionne parfaitement sur mon wifi domestique, mais ce n'est pas le cas lorsque j'utilise des données mobiles sur le réseau de Vodafone (en Hongrie). Ou combinez les 2 méthodes comme solution de rechange, mais soyez prudent car waitFor () attendra environ 20 secondes même si -w ou -W est utilisé.
Tamás Bolvári


@ TamásBolvári: Encore mieux serait de l'aborder au niveau de la couche TCP. Ce qui devrait vous rapprocher de la vitesse d'un ICMP, avec la fiabilité d'une requête HTTP. J'ai modifié la "réponse ping" en conséquence.
Lévite

Réponses:


556

Connexion réseau / accès Internet

  • isConnectedOrConnecting()(utilisé dans la plupart des réponses) vérifie toute connexion réseau
  • Pour savoir si l'un de ces réseaux dispose d' un accès à Internet , utilisez l'une des méthodes suivantes

A) Ping un serveur (facile)

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

+ pourrait fonctionner sur le thread principal

- ne fonctionne pas sur certains appareils anciens (Galays S3, etc.), il bloque un certain temps si aucune connexion Internet n'est disponible.

B) Se connecter à un socket sur Internet (avancé)

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

+très rapide (de toute façon), fonctionne sur tous les appareils, très fiable

- ne peut pas fonctionner sur le thread d'interface utilisateur

Cela fonctionne de manière très fiable, sur tous les appareils, et est très rapide. Il doit cependant être exécuté dans une tâche distincte (par exemple ScheduledExecutorServiceou AsyncTask).

Questions possibles

  • Est-ce vraiment assez rapide?

    Oui, très vite ;-)

  • Existe-t-il un moyen fiable de vérifier Internet, autre que de tester quelque chose sur Internet?

    Pas autant que je sache, mais faites-le moi savoir et je modifierai ma réponse.

  • Et si le DNS est en panne?

    Le DNS de Google (par exemple 8.8.8.8) est le plus grand DNS public au monde. En 2013, il traitait 130 milliards de demandes par jour. Disons simplement que votre application ne sera probablement pas le sujet du jour.

  • Quelles autorisations sont nécessaires?

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

    Juste un accès Internet - surprise ^^ (Au fait, avez-vous déjà pensé à la façon dont certaines des méthodes suggérées ici pourraient même avoir une colle à distance sur l'accès à Internet, sans cette autorisation?)

 

Extra: AsyncTaskExemple ponctuel

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/RxAndroidExemple ponctuel (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 */}

22
C'est une grande paix de code! Je l'ai trouvé très utile sur les appareils qui utilisent des cartes prépayées! Quand ils manquent d'argent, ils ont accès à Internet, mais pas à Internet. Donc, il ne suffit pas de vérifier la connectivité. MERCI!
Blejzer

10
Gardez à l'esprit que cette approche est bloquante, vous ne devez donc pas l'exécuter dans l'interface utilisateur
Sergii

36
@Levit Ce devrait être la réponse acceptée. La réponse ci-dessus vérifie simplement le réseau n PAS LA CONNEXION INTERNET . Et oui, c'est très rapide. Merci. D'où un vote positif.
Roon13

9
Cette solution ne fonctionne pas pour tous les appareils. Certains appareils retournent toujours 2 comme l'a déclaré @Salmaan. Les appareils que j'ai testés avaient une connexion Internet et la cible ping est le serveur DNS de Google - qui répond aux requêtes ping. Je pense que certains fournisseurs n'autorisent pas les requêtes ping. Par exemple, j'ai testé avec une tablette Samsung 10.1 (4.3), et la solution ne fonctionne pas. Lorsque j'exécute la commande ping via l'utilitaire de ligne de commande, j'obtiens une erreur d'autorisation. La commande ne fonctionne pas non plus sur les émulateurs. Soyez prudent en utilisant cette solution.
Eren Yilmaz

9
Cette approche ne fonctionne pas sur tous les téléphones. Il échoue par exemple sur Samsung Galaxy S3. Voir ici: Pourquoi le ping fonctionne-t-il sur certains appareils et pas sur d'autres?
Adil Hussain

1032

Si l'appareil est en mode avion (ou probablement dans d'autres situations où il n'y a pas de réseau disponible), ce cm.getActiveNetworkInfo()sera le cas null, vous devez donc ajouter une nullvérification.

Modifié ( solution d'Eddie ) ci-dessous:

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnectedOrConnecting();
}

Ajoutez également l'autorisation suivante au AndroidManifest.xml:

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

Un autre petit point, si vous avez absolument besoin d'une connexion réseau à un moment donné, alors il pourrait être préférable d'utiliser netInfo.isConnected()plutôt que netInfo.isConnectedOrConnecting. Je suppose que cela dépend du cas d'utilisation individuel.


109
imo, vous devriez et devez toujours vérifier les exceptions de délai d'attente http car il peut y avoir des situations où un réseau est connecté mais il n'y aurait pas de connexion Internet réelle parce que le seul moyen d'y accéder est par exemple via VPN - de cette façon, vous l'avez, pour par exemple, une connexion WI-FI mais pas de trafic Internet réel. Une autre situation est un blocage du serveur. Ce sont 2 problèmes que j'ai exécutés récemment et le gestionnaire de connexions ne va pas vous aider.
minuit

21
Je suis d'accord avec minuit et Pintu, cette réponse ne devrait pas être la réponse acceptée, elle n'a rien à voir avec le fait de vérifier si vous êtes sur Internet. Par exemple, si le téléphone est connecté à un réseau WiFi avec un portail captif, comme dans un hôtel, cette fonction renverra incorrectement la valeur true. La bonne réponse est d'envoyer une requête ping à un serveur sur Internet public.
miguel

9
lorsqu'il n'y a pas d'Internet qui fonctionne pour mon routeur, si je me connecte au routeur via le wifi, le code ci-dessus revient vrai. Mais, ce n'est pas censé l'être, non? Pouvez-vous m'aider
MoHaN K RaJ

5
J'ai dû ajouter le contexte, sinon context.getSystemServiceça ne marche pas. J'ai eu mon indice ici androidhive.info/2012/07/…
Francisco Corrales Morales

1
Belle façon de vérifier la disponibilité du réseau. Mais comment vérifier l'accès à Internet?
Tamás Bolvári

296

Pas besoin d'être complexe. La manière la plus simple et la plus structurée consiste à utiliser l' ACCESS_NETWORK_STATEautorisation et à créer une méthode connectée

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

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

Vous pouvez également l'utiliser requestRouteToHostsi vous avez un hôte particulier et un type de connexion (wifi / mobile) à l'esprit.

Vous aurez également besoin de:

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

dans votre manifeste Android.


82
il est préférable de faire une vérification nulle au niveau cm.getActiveNetworkInfo (), il a jeté une valeur nulle si aucun réseau actif n'était disponible.
Samuel

voir stackoverflow.com/a/11691676/1979773 pour une explication plus approfondie sur requestRouteToHost ()
Spartako

J'ai dû ajouter le contexte, sinon context.getSystemServiceça ne marche pas. J'ai eu mon indice ici androidhive.info/2012/07/…
Francisco Corrales Morales

9
Cette solution reviendra vraie si vous êtes connecté à un hotspot WiFi, même si ce hotspot n'a PAS de connectivité Internet.
Josh


63

Pour vous mettre getActiveNetworkInfo()au travail, vous devez ajouter ce qui suit au manifeste.

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

Celui-ci devrait être définitivement sous la bonne réponse (trop de temps perdu à comprendre ce qui ne va pas).
Indrek Kõue

2
L'autorisation INTERNET n'est PAS nécessaire pour cela, juste ACCESS_NETWORK_STATE. INTERNET n'est nécessaire que si vous effectuez des connexions vers des sites distants, sans interroger l'état de la radio de l'appareil.
Tom

3
Votre réponse n'est actuellement pas vraiment une réponse, c'est juste un ajout relativement mineur aux autres réponses. Si toutes les autres réponses n'étaient pas là, votre réponse aurait-elle un sens? Pas vraiment. Parce que si cela vaut mieux développer votre réponse avec du code sur la façon de l'utiliser, ou supprimer votre réponse et ajouter les informations dans une autre réponse (vous ne perdrez aucune réputation)
Tim

Attention, getActiveNetworkInfo()est déconseillé dans le niveau 29 de l'API.
Débordement de pile

46

Jetez un œil à la classe ConnectivityManager. Vous pouvez utiliser cette classe pour obtenir des informations sur les connexions actives sur un hôte. http://developer.android.com/reference/android/net/ConnectivityManager.html

EDIT: vous pouvez utiliser

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) 

ou

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_WIFI) 

et analyser l'énumération DetailState de l'objet NetworkInfo retourné

EDIT EDIT: Pour savoir si vous pouvez accéder à un hôte, vous pouvez utiliser

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .requestRouteToHost(TYPE_WIFI, int hostAddress)

Évidemment, j'utilise Context.getSystemService (Context.CONNECTIVITY_SERVICE) comme proxy pour dire

ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();

Pas sûr, mais cela semble être du code pour tester le type de connexion réseau actuellement. Par exemple, sur le WiFi, il n'y a aucune garantie que votre routeur wifi domestique soit connecté à Internet ... pour vérifier que vous avez réellement besoin de faire une demande à un
serveur

1
Il y avait une erreur dans la section EDIT EDIT, j'avais omis l'appel requestRouteToHost (). Relisez la réponse maintenant :)
Chinmay Kanchi

requestRouteToHost est obsolète.
Jahaziel

46

vérifiez ce code ... cela a fonctionné pour moi :)

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

Ensuite, je définis le gestionnaire:

Handler h = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        if (msg.what != 1) { // code if not connected

        } else { // code if connected

        }   
    }
};

... et lancez le test:

isNetworkAvailable(h,2000); // get the answser within 2000 ms

3
Qu'est-ce que Google est en panne? Cela nécessite également l'autorisation INTERNET, qui n'est pas nécessaire pour la tâche donnée. Enfin, cela consomme des données (même si elles sont insignifiantes). Cela ressemble à un tel coup de tête.
Tom

28
@Tom pour être juste, c'est probablement la seule bonne réponse. Les autres exemples montrent simplement si une connexion réseau est disponible et / ou s'il existe une connexion à ce réseau, mais ne répondent pas à la question de savoir si ce réseau peut également établir une connexion à distance (par exemple vers un site Web). Cela répond donc aux affiches Q, et les autres réponses ne le font pas
slinden77

2
@dmmh Oui, c'est malheureusement vrai d'après ce que j'ai vu avec les API Android. Peut-être qu'un simple ping pourrait être meilleur, stackoverflow.com/questions/3905358/… . Si vous étiez vraiment inquiet, vous pourriez même inclure une liste d'adresses IP à envoyer au ping, car même s'il y a très peu de chances que Google tombe en panne, il y a une chance encore plus petite que Google, Bing ET Yahoo soient arrêtés le même jour. . Juste mes pensées.
Tom

10
Il est inutile de faire cette vérification. Si vous allez dépenser le temps système et les ressources réseau pour vous connecter à Google, vous auriez pu les dépenser à la place pour vous connecter à la ressource qui vous intéresse réellement.
Benjamin

16
En Chine, Google a été bloqué !!
Anthone

26

Trouvé et modifié (!) À partir de ce lien :

Dans votre fichier manifeste, ajoutez au moins:

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

Vous avez probablement déjà l'autorisation INTERNET si vous y accédez. Ensuite, une fonction booléenne qui permet de tester la connectivité est:

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

18

J'ai fait ce code, c'est le plus simple et c'est juste un booléen. en demandantif(isOnline()){

Vous obtenez s'il y a une connexion et s'il peut se connecter à une page le code d'état 200(connexion stable).

Assurez - vous d'ajouter le bon INTERNETet les ACCESS_NETWORK_STATEautorisations.

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

6
Peut-être que vous devriez remplacer 200 par HttpURLConnection.HTTP_OK
Yash

5
Et si Google est en panne?
Yauraw Gadav

12

Cela fonctionne pour moi:

Pour vérifier la disponibilité du réseau:

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

Pour vérifier l'accès à 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;
}

c'est une excellente solution pour vérifier si un serveur fonctionne correctement. Merci!
Williew

1
isOnline () ne devrait pas du tout fonctionner sur le thread principal, comme s'il y avait un signal Wi-Fi mais pas d'Internet, cela prendrait trop de temps et bloquerait le thread principal.
humazed

9

Il y a plus d'une façon

Premier moyen, le plus court mais inefficace

Autorisation de l'état du réseau uniquement nécessaire

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

Ensuite, cette méthode,

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

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null &&
                activeNetwork.isConnected();

        return isConnected;

    }

Comme on le voit dans les réponses ConnectivityManagerest une solution, je viens de l'ajouter dans une méthode c'est une méthode simplifiée tout usage
ConnectivityManagerrenvoie vrai s'il y a un accès réseau pas un accès Internet, signifie que votre WiFi est connecté à un routeur mais que le routeur n'a pas Internet il renvoie vrai, il vérifie la disponibilité de la connexion

Deuxièmement, manière efficace

État du réseau et autorisations Internet nécessaires

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

Ensuite, cette classe,

 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
            }

        }


    }

Appel CheckInternetAsyncTask

new CheckInternetAsyncTask(getApplicationContext()).execute();

Quelques explications: -

  • vous devez vérifier Internet AsyncTask, sinon il peut jeter android.os.NetworkOnMainThreadExceptiondans certains cas

  • ConnectivityManager utilisé pour vérifier l'accès au réseau si true envoie une demande (Ping)

  • Request send to http://clients3.google.com/generate_204, Cette URL bien connue est connue pour renvoyer une page vide avec un état HTTP 204, c'est plus rapide et plus efficace que http://www.google.com, lisez ceci . si vous avez un site Web, il est préférable de mettre votre site Web au lieu de Google, uniquement si vous l'utilisez dans l'application

  • Le délai d'attente peut être changé de plage (20 ms -> 2000 ms), 1500 ms est couramment utilisé


2
Grande question, c'est triste que vous n'ayez plus de points. Ce doit être la bonne réponse.
Jhon Fredy Trujillo Ortega

Je suis nouveau sur Android. cependant, c'est une réponse bien couverte et elle attire plus d'attention @ 7569106
Mazen Embaby

1
meilleure et complète réponse, merci. si quelqu'un a un site Web, notez que la condition doit aimer cette urlc.getResponseCode () == 200 et pas besoin de vérifier urlc.getContentLength () == 0
AREF

votre deuxième option se
bloque,

il bloque l'application
nafees ahmed

8

De tout ce que j'ai vu jusqu'à présent, le moyen le plus court et le plus propre devrait être:

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

PS: Cela ne fait pas de ping sur aucun hôte, il vérifie simplement l'état de la connexion, donc si votre routeur n'a pas de connexion Internet et que votre appareil y est connecté, cette méthode retournerait vraie bien que vous n'ayez pas d'Internet.
Pour un test réel, je recommanderais d'exécuter une demande HttpHead (par exemple à www.google.com) et de vérifier l'état, si son 200 OK tout va bien et que votre appareil dispose d'une connexion Internet.


Je voulais mettre cette méthode dans une classe globale, j'ai donc dû utiliser cette version pour pouvoir passer le contexte de l'activité à partir de laquelle je l'appelais. Merci!
RyanG

8

Voici la méthode que j'utilise:

public boolean isNetworkAvailable(final Context context) {
    return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}

Encore mieux, vérifiez qu'il est "connecté":

public boolean isNetworkAvailable(final Context context) {
    final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
    return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}

Voici comment utiliser la méthode:

if (isNetworkAvailable(context)) {
    // code here
} else {
    // code
}

Autorisation nécessaire:

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

https://stackoverflow.com/a/16124915/950427


7

Un cas d'utilisation important sur les appareils mobiles pour garantir l'existence d'une connexion réelle. Il s'agit d'un problème courant lorsqu'un utilisateur mobile pénètre dans un réseau Wifi avec un "portail captif", dans lequel il doit se connecter. J'utilise cette fonction de blocage en arrière-plan pour garantir l'existence d'une connexion.

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

3
+1 pour vérifier réellement la connectivité de bout en bout. Pour la situation "Portail captif", cependant, j'ai constaté que beaucoup passeront le test ci-dessus même si vous ne vous êtes pas connecté - vous obtenez la page de connexion et une réponse 200, quelle que soit l'URL que vous demandez. Donc, j'essaie de frapper une page sur mon propre domaine que je sais n'existe pas et je m'assure que j'obtiens un 404. Alternativement, vous pouvez frapper une page existante connue, assurez-vous que vous obtenez un 200 et vérifiez le contenu qui est retourné pour s'assurer que c'est ce que vous attendez.
GreyBeardedGeek

6

Vous pouvez parcourir toutes les connexions réseau et vérifier s'il y a au moins une connexion 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;
}

6

Pour moi, ce n'était pas une bonne pratique de vérifier l'état de la connexion dans la classe Activity, car

ConnectivityManager cm =
    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

doit être appelé là, ou vous devez pousser votre instance d'activité (contexte) vers la classe du gestionnaire de connexion pour pouvoir vérifier l'état de la connexion là-bas. Lorsqu'aucune connexion disponible (wifi, réseau) j'attrape l' exception 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 cette façon, je peux gérer ce cas avec les autres cas de la même classe (mon serveur répond toujours en retour avec une chaîne json)


6

Ça marche pour moi. Essaye le.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
        URL url = new URL("http://stackoverflow.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());
}}

Cette réponse ne peut pas fonctionner maintenant, car nous ne pouvons pas accéder au réseau sur le thread principal maintenant.
正宗 白 布鞋

1
Je veux dire à partir de l'API niveau 11, cela ne fonctionne pas. Motif: developer.android.com/reference/android/os/… . Si cela fonctionne pour vous, cela signifie que vous exécutez ce code sur un ancien appareil Android. (avant GB).
正宗 白 布鞋

Politique StrictMode.ThreadPolicy = nouveau StrictMode.ThreadPolicy.Builder () .permitAll (). Build (); StrictMode.setThreadPolicy (stratégie); ajoutez ces deux lignes à votre programme pour éviter l'exception de thread principal du réseau
selva_pollachi

Ok, je ne devrais pas dire que cela ne peut pas fonctionner, je dois dire que cela peut fonctionner (par l'ancienne version cible ou la configuration Strictmode) mais est déconseillé. Cela peut provoquer facilement l'ANR. (Avec une configuration de timeout si élevée dans httpurlconnection)
正宗 白 布鞋

ya..vous avez raison .. je mets juste cela parce que c'est aussi l'un des chemin.
selva_pollachi

6

Cette méthode vous donne la possibilité d'une méthode très rapide (pour la rétroaction en temps réel) ou d'une méthode plus lente (pour les contrôles ponctuels qui nécessitent de la fiabilité)

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

5

Im utilisant ce code au lieu 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();
    }

Ce serait formidable si vous aviez clarifié si l'IOException signifie pas de connexion Internet et à quel point il pourrait être fiable.
Milad.Nozari

5

Il n'est pas complexe de vérifier l'état de la connectivité réseau / Internet Android. Le cours ci DetectConnection- dessous vous aidera à vérifier ce statut:

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

Pour plus de détails, consultez Comment vérifier l'état du réseau Android / de la connectivité Internet


5

Meilleure approche:

public static boolean isOnline() {
    try {
    InetAddress.getByName("google.com").isReachable(3);

    return true;
    } catch (UnknownHostException e){
    return false;
    } catch (IOException e){
    return false;
    }
    }

1
J'aime cette approche mais je dois souligner certaines choses. isReachable () renvoie un booléen, donc au lieu de retourner true dans la section try, vous pouvez le faire comme boolean connected = InetAddress.getByName ("google.com"). isReachable (3); puis revenez connecté. De plus, isReacheable lève les exceptions IOException et IllegalArgumentException, donc ce sera une bonne idée de remplacer UnknownHostException par IllegalArgumentException et d'inclure un troisième catch: catch (Exception E).
Yash

2
Mais alors, isReachable utilise ICMP qui pourrait nécessiter des privilèges root et utilise le port 7 qui n'a généralement aucun service en cours d'exécution sur les derniers systèmes. Par conséquent, la meilleure façon de vérifier l'itinéraire vers un service en ligne est d'utiliser le protocole TCP standard; d'où un vote négatif.
Yash

5

Voici le code de ma Utilsclasse:

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

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

}

Comme tous les autres qui n'ont pas lu le problème, cela ne résout pas le problème, car il ne vérifie pas vraiment la connexion à Internet. Une connexion à un point d'accès Wi-Fi local redeviendra vraie, même si le point d'accès ne vous permettra pas d'accéder à Internet.
Pedro Pombeiro

5

Vous pouvez utiliser cette méthode pour détecter la disponibilité du réseau-

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

5

J'ai appliqué la solution fournie par @Levit et créé une fonction qui n'appellera pas la demande Http supplémentaire.

Cela résoudra l'erreur 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;
}

Maintenant, appelez ça comme,

if (!isInternetAvailable(getActivity())) {
     //Show message
} else {
     //Perfoem the api request
}

4

1
Mais la méthode décrite ici ne vérifie pas vraiment la connexion Internet, elle vérifie simplement si une connexion est établie (qu'elle ait accès à Internet ou non). Le titre de ce document officiel est vraiment trompeur.
Tiago

2
Il est préférable de répondre à la question que de simplement publier un lien vers des informations. Et si le lien s'éteint? Nous n'aurons pas de réponse.
Jose Llausas

4

J'ai parcouru toutes les réponses et je trouve ma propre réponse qui vérifie d'abord si Internet est disponible et si Internet est disponible, puis il vérifie s'il est actif ou non.

J'ai inclus toutes les méthodes et classes nécessaires pour vérifier la connexion Internet active.

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

Vous pouvez vérifier si Internet est actif en utilisant le code ci-dessous:

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

Un meilleur threading de pack dans vos NetworkUtils et donc "forcez" le développeur à ne pas mal utiliser votre méthode
Ewoks

Pour supprimer un supplément si condition. if ((NetworkUtils.isInternetActiveWithPing () == NetworkUtils.STATUS_CONNECTED) || NetworkUtils.isInternetActiveWithInetAddress ()) {// Do Network Operation} else {// Error Message}
Jawad Zeb

4

Très important de vérifier si nous avons une connectivité avec isAvailable () et s'il est possible d'établir une connexion avec 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();
}

et vous pouvez déterminer le type de réseau WiFi actif :

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

ou Móvil mobile :

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

n'oubliez pas les autorisations:

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

Beau résumé des composants de connectivité de l'appareil, il suffit de les envelopper dans les instructions try / catch pour éviter les plantages. De même, faites simplement vos appels HttpURLConnection de routine, tant qu'ils sont enveloppés dans la gestion des erreurs, vous saurez bientôt si vous avez ou non une connexion Internet
rangi

4

Kotlin et coroutines

J'ai placé la fonction dans un ViewModel, qui a le viewModelScope. En utilisant un observable LiveDataj'informe une activité sur la connexion.

ViewModel

 fun checkInternetConnection() {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val timeoutMs = 3000
                    val socket = Socket()
                    val socketAddress = InetSocketAddress("8.8.8.8", 53)

                    socket.connect(socketAddress, timeoutMs)
                    socket.close()

                    withContext(Dispatchers.Main) {
                        _connection.value = true
                    }
                }
                catch(ex: IOException) {
                    withContext(Main) {
                        _connection.value = false
                    }
                }
            }
        }
    }
 private val _connection = MutableLiveData<Boolean>()
 val connection: LiveData<Boolean> = _connection

Activité

 private fun checkInternetConnection() {
     viewModel.connection.observe(this) { hasInternet ->
         if(!hasInternet) {
             //hasn't connection
         }
         else {
            //has connection
         }
     }
  }

3

Créez simplement la classe suivante qui vérifie une connexion 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;
    }
}

Cette classe contient simplement une méthode qui renvoie la valeur booléenne de l'état de la connexion. Par conséquent, en termes simples, si la méthode trouve une connexion valide à Internet, la valeur de retour est true, sinonfalse si aucune connexion valide n'est trouvée.

La méthode suivante dans MainActivity appelle ensuite le résultat de la méthode décrite précédemment et invite l'utilisateur à agir en conséquence:

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

Dans le code ci-dessus, si le résultat est faux (par conséquent, il n'y a pas de connexion Internet, l'utilisateur est redirigé vers le panneau Wi-Fi Android, où il est invité à se connecter à un point d'accès Wi-Fi.


3

Mise à jour 29/06/2015 Si vous utilisez Xamarin.Android et souhaitez vérifier la connectivité, vous pouvez utiliser un package Nuget qui vous offrirait cette fonctionnalité sur plusieurs plates-formes. Les bons candidats sont ici et ici . [Fin de la mise à jour]

Les réponses ci-dessus sont assez bonnes, mais elles sont toutes en Java et presque toutes vérifient une connectivité. Dans mon cas, je devais avoir une connectivité avec un type de connexion spécifique et je développe sur Xamarin.Android. De plus, je ne passe pas de référence à mes activités Contexte dans la couche Matériel, j'utilise le Contexte d'application. Voici donc ma solution, au cas où quelqu'un viendrait ici avec des exigences similaires. Je n'ai pas fait de test complet cependant, mettra à jour la réponse une fois mes tests terminés

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
    }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.