Обнаружить, если Android-устройство имеет подключение к интернету
Я хочу сказать, если устройство имеет подключение к Интернету или нет. Я нашел много ответов, таких как:
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null;
}
(взято из определения, есть ли подключение к Интернету на Android.)
но это не правильно, например если я подключен к беспроводной сети, которая не имеет доступ в интернет, этот метод вернет true...есть ли способ, чтобы сказать, если устройство имеет подключение к Интернету, а не если он связан к чему-то?
9 ответов:
вы правы. Код, который вы предоставили, проверяет только наличие сетевого подключения. Лучший способ проверить, если есть активное подключение к Интернету, чтобы попытаться подключиться на известный сервер через http.
public static boolean hasActiveInternetConnection(Context context) { if (isNetworkAvailable(context)) { try { HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection()); urlc.setRequestProperty("User-Agent", "Test"); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(1500); urlc.connect(); return (urlc.getResponseCode() == 200); } catch (IOException e) { Log.e(LOG_TAG, "Error checking internet connection", e); } } else { Log.d(LOG_TAG, "No network available!"); } return false; }конечно, вы можете заменить
http://www.google.comURL для любого другого сервера, к которому вы хотите подключиться, или сервер, который вы знаете, имеет хорошее время безотказной работы.как Тони Чо также указал в этот комментарий ниже, убедитесь, что вы не запустите этот код на основной поток, в противном случае вы получите исключение NetworkOnMainThread (в Android 3.0 или более поздней версии). Вместо этого используйте AsyncTask или Runnable.
если вы хотите использовать google.com вы должны смотреть на изменения в Ешурун. В ответ он изменил мой код и сделал его немного более эффективным. Если вы подключаетесь к
HttpURLConnection urlc = (HttpURLConnection) (new URL("http://clients3.google.com/generate_204") .openConnection());а затем проверьте responsecode для 204
return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);тогда вам не нужно сначала извлекать всю домашнюю страницу google.
Я немного изменил ответ THelper, чтобы использовать известный хак, который Android уже использует, чтобы проверить, имеет ли подключенная сеть WiFi доступ в интернет. Это намного эффективнее, чем захват всей домашней страницы Google. Смотрите здесь и здесь для получения дополнительной информации.
public static boolean hasInternetAccess(Context context) { if (isNetworkAvailable(context)) { try { HttpURLConnection urlc = (HttpURLConnection) (new URL("http://clients3.google.com/generate_204") .openConnection()); urlc.setRequestProperty("User-Agent", "Android"); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(1500); urlc.connect(); return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0); } catch (IOException e) { Log.e(TAG, "Error checking internet connection", e); } } else { Log.d(TAG, "No network available!"); } return false; }
public boolean isInternetWorking() { boolean success = false; try { URL url = new URL("https://google.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(10000); connection.connect(); success = connection.getResponseCode() == 200; } catch (IOException e) { e.printStackTrace(); } return success; }возвращает true, если интернет действительно доступен
убедитесь, что у вас есть эти два разрешения
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Если вы нацелены на Lollipop или выше, можно использовать новый класс NetworkCapabilities, т. е.:
public static boolean hasInternetConnection(final Context context) { final ConnectivityManager connectivityManager = (ConnectivityManager)context. getSystemService(Context.CONNECTIVITY_SERVICE); final Network network = connectivityManager.getActiveNetwork(); final NetworkCapabilities capabilities = connectivityManager .getNetworkCapabilities(network); return capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); }
попробуй этот
public class ConnectionDetector { private Context _context; public ConnectionDetector(Context context) { this._context = context; } public boolean isConnectingToInternet() { if (networkConnectivity()) { try { HttpURLConnection urlc = (HttpURLConnection) (new URL( "http://www.google.com").openConnection()); urlc.setRequestProperty("User-Agent", "Test"); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(3000); urlc.setReadTimeout(4000); urlc.connect(); // networkcode2 = urlc.getResponseCode(); return (urlc.getResponseCode() == 200); } catch (IOException e) { return (false); } } else return false; } private boolean networkConnectivity() { ConnectivityManager cm = (ConnectivityManager) _context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { return true; } return false; } }вам нужно будет добавить следующее разрешение в файл манифеста:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />тогда звоните вот так:
if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){ Log.d("internet status","Internet Access"); }else{ Log.d("internet status","no Internet Access"); }
вам не обязательно делать полное HTTP-соединение. Можно попробовать просто открыть TCP-соединение на сервере, и если это удастся, у вас есть подключение к интернету.
public boolean hostAvailable(String host, int port) { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), 2000); return true; } catch (IOException e) { // Either we have a timeout or unreachable host or failed DNS lookup System.out.println(e); return false; } }тогда просто проверьте с:
boolean online = hostAvailable("www.google.com", 80);
основываясь на принятых ответах, я построил этот класс со слушателем, чтобы вы могли использовать его в основном потоке:
первый: класс InterntCheck, который проверяет подключение к интернету в фоновом режиме, затем вызывает метод прослушивателя с результатом.
public class InternetCheck extends AsyncTask<Void, Void, Void> { private Activity activity; private InternetCheckListener listener; public InternetCheck(Activity x){ activity= x; } @Override protected Void doInBackground(Void... params) { boolean b = hasInternetAccess(); listener.onComplete(b); return null; } public void isInternetConnectionAvailable(InternetCheckListener x){ listener=x; execute(); } private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) activity.getSystemService(CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null; } private boolean hasInternetAccess() { if (isNetworkAvailable()) { try { HttpURLConnection urlc = (HttpURLConnection) (new URL("http://clients3.google.com/generate_204").openConnection()); urlc.setRequestProperty("User-Agent", "Android"); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(1500); urlc.connect(); return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0); } catch (IOException e) { e.printStackTrace(); } } else { Log.d("TAG", "No network available!"); } return false; } public interface InternetCheckListener{ void onComplete(boolean connected); } }второй: создать экземпляр класса в главном потоке и ждать ответа (если вы работали с Firebase api для android, прежде чем это должно быть знакомо ты!).
new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() { @Override public void onComplete(boolean connected) { //proceed! } });теперь внутри метода onComplete вы получите, подключено ли устройство к интернету или нет.
private static NetworkUtil mInstance; private volatile boolean mIsOnline; private NetworkUtil() { ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.scheduleAtFixedRate(new Runnable() { @Override public void run() { boolean reachable = false; try { Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com"); int returnVal = process.waitFor(); reachable = (returnVal==0); } catch (Exception e) { e.printStackTrace(); } mIsOnline = reachable; } }, 0, 5, TimeUnit.SECONDS); } public static NetworkUtil getInstance() { if (mInstance == null) { synchronized (NetworkUtil.class) { if (mInstance == null) { mInstance = new NetworkUtil(); } } } return mInstance; } public boolean isOnline() { return mIsOnline; }надеюсь, что приведенный выше код поможет вам, а также убедитесь, что у вас есть разрешение на доступ в интернет в приложении ur.
последний способ сделать это из документация использовать
ConnectivityManagerчтобы запросить активную сеть и определить, имеет ли она подключение к интернету.public boolean hasInternetConnectivity() { ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnectedOrConnecting()); }добавьте эти два разрешения на ваш AndroidManifest.xml-файл:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Comments