Wie überprüfe ich den Internetzugang auf Android? InetAddress läuft nie ab

657

Ich habe eine AsyncTask, die den Netzwerkzugriff auf einen Hostnamen überprüfen soll. Aber das doInBackground()ist nie abgelaufen. Hat jemand eine Ahnung?

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();
    }   
}
Vidar Vestnes
quelle
5
Um nach einer Internetverbindung zu suchen, ist es wahrscheinlich am zuverlässigsten, einen der wichtigsten Nameserver anzupingen. Dies kann beispielsweise mit geschehen if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) .... Siehe meine Antwort für eine schönere Implementierung davon. Bei der akzeptierten Antwort (und vielen anderen hier) wird nur nach einer Netzwerkverbindung gesucht , nicht nach dem Internet.
Levite
4
Verwenden Sie nicht die Ping-Methode, sondern eine HTTP-Prüfung. ICMP ist in einigen Netzwerken blockiert, sodass Ping nicht funktioniert. Beispiel: Es funktioniert perfekt in meinem Heim-WLAN, aber nicht, wenn ich mobile Daten im Vodafone-Netzwerk (in Ungarn) verwende. Oder kombinieren Sie die beiden Methoden als Fallback, aber seien Sie vorsichtig, da waitFor () etwa 20 Sekunden wartet, selbst wenn -w oder -W verwendet wird.
Tamás Bolvári
Überprüfen Sie dies: stackoverflow.com/a/39766506/3806413
0xAliHn
@ TamásBolvári: Noch besser wäre es, es auf der TCP-Ebene anzugehen. Damit sollten Sie sich der Geschwindigkeit eines ICMP mit der Zuverlässigkeit einer HTTP-Anforderung annähern. Ich habe die "Ping-Antwort" entsprechend bearbeitet.
Levite

Antworten:

550

Netzwerkverbindung / Internetzugang

  • isConnectedOrConnecting()Kontrollen für alle (in den meisten Antworten verwendet) Netzwerk - Verbindung
  • Verwenden Sie eine der folgenden Methoden, um festzustellen, ob eines dieser Netzwerke über einen Internetzugang verfügt

A) Pingen Sie einen Server (einfach)

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

+ könnte auf Haupt-Thread laufen

- funktioniert auf einigen alten Geräten (Galays S3 usw.) nicht, blockiert eine Weile, wenn kein Internet verfügbar ist.

B) Stellen Sie eine Verbindung zu einer Steckdose im Internet her (erweitert)

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

+sehr schnell (so oder so), funktioniert auf allen Geräten, sehr zuverlässig

- kann nicht auf dem UI-Thread ausgeführt werden

Dies funktioniert auf jedem Gerät sehr zuverlässig und ist sehr schnell. Es muss jedoch in einer separaten Aufgabe ausgeführt werden (z . B. ScheduledExecutorServiceoder AsyncTask).

Mögliche Fragen

  • Ist es wirklich schnell genug?

    Ja sehr schnell ;-)

  • Gibt es keine zuverlässige Möglichkeit, das Internet zu überprüfen, außer etwas im Internet zu testen?

    Nicht so weit ich weiß, aber lass es mich wissen, und ich werde meine Antwort bearbeiten.

  • Was ist, wenn der DNS ausgefallen ist?

    Google DNS (z. B. 8.8.8.8) ist das größte öffentliche DNS der Welt. Ab 2013 wurden täglich 130 Milliarden Anfragen bearbeitet. Sagen wir einfach, Ihre App wäre wahrscheinlich nicht das Tagesgespräch.

  • Welche Berechtigungen sind erforderlich?

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

    Nur Internetzugang - Überraschung ^^ (Übrigens haben Sie jemals darüber nachgedacht, wie einige der hier vorgeschlagenen Methoden ohne diese Erlaubnis sogar einen Fernkleber über den Internetzugang haben könnten?)

 

Extra: One-Shot- AsyncTaskBeispiel

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: One-Shot- RxJava/RxAndroidBeispiel (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 */}
Levit
quelle
22
Das ist ein großer Code-Frieden! Ich fand es sehr nützlich auf Geräten, die Prepaid-Karten verwenden! Wenn ihnen das Geld ausgeht, steht ihnen ein Internetzugang zur Verfügung, aber kein Internet. Es reicht also nicht aus, nur auf Konnektivität zu prüfen. VIELEN DANK!
Blejzer
10
Denken Sie daran, dass dieser Ansatz blockiert ist, sodass Sie ihn nicht in der Benutzeroberfläche ausführen sollten
Sergii
36
@Levit Dies sollte die akzeptierte Antwort sein. Die obige Antwort überprüft nur Netzwerk n NICHT INTERNETVERBINDUNG . Und ja das geht sehr schnell. Vielen Dank. Daher Upvote.
Roon13
9
Diese Lösung funktioniert nicht für alle Geräte. Einige Geräte geben immer 2 zurück, wie @Salmaan angegeben hat. Die von mir getesteten Geräte hatten eine Internetverbindung und das Ping-Ziel ist der Google DNS-Server, der auf Ping-Anfragen reagiert. Ich denke, einige Anbieter erlauben keine Ping-Anfragen. Ich habe zum Beispiel mit einem Samsung 10.1-Tablet (4.3) getestet und die Lösung funktioniert nicht. Wenn ich den Befehl ping über das Befehlszeilenprogramm ausführe, wird ein Berechtigungsfehler angezeigt. Der Befehl funktioniert auch nicht mit Emulatoren. Seien Sie vorsichtig mit dieser Lösung.
Eren Yilmaz
9
Dieser Ansatz funktioniert nicht auf allen Telefonen. Es schlägt zum Beispiel auf Samsung Galaxy S3 fehl. Siehe hier: Warum funktioniert Ping auf einigen Geräten und nicht auf anderen?
Adil Hussain
1032

Befindet sich das Gerät im Flugzeugmodus (oder vermutlich in anderen Situationen, in denen kein Netzwerk verfügbar ist), cm.getActiveNetworkInfo()müssen nullSie eine nullPrüfung hinzufügen .

Modifiziert ( Eddies Lösung ) unten:

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

Fügen Sie außerdem die folgende Berechtigung hinzu AndroidManifest.xml:

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

Ein weiterer kleiner Punkt: Wenn Sie zum angegebenen Zeitpunkt unbedingt eine Netzwerkverbindung benötigen, ist es möglicherweise besser, diese zu verwenden netInfo.isConnected()als netInfo.isConnectedOrConnecting. Ich denke, dies hängt jedoch vom jeweiligen Anwendungsfall ab.

gar
quelle
109
Imo sollten und müssen Sie immer noch nach http-Timeout-Ausnahmen suchen, da es Situationen geben kann, in denen ein Netzwerk verbunden ist, aber keine tatsächliche Internetverbindung besteht, da der einzige Weg, darauf zuzugreifen, beispielsweise über VPN ist - auf diese Weise haben Sie z Beispiel: WI-FI-Verbindung, aber kein tatsächlicher Internetverkehr. Eine andere Situation ist ein Server-Hang-On. Dies sind zwei Probleme, die ich kürzlich ausgeführt habe, und der Verbindungsmanager wird dort nicht helfen.
Mitternacht
21
Ich stimme Mitternacht und Pintu zu, diese Antwort sollte nicht die akzeptierte Antwort sein, sie hat nichts damit zu tun, zu überprüfen, ob Sie im Internet sind. Wenn das Telefon beispielsweise wie in einem Hotel mit einem WiFi-Netzwerk mit einem Captive-Portal verbunden ist, gibt diese Funktion fälschlicherweise true zurück. Die richtige Antwort ist das Pingen eines Servers im öffentlichen Internet.
Miguel
9
Wenn für meinen Router kein Internet funktioniert und ich über WLAN eine Verbindung zum Router herstelle, gibt der obige Code true zurück. Aber es soll nicht sein, oder? Können Sie mir helfen
MoHaN K RaJ
5
Ich musste den Kontext hinzufügen, sonst context.getSystemServicefunktioniert es nicht. Ich habe meinen Hinweis hier androidhive.info/2012/07/…
Francisco Corrales Morales
1
Gute Möglichkeit, die Netzwerkverfügbarkeit zu überprüfen. Aber wie kann man den Internetzugang überprüfen?
Tamás Bolvári
296

Keine Notwendigkeit, komplex zu sein. Die einfachste und einfachste ACCESS_NETWORK_STATEMethode besteht darin, die Berechtigung zu verwenden und nur eine verbundene Methode zu erstellen

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

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

Sie können es auch verwenden, requestRouteToHostwenn Sie einen bestimmten Host- und Verbindungstyp (WLAN / Mobil) im Auge haben.

Sie benötigen außerdem:

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

in Ihrem Android-Manifest.

Eddie
quelle
82
Es ist besser, eine Nullprüfung auf cm.getActiveNetworkInfo () -Ebene durchzuführen. Es wurde eine Null ausgegeben, wenn kein aktives Netzwerk verfügbar war.
Samuel
siehe stackoverflow.com/a/11691676/1979773 für eine tiefere exaplanation über requestRouteToHost ()
Spartako
Ich musste den Kontext hinzufügen, sonst context.getSystemServicefunktioniert es nicht. Ich habe meinen Hinweis hier androidhive.info/2012/07/…
Francisco Corrales Morales
9
Diese Lösung gibt true zurück, wenn Sie mit einem WLAN-Hotspot verbunden sind, auch wenn dieser Hotspot KEINE Internetverbindung hat.
Josh
63

Um getActiveNetworkInfo()zur Arbeit zu gelangen , müssen Sie dem Manifest Folgendes hinzufügen.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Azelez
quelle
Dieser sollte definitiv unter der richtigen Antwort sein (verschwendete zu viel Zeit, um herauszufinden, was zum Teufel los ist).
Indrek Kõue
2
Die INTERNET-Berechtigung wird hierfür NICHT benötigt, sondern nur ACCESS_NETWORK_STATE. INTERNET wird nur benötigt, wenn Sie tatsächlich Verbindungen zu entfernten Standorten herstellen und nicht den Status des Funkgeräts des Geräts abfragen.
Tom
3
Ihre Antwort ist derzeit keine wirkliche Antwort, sondern nur eine relativ geringfügige Ergänzung zu anderen Antworten. Wenn alle anderen Antworten nicht hier wären, wäre Ihre Antwort sinnvoll? Nicht wirklich. Denn wenn das besser ist, erweitern Sie Ihre Antwort mit Code zur Verwendung oder entfernen Sie Ihre Antwort und fügen Sie die Informationen in eine andere Antwort ein (Sie verlieren keinen Ruf)
Tim
Seien Sie vorsichtig, es getActiveNetworkInfo()ist in API-Level 29 veraltet.
Stapelüberlauf
46

Schauen Sie sich die ConnectivityManager-Klasse an. Mit dieser Klasse können Sie Informationen zu den aktiven Verbindungen auf einem Host abrufen. http://developer.android.com/reference/android/net/ConnectivityManager.html

EDIT: Sie können verwenden

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

oder

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

und analysieren Sie die DetailedState-Enumeration des zurückgegebenen NetworkInfo-Objekts

BEARBEITEN BEARBEITEN: Um herauszufinden, ob Sie auf einen Host zugreifen können, können Sie verwenden

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

Offensichtlich verwende ich Context.getSystemService (Context.CONNECTIVITY_SERVICE) als Proxy

ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
Chinmay Kanchi
quelle
Ich bin mir nicht sicher, aber dies scheint ein Code zu sein, um zu testen, welche Art von Netzwerkverbindung derzeit besteht. ZB bin ich auf WiFi, es gibt keine Garantie, dass Ihr Heim-WLAN-Router mit Internett verbunden ist ... um zu überprüfen, ob Sie tatsächlich eine Anfrage an einen Internetserver stellen müssen ...
Vidar Vestnes
1
Im Abschnitt EDIT EDIT ist ein Fehler aufgetreten. Ich habe den Aufruf requestRouteToHost () ausgelassen. Lesen Sie die Antwort jetzt noch einmal :)
Chinmay Kanchi
requestRouteToHost ist veraltet.
Jahaziel
46

Überprüfen Sie diesen Code ... es hat bei mir funktioniert :)

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

Dann definiere ich den Handler:

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

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

        } else { // code if connected

        }   
    }
};

... und starten Sie den Test:

isNetworkAvailable(h,2000); // get the answser within 2000 ms
Gilbou
quelle
3
Was ist Google ist ausgefallen? Dies erfordert auch die INTERNET-Berechtigung, die für die angegebene Aufgabe nicht erforderlich ist. Schließlich verbraucht das Daten (auch wenn sie unbedeutend sind). Das scheint einfach so ein Kludge zu sein.
Tom
28
@ Tom um fair zu sein, dies ist wahrscheinlich die einzig richtige Antwort. Die anderen Beispiele zeigen lediglich, ob eine Netzwerkverbindung verfügbar ist und / oder ob eine Verbindung zu diesem Netzwerk besteht. Beantworten Sie jedoch nicht die Frage, ob dieses Netzwerk tatsächlich auch eine Remoteverbindung herstellen kann (z. B. zu einer Website). Dies beantwortet also die Poster Q und die anderen Antworten nicht
slinden77
2
@dmmh Ja, das stimmt leider von dem, was ich mit den Android-APIs gesehen habe. Vielleicht ist ein einfacher Ping besser, stackoverflow.com/questions/3905358/… . Wenn Sie wirklich besorgt waren, könnten Sie sogar eine Liste von IPs zum Ping hinzufügen, denn während die Wahrscheinlichkeit sehr gering ist, dass Google jemals ausfällt, besteht eine noch geringere Wahrscheinlichkeit, dass Google, Bing UND Yahoo am selben Tag ausfallen . Nur meine Gedanken.
Tom
10
Es macht keinen Sinn, diese Prüfung durchzuführen. Wenn Sie die Systemzeit und die Netzwerkressourcen für die Verbindung mit Google verwenden, haben Sie diese möglicherweise stattdessen für die Verbindung mit der Ressource verwendet, die Sie tatsächlich interessiert.
Benjamin
16
In China wurde Google blockiert !!
Anthone
26

Gefunden bei und geändert (!) Von diesem Link :

Fügen Sie in Ihrer Manifestdatei mindestens Folgendes hinzu:

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

Sie haben wahrscheinlich bereits die INTERNET-Berechtigung, wenn Sie darauf zugreifen. Dann ist eine boolesche Funktion, mit der die Konnektivität getestet werden kann:

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;
    }
}
Ajhar
quelle
18

Ich habe diesen Code gemacht, er ist der einfachste und nur ein Boolescher Wert. durch Fragenif(isOnline()){

Sie erhalten, wenn eine Verbindung besteht und wenn eine Verbindung zu einer Seite hergestellt werden kann, den Statuscode 200(stabile Verbindung).

Stellen Sie sicher, dass Sie die richtigen INTERNETund ACCESS_NETWORK_STATEBerechtigungen hinzufügen .

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;
}
Android.Thirio.nl
quelle
6
Vielleicht sollten Sie 200 durch HttpURLConnection.HTTP_OK
Yash
5
Was ist, wenn Google nicht verfügbar ist?
Yauraw Gadav
12

Es funktioniert bei mir:

So überprüfen Sie die Netzwerkverfügbarkeit:

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

So überprüfen Sie den Internetzugang:

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;
}
Musculaa
quelle
Dies ist eine großartige Lösung, um zu überprüfen, ob ein Server in Betrieb ist. Vielen Dank!
Williew
1
isOnline () sollte überhaupt nicht auf dem Hauptthread ausgeführt werden, als ob es ein Wi-Fi-Signal gibt, aber kein Internet. Es wird zu lange dauern und den Hauptthread blockieren.
Humazed
9

Es gibt mehr als einen Weg

Erstens der kürzeste, aber ineffiziente Weg

Netzwerkstatusberechtigung nur erforderlich

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

Dann diese Methode,

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

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

        return isConnected;

    }

Wie aus den Antworten hervorgeht, ConnectivityManagerhandelt es sich um eine Lösung. Ich habe sie nur innerhalb einer Methode hinzugefügt. Dies ist eine vereinfachte Methode. Alle Verwendungszwecke geben
ConnectivityManagertrue zurück, wenn ein Netzwerkzugriff und kein Internetzugang vorhanden ist. Wenn Ihr WLAN mit einem Router verbunden ist, der Router jedoch kein Internet hat Gibt true zurück und überprüft die Verfügbarkeit der Verbindung

Zweitens effizienter Weg

Netzwerkstatus und Internetberechtigungen erforderlich

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

Dann diese Klasse,

 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
            }

        }


    }

Anruf CheckInternetAsyncTask

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

Einige Erklärungen :-

  • Sie müssen das Internet einschalten AsyncTask, sonst kann es android.os.NetworkOnMainThreadExceptionin einigen Fällen werfen

  • ConnectivityManager Wird verwendet, um den Netzwerkzugriff zu überprüfen, wenn true eine Anforderung sendet (Ping).

  • Anfrage senden an http://clients3.google.com/generate_204, Diese bekannte URL gibt bekanntermaßen eine leere Seite mit einem HTTP-Status zurück. 204 Dies ist schneller und effizienter als http://www.google.com, lesen Sie diese . Wenn Sie eine Website haben, ist es vorzuziehen, Ihre Website anstelle von Google zu platzieren, nur wenn Sie sie in der App verwenden

  • Zeitüberschreitung kann Bereich geändert werden (20ms -> 2000ms), 1500ms wird häufig verwendet

Mohamed Embaby
quelle
2
Gute Frage, es ist traurig, dass Sie nicht mehr Punkte haben. Dies muss die richtige Antwort sein.
Jhon Fredy Trujillo Ortega
Ich bin neu bei Android. Dies ist jedoch eine gut abgedeckte Antwort, die mehr Aufmerksamkeit erhält @ 7569106
Mazen Embaby
1
beste und vollständige Antwort, danke. Wenn jemand eine Website hat, bemerken Sie, dass diese Bedingung diese urlc.getResponseCode () == 200 mögen muss und nicht urlc.getContentLength () == 0
AREF
Ihre zweite Option bekommen Absturz Ich weiß nicht warum
nafees ahmed
es friert die Anwendung ein
nafees ahmed
8

Von allem, was ich bisher gesehen habe, sollte der kürzeste und sauberste Weg sein:

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: Dies pingt keinen Host an, sondern überprüft nur den Verbindungsstatus. Wenn Ihr Router keine Internetverbindung hat und Ihr Gerät damit verbunden ist, gibt diese Methode true zurück, obwohl Sie kein Internet haben.
Für einen tatsächlichen Test würde ich empfehlen, eine HttpHead-Anfrage (z. B. an www.google.com) auszuführen und den Status zu überprüfen. Wenn 200 OK, ist alles in Ordnung und Ihr Gerät verfügt über eine Internetverbindung.

Nickolaus
quelle
Ich wollte diese Methode in eine globale Klasse einordnen, also musste ich diese Version verwenden, damit ich den Kontext aus der Aktivität übergeben konnte, von der aus ich sie aufrief. Vielen Dank!
RyanG
8

Hier ist die Methode, die ich benutze:

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

Überprüfen Sie noch besser, ob es "verbunden" ist:

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

So verwenden Sie die Methode:

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

Erlaubnis erforderlich:

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

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

Jared Burrows
quelle
7

Ein wichtiger Anwendungsfall auf Mobilgeräten, um sicherzustellen, dass eine tatsächliche Verbindung besteht. Dies ist ein häufiges Problem, wenn ein mobiler Benutzer ein Wifi-Netzwerk mit einem "Captive Portal" betritt, in dem er sich anmelden muss. Ich verwende diese Blockierungsfunktion im Hintergrund, um sicherzustellen, dass eine Verbindung besteht.

/*
 * 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;
}
user1528493
quelle
3
+1 für die tatsächliche Überprüfung der End-to-End-Konnektivität. Für die Situation "Captive Portal" habe ich jedoch festgestellt, dass viele den oben genannten Test bestehen, auch wenn Sie sich nicht angemeldet haben. Sie erhalten die Anmeldeseite und eine Antwort von 200, unabhängig davon, nach welcher URL Sie fragen. Daher versuche ich, eine Seite in meiner eigenen Domain aufzurufen, von der ich weiß, dass sie nicht vorhanden ist, und stelle sicher, dass ich eine 404 erhalte. Alternativ können Sie eine bekannte vorhandene Seite aufrufen, sicherstellen, dass Sie eine 200 erhalten, und den Inhalt überprüfen wird zurückgegeben, um sicherzustellen, dass es das ist, was Sie erwarten.
GreyBeardedGeek
6

Sie können über alle Netzwerkverbindungen iterieren und prüfen, ob mindestens eine Verbindung verfügbar ist:

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;
}
Emre Yazici
quelle
6

Für mich war es keine gute Praxis, den Verbindungsstatus in der Aktivitätsklasse zu überprüfen, weil

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

sollte dort aufgerufen werden, oder Sie müssen Ihre Aktivitätsinstanz (Kontext) in die Verbindungshandlerklasse verschieben, um dort den Verbindungsstatus überprüfen zu können. Wenn keine Verbindung verfügbar ist (WLAN, Netzwerk), erhalte ich die UnknownHostException- Ausnahme:

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

Auf diese Weise kann ich diesen Fall zusammen mit den anderen Fällen in derselben Klasse behandeln (mein Server antwortet immer mit einer JSON-Zeichenfolge).

HiB
quelle
6

Es funktioniert bei mir. Versuch es.

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());
}}
selva_pollachi
quelle
Diese Antwort kann jetzt nicht funktionieren, da wir jetzt nicht auf das Netzwerk im Hauptthread zugreifen können.
白 布鞋
1
Ich meine, ab API Level 11 funktioniert das nicht. Grund: developer.android.com/reference/android/os/… . Wenn es für Sie funktioniert, bedeutet dies, dass Sie diesen Code auf einem alten Android-Gerät ausführen. (vor GB).
白 布鞋
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder () .permitAll (). Build (); StrictMode.setThreadPolicy (Richtlinie);
Fügen
Ok, ich sollte nicht sagen, dass dies nicht funktionieren kann, ich sollte sagen, dass es funktionieren kann (nach alter Zielversion oder Strictmode-Setup), aber es wird davon abgeraten. Dies kann leicht zu ANR führen. (Mit so hoher Timeout-Konfiguration in httpurlconnection)
布鞋 白 布鞋
ya..you hast recht .. nur ich sage das, weil dies auch einer der Wege ist.
selva_pollachi
6

Diese Methode bietet Ihnen die Möglichkeit einer sehr schnellen Methode (für Echtzeit-Feedback) oder einer langsameren Methode (für einmalige Überprüfungen, die Zuverlässigkeit erfordern).

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;
}
WonderWorker
quelle
5

Ich benutze diesen Code anstelle der 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();
    }
Vidar Vestnes
quelle
Es wäre großartig, wenn Sie geklärt hätten, ob die IOException keine Internetverbindung bedeutet und wie zuverlässig sie sein könnte.
Milad.Nozari
5

Es ist nicht komplex, den Status der Android-Netzwerk- / Internetverbindung zu überprüfen. Die folgende DetectConnectionKlasse hilft Ihnen, diesen Status zu überprüfen:

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

Weitere Informationen finden Sie unter Überprüfen des Android-Netzwerk- / Internetverbindungsstatus

JSupport
quelle
5

Bester Ansatz:

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

    return true;
    } catch (UnknownHostException e){
    return false;
    } catch (IOException e){
    return false;
    }
    }
Lo Juego
quelle
1
Ich mag diesen Ansatz, aber ich muss auf einige Dinge hinweisen. isReachable () gibt einen Booleschen Wert zurück. Anstatt true im Abschnitt try zurückzugeben, können Sie dies wie folgt tun: boolean connection = InetAddress.getByName ("google.com"). isReachable (3); dann wieder verbunden. Außerdem löst isReacheable Ausnahmen für IOException und IllegalArgumentException aus. Daher ist es eine gute Idee, UnknownHostException durch IllegalArgumentException zu ersetzen und einen dritten catch einzuschließen: catch (Ausnahme E).
Yash
2
IsReachable verwendet jedoch ICMP, für das möglicherweise Root-Berechtigungen erforderlich sind, und verwendet Port 7, auf dem auf den neuesten Systemen normalerweise keine Dienste ausgeführt werden. Daher ist der beste Weg, um die Route zu einem Onlinedienst zu überprüfen, das reguläre TCP. daher eine Abwärtsabstimmung.
Yash
5

Es folgt der Code aus meiner UtilsKlasse:

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Mahendra Liya
quelle
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();
}

}
user2912903
quelle
Wie alle anderen, die das Problem nicht durchgelesen haben, löst dies das Problem nicht, da nicht wirklich nach einer Verbindung zum Internet gesucht wird. Eine Verbindung zu einem lokalen WLAN-Hotspot gibt true zurück, auch wenn der Hotspot es Ihnen nicht ermöglicht, ins Internet zu gelangen.
Pedro Pombeiro
5

Mit dieser Methode können Sie die Netzwerkverfügbarkeit ermitteln.

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;
    }
Akshay Paliwal
quelle
5

Ich habe die von @Levit bereitgestellte Lösung angewendet und eine Funktion erstellt, die die zusätzliche HTTP-Anforderung nicht aufruft.

Es wird den Fehler beheben 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;
}

Nennen wir es jetzt wie,

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

Dies wird in den Android-Dokumenten http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html behandelt

Kreker
quelle
1
Die dort beschriebene Methode prüft jedoch nicht wirklich, ob eine Internetverbindung besteht, sondern nur, ob eine Verbindung hergestellt wurde (ob Zugriff auf das Internet besteht oder nicht). Der Titel dieses offiziellen Dokuments ist wirklich irreführend.
Tiago
2
Eine Antwort auf die Frage zu geben ist besser als nur einen Link zu Informationen zu veröffentlichen. Was ist, wenn der Link nicht mehr funktioniert? Wir werden keine Antwort haben.
Jose Llausas
4

Ich habe alle Antworten durchgesehen und mir eine eigene Antwort ausgedacht, die zuerst prüft, ob das Internet verfügbar ist, und ob das Internet verfügbar ist, prüft, ob es aktiv ist oder nicht.

Ich habe alle notwendigen Methoden und Klassen aufgenommen, um nach einer aktiven Internetverbindung zu suchen.

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

Sie können überprüfen, ob das Internet aktiv ist, indem Sie den folgenden Code verwenden:

 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);
            }
        });
    }
Rajesh
quelle
Packen Sie das Threading besser in Ihre NetworkUtils und "zwingen" Sie den Entwickler, Ihre Methode nicht falsch zu verwenden
Ewoks
So entfernen Sie eine zusätzliche if-Bedingung. if ((NetworkUtils.isInternetActiveWithPing () == NetworkUtils.STATUS_CONNECTED) || NetworkUtils.isInternetActiveWithInetAddress ()) {// Netzwerkoperation ausführen} else {// Fehlermeldung}
Jawad Zeb
4

Es ist sehr wichtig zu überprüfen, ob wir eine Verbindung mit isAvailable () haben und ob es möglich ist, eine Verbindung mit isConnected () herzustellen.

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

und Sie können die Art von Netzwerk aktiv derterminate 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;
}

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

Vergessen Sie nicht die Berechtigungen:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.INTERNET" />
Jorgesys
quelle
Schöne Zusammenfassung der Gerätekonnektivitätskomponenten. Sie müssen sie nur in try / catch-Anweisungen einschließen, um Abstürze zu vermeiden. In ähnlicher Weise führen Sie einfach Ihre routinemäßigen HttpURLConnection-Aufrufe durch, solange sie in die Fehlerbehandlung eingebunden sind. Sie werden bald wissen, ob Sie eine Internetverbindung haben oder nicht
Rangi
4

Kotlin und Coroutinen

Ich habe die Funktion in eine platziert ViewModel, die die hat viewModelScope. Mit einem Observable LiveDatainformiere ich eine Aktivität über die Verbindung.

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

Aktivität

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

Erstellen Sie einfach die folgende Klasse, die nach einer Internetverbindung sucht:

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

Diese Klasse enthält einfach eine Methode, die den booleschen Wert des Verbindungsstatus zurückgibt. Wenn die Methode in einfachen Worten eine gültige Verbindung zum Internet findet, lautet der Rückgabewert true, andernfalls, falsewenn keine gültige Verbindung gefunden wird.

Die folgende Methode in der MainActivity ruft dann das Ergebnis der zuvor beschriebenen Methode auf und fordert den Benutzer auf, entsprechend zu handeln:

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

Wenn im obigen Code das Ergebnis falsch ist (daher besteht keine Internetverbindung), wird der Benutzer zum Android-WLAN-Bereich weitergeleitet, wo er aufgefordert wird, eine Verbindung zu einem WLAN-Hotspot herzustellen.

Michele La Ferla
quelle
3

Update 29/06/2015 Wenn Sie Xamarin.Android verwenden und die Konnektivität überprüfen möchten, können Sie ein Nuget-Paket verwenden, das Ihnen diese Funktionalität auf mehreren Plattformen bietet. Gute Kandidaten sind hier und hier . [Ende des Updates]

Die obigen Antworten sind recht gut, aber sie sind alle in Java und fast alle prüfen auf Konnektivität. In meinem Fall musste ich mit einem bestimmten Verbindungstyp verbunden sein und entwickle auf Xamarin.Android. Außerdem übergebe ich keinen Verweis auf meinen Aktivitätskontext in der Hardwareschicht, ich verwende den Anwendungskontext. Hier ist meine Lösung für den Fall, dass jemand mit ähnlichen Anforderungen hierher kommt. Ich habe jedoch noch keine vollständigen Tests durchgeführt. Die Antwort wird aktualisiert, sobald ich mit meinen Tests fertig bin

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
    }
Hat AlTaiar
quelle