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.

4voto

miguel Punkte 15066

Die anderen Antworten, die ConnectivityManager verwenden, sind falsch, da eine Netzwerkverbindung nicht bedeutet, dass man einen Internetzugang hat. Zum Beispiel könnte der Benutzer mit dem WiFi-Portal eines Cafés verbunden sein, aber keinen Zugang zum Internet haben. Um zu prüfen, ob das Internet zugänglich ist, müssen Sie versuchen, eine Verbindung zu einem tatsächlichen Server herzustellen. Normalerweise haben Sie dabei einen bestimmten Server im Sinn, mit dem Sie eine Verbindung herstellen möchten. Prüfen Sie also, ob Sie eine Verbindung zu diesem Server herstellen können. Hier ist eine einfache Methode, um die Verbindung zu einem Server zu überprüfen.

private boolean isOnTheInternet() {
    try {
        URLConnection urlConnection = new URL("http://yourserver").openConnection();
        urlConnection.setConnectTimeout(400);
        urlConnection.connect();
        return true;
    } catch (Exception e) {
        return false;
    }
}

Der Grund für die Einstellung von ConnectTimeout ist, dass andernfalls standardmäßig der TCP-Timeout verwendet wird, der viele Sekunden lang sein kann.

Beachten Sie auch, dass Android es nicht zulässt, dass Sie dies auf Ihrem Haupt-Thread ausführen.

3voto

Muhammad Punkte 5513

Die einfachste Lösung wäre

In den meisten Fällen wird man die Internetverbindung nur prüfen, wenn man sich mit dem entfernten Server verbinden will. Die einfachste und beste Lösung wäre also, den Server wie folgt anzupingen.

public boolean isConnected() {
    final String command = "ping -c 1 yourExmapleDomain.com";
    boolean isConnected = false;
    try {
        isConnected = Runtime.getRuntime().exec(command).waitFor() == 0;
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return isConnected;
}

0 Stimmen

Können Sie mir sagen, was -c 1 bedeutet?

3voto

Michele La Ferla Punkte 6525

Erstellen Sie einfach die folgende Klasse, die auf eine Internetverbindung prüft:

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. Einfach ausgedrückt: Wenn die Methode eine gültige Verbindung zum Internet findet, lautet der Rückgabewert also true sonst false wenn 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.");
        }
    }

Im obigen Code wird der Benutzer, wenn das Ergebnis falsch ist (also keine Internetverbindung besteht), zum Android-Wi-Fi-Panel geleitet, wo er aufgefordert wird, eine Verbindung zu einem Wi-Fi-Hotspot herzustellen.

3voto

Keeeeeenw Punkte 407

Wenn Sie API 23 oder höher verwenden, können Sie jetzt überprüfen, ob das Internet aktiv ist oder nicht, indem Sie NetworkCapabilities.NET_CAPABILITY_VALIDATED die von Googles eigenem Ping-Dienst unterstützt wird.

ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onLost(Network network) {
        // handle network lost
    }

    @Override
    public void onAvailable(Network network) {
        ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getNetworkInfo(network);
        boolean isConnected = (info != null && info.isConnectedOrConnecting());

        if (isConnected) {
            NetworkCapabilities nc = cm.getNetworkCapabilities(network);
            if (nc != null) {
                boolean isInternetValid = nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
                if (isInternetValid) {
                    // internet is valid
                }
            }
        }
    }
};

NetworkRequest request = new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.registerNetworkCallback(request, networkCallback);

1 Stimmen

Ich habe dies versucht und obwohl der Aufruf von onAvailable und isConnected wahr ist, gibt NetworkCapabilities false zurück. Ich denke, dass es ein Zeitproblem gibt, wenn man es auf diese Weise macht. Wenn dies jedoch funktioniert, dann wäre es der richtige Weg, um zu überprüfen, ob Ihr Netzwerk tatsächlich mit dem Internet verbunden ist.

0 Stimmen

Ja, es scheint ein Zeitproblem zu geben, wie ich in einem der Kommentare hier beschrieben habe: stackoverflow.com/questions/36358531/

0 Stimmen

Diese Methode scheint auf dem Emulator zuverlässig zu funktionieren, selbst wenn er hinter einem Firmenproxy sitzt. Wenn der Proxy eine neue Anmeldung erfordert, erkennt dieser Code das Problem und gibt false zurück. Ich habe eine kleine Verzögerung beobachtet, wenn dies geschieht. Es gibt also ein kleines Zeitfenster, in dem das System denkt, dass es Internet gibt, aber es gibt keins. Wenn Sie so schnell wie möglich wissen wollen, ob eine Internetverbindung besteht, empfehle ich nach meiner Beobachtung, zu prüfen, ob eine Socket-Verbindung zu einer bestimmten IP-Adresse (z. B. 8.8.8.8) möglich ist.

2voto

geekdev786 Punkte 35
public static boolean isNetworkAvailable(Context ctx) {
ConnectivityManager connMgr = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
if(connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected() ||
    connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected()){
        return true;
}

return false;
 } 

Benutzer dies

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