Android, как проверить Wi-Fi подключен, но нет подключения к Интернету

Android-устройство, подключенное к Wi-Fi, но как подключиться к Wi-Fi, но это не интернет-соединение.

Следующим является мой код, который я пытаюсь проверить, нет ли подключения к Интернету

public static boolean isConnectedWifi(Context context) {
        NetworkInfo info=null;
        if(context!=null){
            info= IsNetConnectionAvailable.getNetworkInfo(context);
        }
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
    }

он всегда возвращает true, когда нет доступа в Интернет

Ответ 1

NetworInfo.isAvailable и NetworkInfo.isConnected только указывают, возможно ли сетевое подключение или существуют, они не могут указать, имеет ли подключенная ситуация доступ к общедоступному Интернету, короче говоря, они не могут сказать нам, что устройство действительно в сети.

Чтобы проверить, подключено ли устройство к сети, попробуйте следующие способы:

Во-первых:

@TargetApi(Build.VERSION_CODES.M)
public static boolean isNetworkOnline1(Context context) {
    boolean isOnline = false;
    try {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkCapabilities capabilities = manager.getNetworkCapabilities(manager.getActiveNetwork());  // need ACCESS_NETWORK_STATE permission
        isOnline = capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return isOnline;
}

Сила: 1. может работать в потоке пользовательского интерфейса; 2. быстро и точно.

Слабость: нужен API> = 23 и проблемы с совместимостью.

Во-вторых:

public static boolean isNetworkOnline2() {
    boolean isOnline = false;
    try {
        Runtime runtime = Runtime.getRuntime();
        Process p = runtime.exec("ping -c 1 8.8.8.8");
        int waitFor = p.waitFor();
        isOnline = waitFor == 0;    // only when the waitFor value is zero, the network is online indeed

        // BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        // String str;
        // while ((str = br.readLine()) != null) {
        //     System.out.println(str);     // you can get the ping detail info from Process.getInputStream()
        // }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    return isOnline;
}

Сила: 1. может работать в потоке пользовательского интерфейса; 2. вы можете пинговать много раз и делать статистику по минимальному/среднему/максимальному задержанному времени и скорости потери пакетов.

Слабость: проблемы совместимости.

В-третьих:

public static boolean isNetworkOnline3() {
    boolean isOnline = false;
    try {
        URL url = new URL("http://www.google.com"); // or your server address
        // URL url = new URL("http://www.baidu.com");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Connection", "close");
        conn.setConnectTimeout(3000);
        isOnline = conn.getResponseCode() == 200;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return isOnline;
}

Сила: можно использовать на всех устройствах и API.

Слабость: трудоемкая операция, не может выполняться в потоке пользовательского интерфейса.

В-четвертых:

public static boolean isNetworkOnline4() {
    boolean isOnline = false;
    try {
        Socket socket = new Socket();
        socket.connect(new InetSocketAddress("8.8.8.8", 53), 3000);
        // socket.connect(new InetSocketAddress("114.114.114.114", 53), 3000);
        isOnline = true;
    } catch (IOException e) {
        e.printStackTrace();
    }

    return isOnline;
}

Сила: 1. может использоваться на всех устройствах и API; 2. относительно быстро и точно.

Слабость: трудоемкая операция, не может выполняться в потоке пользовательского интерфейса.

Ответ 2

Используемый вами код просто используется, чтобы проверить, подключены ли вы к Wi-Fi или нет. Он не проверяет, работает ли этот wifi или нет. (Интернет не означает медленное соединение).

Я пытался использовать этот код. Здесь я пытаюсь нажать google.com и установить значение тайм-аута соединения. Если здесь скорость интернета хороша, тогда результат возвращается 200. Поэтому я проверяю, равен ли код результата 200 или нет. Если нет, я предупреждаю о медленном подключении к Интернету. Используйте его в asyntask, а onPostExecute() проверяет значение возвращаемого результата.

HttpURLConnection urlc = null;
    try {
        urlc = (HttpURLConnection) (new URL("http://www.google.com")
                .openConnection());
    } catch (MalformedURLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    urlc.setRequestProperty("User-Agent", "Test");
    urlc.setRequestProperty("Connection", "close");
    urlc.setConnectTimeout(1000); // choose your own timeframe
    urlc.setReadTimeout(2000); // choose your own timeframe
    try {
        urlc.connect();

        // returning connection code.
        return (urlc.getResponseCode());
    } catch (IOException e1) {
        e1.printStackTrace();
    }

Ответ 3

После поисков в течение нескольких дней и после попыток найти разные решения, некоторые из них не идеальны, некоторые слишком длинны, ниже приведено решение, предложенное LEVIT с использованием розеток, которое идеально для меня. Любой, кто ищет это решение, может обратиться к этому сообщению. Как проверить доступ в интернет на Android? InetAddress никогда не истекает

Ниже приведен фрагмент кода с примером задачи в AsyncTask

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

Ниже приведена сводная информация о решении Возможные вопросы Это действительно достаточно быстро?

Да, очень быстро ;-)

Нет ли надежного способа проверить интернет, кроме тестирования чего-либо в интернете?

Не настолько, насколько я знаю, но дайте мне знать, и я отредактирую свой ответ.

Что делать, если DNS не работает?

Google DNS (например, 8.8.8.8) является крупнейшим общедоступным DNS в мире. По состоянию на 2013 год он обслуживал 130 миллиардов запросов в день. Скажем так, ваше приложение, вероятно, не будет темой дня.

Какие разрешения требуются?

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

Ответ 4

Чтобы проверить, подключены ли вы к Интернету через Wi-Fi, просмотрите фрагмент ниже:

NetworkInfo getWifi(){
    ConnectivityManager connManager = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    return mWifi;
}

Проверьте, подключен ли он или нет;

if(getWifi().isConnected()) {
//wi-fi connected
}