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
}