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

Wadelzubair Punkte 31

Dies mein Workaround, um dieses Problem zu lösen und überprüfen Sie die gültige Internet-Verbindung, weil, wie sie sagte, dass Network info Klasse kann nicht geben Sie das erwartete Ergebnis und es kann true zurückgeben, wenn Netzwerk verbunden, aber kein Internet.

Das ist also mein VOLLSTÄNDIGE UMGEHUNG basierend auf @Levite Antwort:

Zuerst müssen Sie AsynckTask für die Überprüfung der Netzverfügbarkeit haben, und das ist meine Aufgabe:

public class Connectivity {
 private static final String TAG = "Connectivity";
private static boolean hasConnected = false, hasChecked = false;
private InternetListener internetListener;
private Activity activity;

public Connectivity(InternetListener internetListener, Activity activity) {
    this.internetListener = internetListener;
    this.activity = activity;
}

public void startInternetListener() {

    CheckURL checkURL = new CheckURL(activity);

    checkURL.execute();

    long startTime = System.currentTimeMillis();

    while (true) {
        if (hasChecked && hasConnected) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    internetListener.onConnected();
                }
            });

            checkURL.cancel(true);
            return;
        }

        // check if time
        if (System.currentTimeMillis() - startTime >= 1000) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    internetListener.onDisconnected();
                }
            });

            checkURL.cancel(true);
            return;
        }
    }

    //return hasConnected;
}

class CheckURL extends AsyncTask<Void, Void, Boolean> {

    private Activity activity;

    public CheckURL(Activity activity) {
        this.activity = activity;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        if (!isNetWorkAvailable(activity)) {
            Log.i(TAG, "Internet not available!");
            return false;
        }

        int timeoutMs = 3000;

        try {
            Socket sock = new Socket();
            SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
            sock.connect(sockaddr, timeoutMs);
            sock.close();
            Log.i(TAG, "Internet available :)");
            return true;

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    @Override
    protected void onPostExecute(Boolean result) {
        hasChecked = true;
        hasConnected = result;
        super.onPostExecute(result);}}

private static final String TAG = "Connectivity";

private static boolean isNetWorkAvailable(Activity activity) {

    ConnectivityManager connectivityManager =
            (ConnectivityManager) 
   activity.getSystemService(Activity.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo =
            null;
    if (connectivityManager != null) {
        networkInfo = 
   connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    }
    boolean isConnected;
    boolean isWifiAvailable = false;
    if (networkInfo != null) {
        isWifiAvailable = networkInfo.isAvailable();
    }
    boolean isWifiConnected = false;
    if (networkInfo != null) {
        isWifiConnected = networkInfo.isConnected();
    }
    if (connectivityManager != null) {
        networkInfo =
                connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    }
    boolean isMobileAvailable = false;
    if (networkInfo != null) {
        isMobileAvailable = networkInfo.isAvailable();
    }
    boolean isMobileConnected = false;
    if (networkInfo != null) {
        isMobileConnected = networkInfo.isConnected();
    }
    isConnected = (isMobileAvailable && isMobileConnected) ||
            (isWifiAvailable && isWifiConnected);
    return (isConnected);}
    }}

private static boolean isNetWorkAvailable(Context context) {

    ConnectivityManager connectivityManager =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo =
            null;
    if (connectivityManager != null) {
        networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    }
    boolean isConnected;
    boolean isWifiAvailable = false;
    if (networkInfo != null) {
        isWifiAvailable = networkInfo.isAvailable();
    }
    boolean isWifiConnected = false;
    if (networkInfo != null) {
        isWifiConnected = networkInfo.isConnected();
    }
    if (connectivityManager != null) {
        networkInfo =
                connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    }
    boolean isMobileAvailable = false;
    if (networkInfo != null) {
        isMobileAvailable = networkInfo.isAvailable();
    }
    boolean isMobileConnected = false;
    if (networkInfo != null) {
        isMobileConnected = networkInfo.isConnected();
    }
    isConnected = (isMobileAvailable && isMobileConnected) ||
            (isWifiAvailable && isWifiConnected);
    return (isConnected);

}

}

Danach sollten Sie einen weiteren Thread erstellen, um AscnkTask zu starten und mit dem InternetListener auf das Ergebnis zu warten.

public interface InternetListener {
void onConnected();
void onDisconnected();
}

Und den Thread, der auf das Ergebnis von AsynckTask wartet, können Sie in der Klasse Utility unterbringen:

 private static Thread thread;

public static void startNetworkListener(Context context, InternetListener 
    internetListener) {

    if (thread == null){
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                new Connectivity(internetListener,context).startInternetListener();
            }
        });
    }

    thread.start();
 }

Rufen Sie schließlich die Methode startNetworkListener() auf und warten Sie auf das Ergebnis.

Beispiel in Aktivität aus der Klasse My Utils.java :

     Utils.startNetworkListener(this, new InternetListener() {
        @Override
        public void onConnected() {
           // do your work when internet available. 
        }

        @Override
        public void onDisconnected() {
          // do your work when no internet available. 
        }
    });

Viel Spaß beim Coding :).

0voto

Context Punkte 1855

Vergessen Sie nicht, diese Berechtigungen in Ihr Manifest aufzunehmen:

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

0voto

D.Snap Punkte 1465

Die meisten Antworten in diesem Thread prüfen nur, ob eine Verbindung vorhanden ist, aber nicht, ob diese Verbindung funktioniert, andere Antworten sind nicht geräteübergreifend, meine Lösung sollte auf jedem Gerät funktionieren.

Sie können meinen Code in Ihre Hauptaktivität einfügen, bevor Sie die App starten. Er wird schnell feststellen, ob tatsächlich eine Internetverbindung besteht, wenn ja, wird der Dialog sofort abgebrochen und die App gestartet.

final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
        alertDialog.setTitle("Checking Connection");
        alertDialog.setMessage("Checking...");
        alertDialog.show();
        new CountDownTimer(5000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {

                new Thread(new Runnable() {
                    public void run() {
                        try {
                            URL url = new URL("http://web.mit.edu/");
                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                            connection.setRequestMethod("GET");
                            connection.setConnectTimeout(5000);
                            isConnected = connection.getResponseCode() == HttpURLConnection.HTTP_OK;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

                if (isConnected == false){
                    alertDialog.setMessage("Try " +  (5 - millisUntilFinished/1000) + " of 5.");
                } else {
                    alertDialog.dismiss();
                }
            }
            @Override
            public void onFinish() {
                if (isConnected == false) {
                    alertDialog.dismiss();
                    new AlertDialog.Builder(activity)
                            .setTitle("No Internet")
                            .setMessage("Please connect to Internet first.")
                            .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    // kill the app?
                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();
                } else {
                    // Launch the app
                }
            }
        }.start();

0voto

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

Hier ist die Genehmigung, die Sie benötigen:

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

0voto

ked Punkte 2229

Die Verwendung der folgenden Methode zur Überprüfung der Internetkonnektivität, auch ConnectivityManager.getActiveNetworkInfo() ist in API 28 veraltet

@Suppress("DEPRECATION")
fun isNetworkConnected(context: Context): Boolean {
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    return cm?.run {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                when {
                    hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            }
        } else {
            cm.activeNetworkInfo?.run {
                when (type) {
                    ConnectivityManager.TYPE_WIFI -> true
                    ConnectivityManager.TYPE_MOBILE -> true
                    else -> false
                }
            }
        }
    } ?: false

}

Fügen Sie dem Manifest außerdem die folgende Berechtigung hinzu

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

hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) wird für Apps verwendet, die für Android TV entwickelt wurden und bei denen das TV-Gerät direkt an das Ethernet angeschlossen werden kann.

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