723 Stimmen

Wie prüft man den Internetzugang auf Android? InetAddress schaltet nie ab

Ich habe eine AsyncTask das den Netzzugang zu einem Hostnamen überprüfen soll. Aber die doInBackground() ist nie zeitlich begrenzt. Hat jemand einen Hinweis?

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

7 Stimmen

Um zu prüfen, ob eine Internetverbindung besteht, ist es wahrscheinlich am zuverlässigsten, einen der großen Nameserver anzupingen, z. B. mit if(Runtime.getRuntime().exec("/system/bin/ping -c 1 8.8.8.8").waitFor()==0) ... . Siehe meine Antwort für eine schönere Implementierung dieser Funktion. Btw die akzeptierte Antwort (und viele andere hier) einfach nach einem Netzanschluss und nicht das Internet.

0 Stimmen

4 Stimmen

Verwenden Sie nicht die Ping-Methode, sondern eine HTTP-Überprüfung. ICMP wird in einigen Netzen blockiert, so dass Ping nicht funktioniert. Beispiel: Bei mir zu Hause funktioniert es einwandfrei, aber nicht, wenn ich mobile Daten im Netz von Vodafone (in Ungarn) verwende. Sie können die beiden Methoden auch kombinieren, aber seien Sie vorsichtig, denn waitFor() wartet etwa 20 Sekunden, auch wenn -w oder -W verwendet wird.

0voto

Sazzad Hissain Khan Punkte 33230

Hier ist die Kotlin Version, die ich für die Erreichbarkeitsprüfung verwende,

Kotlin MyReachability

object MyReachability {

    private val REACHABILITY_SERVER = "http://google.com" // can be any URL you want

    private fun hasNetworkAvailable(context: Context): Boolean {
        val service = Context.CONNECTIVITY_SERVICE
        val manager = context.getSystemService(service) as ConnectivityManager?
        val network = manager?.activeNetworkInfo
        Log.d(classTag, "hasNetworkAvailable: ${(network != null)}")
        return (network != null)
    }

    fun hasInternetConnected(context: Context): Boolean {
        if (hasNetworkAvailable(context)) {
            try {
                val connection = URL(REACHABILITY_SERVER).openConnection() as HttpURLConnection
                connection.setRequestProperty("User-Agent", "Test")
                connection.setRequestProperty("Connection", "close")
                connection.connectTimeout = 1500
                connection.connect()
                Log.d(classTag, "hasInternetConnected: ${(connection.responseCode == 200)}")
                return (connection.responseCode == 200)
            } catch (e: IOException) {
                Log.e(classTag, "Error checking internet connection", e)
            }
        } else {
            Log.w(classTag, "No network available!")
        }
        Log.d(classTag, "hasInternetConnected: false")
        return false
    }
}

Sie können sogar die REACHABILITY_SERVER als param auf der Grundlage von Richtlinien und Beschränkungen, wenn Sie zum Beispiel in China sind, können Sie überprüfen https://baidu.com eher https://google.com .

Beispiel anrufen,

val webLoaderThread = Thread {
   if (MyReachability.hasInternetConnected(this)){
       runOnUiThread {
           //mWebView.loadUrl(LANDING_SERVER) // connected
       }
   } else {
       runOnUiThread {
           //showDialogNoNetwork() // not connected
       }
   }
}
webLoaderThread.start()

Android-Berechtigungen

Vergessen Sie nicht, die folgenden Berechtigungen zu Ihrem AndroidManifest.xml

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

0voto

jenson-button-event Punkte 17193

Hier ist ein moderner Code, der eine AsynTask um ein Problem zu umgehen, bei dem Android abstürzt, wenn man versucht, eine Verbindung zum Haupt-Thread herzustellen, und um eine Warnung mit einer Spül- und Wiederholungsoption für den Benutzer einzuführen.

class TestInternet extends AsyncTask<Void, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            URL url = new URL("http://www.google.com");
            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
            urlc.setConnectTimeout(3000);
            urlc.connect();
            if (urlc.getResponseCode() == 200) {
                return true;
            }
        } catch (MalformedURLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if (!result) { // code if not connected
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setMessage("An internet connection is required.");
            builder.setCancelable(false);

            builder.setPositiveButton(
                    "TRY AGAIN",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            dialog.cancel();
                            new TestInternet().execute();
                        }
                    });

            AlertDialog alert11 = builder.create();
            alert11.show();
        } else { // code if connected
            doMyStuff();
        }
    }
}

...

new TestInternet().execute();

0voto

Foobar Punkte 6425

Hier finden Sie die optimale Methode zur Überprüfung der Internetverbindung. Diese Methode führt eine Reihe von Überprüfungen durch: "Befindet sich das Telefon nicht im Flugzeugmodus, ist das Telefon mit einem Netzwerk verbunden usw.". Wenn alle Prüfungen den Wert "true" ergeben, wird die Methode dann eine Datei aus dem Internet herunterladen und prüfen, ob der Inhalt mit einem erwarteten Wert übereinstimmt.

Die Vorteile dieser Methode im Vergleich zu anderen Methoden, die einen Server anpingen, um die Internetverbindung zu prüfen, sind:

  1. Die Android-Laufzeit variiert von Telefon zu Telefon - daher können Sie diese Befehle möglicherweise nicht immer ausführen, wie hier gezeigt: Warum funktioniert ping auf einigen Geräten und auf anderen nicht?

  2. Das Anpingen eines Servers funktioniert nicht immer, da Anmeldeseiten/Umleitungen in WLAN-Netzen den falschen Eindruck einer Verbindung erwecken können.

Diese Antwort ist in Kotlin geschrieben und verwendet die Kraftstoff Bibliothek zum Herunterladen einer Datei aus dem Internet mit der Methode fetchUrlAsString aber jede Bibliothek kann ersetzt werden, solange Sie sicherstellen, dass Ihre HTTP-Anfrage nicht zwischengespeichert wird. Denken Sie an showConnectionWarning() y hideConnectionWarning() als gleichwertig zu internet connection status = false y internet connection status = true beziehungsweise.

private val networkReceiver = object : BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {

        val activeNetworkInfo = (context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo

        if (activeNetworkInfo != null) {
            if (activeNetworkInfo.isConnectedOrConnecting) {
                //Launches a coroutine to fetch file asynchronously 
                launch {
                    try {
                        //Downloads file from url on the internet - use any library you want here.  
                        val connectionStatus = fetchUrlAsString(<url_for_file_on_internet>)
                        //check if the contents of the file is as expected
                        if (connectionStatus == "Connected To Database") {
                            hideConnectionWarning()
                        } else {
                            showConnectionWarning()
                        }
                    } catch (e: Exception) {
                        //Catches an exception - fetchUrlAsString only throws an exception if there is no internet 
                        showConnectionWarning()
                    }
                }
            } else {
                showConnectionWarning()
            }
        } else {
            showConnectionWarning()
        }
    }
}

private suspend fun fetchUrlAsString(url: String): String = suspendCoroutine { cont ->
    url.httpGet().header(Pair("pragma", "no-cache"), Pair("cache-control", "no-cache")).responseString { _, _, result ->

        when (result) {
            is Result.Failure -> {
                cont.resumeWithException(result.getException())
            }
            is Result.Success -> {
                cont.resume(result.value)
            }
        }

    }
}

Sie benötigen die folgenden Berechtigungen:

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

0voto

Ragu Punkte 173

Anstatt die WIFI-Verbindung oder die mobile Datenverbindung zu überprüfen, versuchen Sie, eine beliebige gehostete Domain aufzurufen. So können Sie überprüfen, ob die WIFI-/Mobilverbindung die Fähigkeit hat, sich mit dem öffentlichen Internet zu verbinden.

Wenn Ihr mobiles Gerät eine Verbindung mit dem öffentlichen Bereich herstellen kann, wird die folgende Meldung angezeigt.

boolean isReachable()
        {
            boolean connected = false;
            String instanceURL = "Your trusted domain name";
            Socket socket;
            try {
                socket = new Socket();
                SocketAddress socketAddress = new InetSocketAddress(instanceURL, 80);
                socket.connect(socketAddress, 5000);
                if (socket.isConnected()) {
                    connected = true;
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                socket = null;
            }
            return connected;
        }

Ich hoffe, es wird hilfreich sein.

0voto

lalit vasan Punkte 452

Android bietet die Klasse ConnectivityManager, um den Status der Internetverbindung zu erfahren. Die folgende Methode ist sehr nützlich, um den Status der Internetverbindung zu erfahren.

Fügen Sie zunächst die INTERNET y ZUGANG_NETZ_ZUSTAND Erlaubnis zu AndroidManifest.xml

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

Verwenden Sie dann die folgende Methode, um zu prüfen, ob das Gerät mit dem Internet verbunden ist oder nicht. Diese Methode gibt true zurück, wenn das Gerät mit dem Internet verbunden ist.

public boolean isInternetAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) 
    context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
    return activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();
}

Referenz-Link :- http://www.androidtutorialshub.com/Android-check-internet-connection-status/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X