Как проверить доступ в Интернет на Android? InetAddress никогда не выбегает
Я получил AsyncTask
, который должен проверить сетевой доступ к имени хоста. Но doInBackground()
никогда не прерывается. У кого-нибудь есть ключ?
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();
}
}
Ответы
Ответ 1
Сетевое подключение/доступ в Интернет
-
isConnectedOrConnecting()
(используется в большинстве ответов) проверяет любое сетевое соединение - Чтобы узнать, имеет ли доступ к Интернету какой-либо из этих сетей, используйте один из следующих
A) Ping a Server (простой)
// ICMP
public boolean isOnline() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
}
catch (IOException e) { e.printStackTrace(); }
catch (InterruptedException e) { e.printStackTrace(); }
return false;
}
+
может работать на главной теме
-
не работает на некоторых старых устройствах (Galays S3 и т.д.), он блокирует некоторое время, если интернет недоступен.
B) Подключение к гнезду в Интернете (расширенный)
// TCP/HTTP/DNS (depending on the port, 53=DNS, 80=HTTP, etc.)
public boolean isOnline() {
try {
int timeoutMs = 1500;
Socket sock = new Socket();
SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53);
sock.connect(sockaddr, timeoutMs);
sock.close();
return true;
} catch (IOException e) { return false; }
}
+
очень быстрый (в любом случае), работает на всех устройствах, очень надежен
-
не может работать в потоке пользовательского интерфейса
Это работает очень надежно, на каждом устройстве, и очень быстро. Он должен запускаться в отдельной задаче (например, ScheduledExecutorService
или AsyncTask
).
Возможные вопросы
-
Это действительно достаточно быстро?
Да, очень быстро ;-)
-
Нет ли надежного способа проверки Интернета, кроме тестирования чего-либо в Интернете?
Не так далеко, насколько я знаю, но дайте мне знать, и я отредактирую свой ответ.
-
Что делать, если DNS не работает?
Google DNS (например, 8.8.8.8
) является крупнейшим публичным DNS в мире. С 2013 года он обслуживал 130 миллиардов запросов в день. Скажем так, ваше приложение, вероятно, не будет говорить о дне.
-
Какие разрешения необходимы?
<uses-permission android:name="android.permission.INTERNET" />
Просто интернет-доступ - неожиданность ^^ (Кстати, вы когда-нибудь задумывались о том, как некоторые из предложенных здесь методов могут даже иметь удаленный клей об интернет-доступе без этого разрешения?)
Дополнительно: пример с одним выстрелом 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 */ });
Дополнительно: RxJava/RxAndroid
пример RxJava/RxAndroid
(Kotlin)
fun hasInternetConnection(): Single<Boolean> {
return Single.fromCallable {
try {
// Connect to Google DNS to check for connection
val timeoutMs = 1500
val socket = Socket()
val socketAddress = InetSocketAddress("8.8.8.8", 53)
socket.connect(socketAddress, timeoutMs)
socket.close()
true
} catch (e: IOException) {
false
}
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
///////////////////////////////////////////////////////////////////////////////////
// Usage
hasInternetConnection().subscribe { hasInternet -> /* do something */}
Ответ 2
Если устройство находится в режиме самолета (или, предположительно, в других ситуациях, когда нет доступной сети), cm.getActiveNetworkInfo()
будет null
, поэтому вам нужно добавить null
проверку.
Модифицированное решение (Eddie) ниже:
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
Также добавьте следующие разрешения для AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Еще одна небольшая точка, если вам абсолютно необходимо подключение к сети в данный момент времени, тогда было бы лучше использовать netInfo.isConnected()
а не netInfo.isConnectedOrConnecting
. Я предполагаю, что это зависит от конкретного случая использования.
Ответ 3
Не нужно быть сложным. Самый простой и каркасный способ - использовать разрешение ACCESS_NETWORK_STATE
и просто сделать подключенный метод
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null &&
cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
Вы также можете использовать requestRouteToHost
, если у вас есть конкретный хост и тип подключения (wifi/mobile).
Вам также понадобится:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
в манифесте Android.
Ответ 4
Чтобы получить getActiveNetworkInfo()
для работы, вам нужно добавить в манифест следующее.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Ответ 5
проверить этот код... он работал у меня:)
public static void isNetworkAvailable(final Handler handler, final int timeout) {
// ask fo message '0' (not connected) or '1' (connected) on 'handler'
// the answer must be send before before within the 'timeout' (in milliseconds)
new Thread() {
private boolean responded = false;
@Override
public void run() {
// set 'responded' to TRUE if is able to connect with google mobile (responds fast)
new Thread() {
@Override
public void run() {
HttpGet requestForTest = new HttpGet("http://m.google.com");
try {
new DefaultHttpClient().execute(requestForTest); // can last...
responded = true;
}
catch (Exception e) {
}
}
}.start();
try {
int waited = 0;
while(!responded && (waited < timeout)) {
sleep(100);
if(!responded ) {
waited += 100;
}
}
}
catch(InterruptedException e) {} // do nothing
finally {
if (!responded) { handler.sendEmptyMessage(0); }
else { handler.sendEmptyMessage(1); }
}
}
}.start();
}
Затем я определяю обработчик:
Handler h = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what != 1) { // code if not connected
} else { // code if connected
}
}
};
... и запустите тест:
isNetworkAvailable(h,2000); // get the answser within 2000 ms
Ответ 6
Взгляните на класс ConnectivityManager. Вы можете использовать этот класс для получения информации об активных соединениях на хосте. http://developer.android.com/reference/android/net/ConnectivityManager.html
EDIT: вы можете использовать
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
или
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
и проанализируйте перечисление DetailedState возвращаемого объекта NetworkInfo
EDIT EDIT: Чтобы узнать, можете ли вы получить доступ к хосту, вы можете использовать
Context.getSystemService(Context.CONNECTIVITY_SERVICE)
.requestRouteToHost(TYPE_WIFI, int hostAddress)
Очевидно, что я использую Context.getSystemService(Context.CONNECTIVITY_SERVICE) в качестве прокси-сервера, чтобы сказать
ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();
Ответ 7
Найден и изменен (!) из этой ссылка:
В файле манифеста добавьте хотя бы:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
У вас, вероятно, уже есть разрешение INTERNET, если вы обращаетесь к нему. Тогда логическая функция, которая позволяет протестировать возможность подключения:
private boolean checkInternetConnection() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// test for connection
if (cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isAvailable()
&& cm.getActiveNetworkInfo().isConnected()) {
return true;
} else {
Log.v(TAG, "Internet Connection Not Present");
return false;
}
}
Ответ 8
Я сделал этот код, он самый простой, и он просто логический.
задав if(isOnline()){
Вы получаете, если есть соединение, и если он может подключиться к странице, код состояния 200
(стабильное соединение).
Обязательно добавьте правильные разрешения INTERNET
и ACCESS_NETWORK_STATE
.
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected()) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
Ответ 9
Это работает для меня:
Чтобы проверить доступность сети:
private Boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();}
Чтобы проверить доступ в Интернет:
public Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
Ответ 10
Из всего, что я видел до сих пор, самый короткий и самый чистый способ:
public final static boolean isConnected( Context context )
{
final ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
PS: Это не проверяет какой-либо хост, он просто проверяет состояние соединения, поэтому, если ваш маршрутизатор не подключен к Интернету, и ваше устройство подключено к нему, этот метод вернет true, хотя у вас нет интернета.
Для фактического теста я рекомендовал бы выполнить запрос HttpHead (например, на www.google.com) и проверить статус, если его 200 OK все в порядке, и ваше устройство имеет подключение к Интернету.
Ответ 11
Вот метод, который я использую:
public boolean isNetworkAvailable(final Context context) {
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo() != null;
}
Еще лучше, убедитесь, что он "подключен":
public boolean isNetworkAvailable(final Context context) {
final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}
Вот как использовать метод:
if (isNetworkAvailable(context)) {
// code here
} else {
// code
}
Необходимое разрешение:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
fooobar.com/questions/13931/...
Ответ 12
Там более одного пути
Во-первых, самый короткий, но неэффективный способ
Разрешение только для сети
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Тогда этот метод,
public boolean activeNetwork () {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
return isConnected;
}
Как видно из ответов ConnectivityManager
- это решение, я просто добавил его в метод, который является упрощенным методом.
ConnectivityManager
возвращает true, если есть сетевой доступ, а не доступ в Интернет, означает, что ваш WiFi подключен к маршрутизатору, но маршрутизатор не имеет интернет, он возвращает true, он проверяет наличие соединения
Во-вторых, эффективный способ
Необходимы права доступа к сети и Интернету
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Тогда этот класс,
public class CheckInternetAsyncTask extends AsyncTask<Void, Integer, Boolean> {
private Context context;
public CheckInternetAsyncTask(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(Void... params) {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnected();
if (isConnected) {
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();
if (urlc.getResponseCode() == 204 &&
urlc.getContentLength() == 0)
return true;
} catch (IOException e) {
Log.e("TAG", "Error checking internet connection", e);
return false;
}
} else {
Log.d("TAG", "No network available!");
return false;
}
return null;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.d("TAG", "result" + result);
if(result){
// do ur code
}
}
}
Вызовите CheckInternetAsyncTask
new CheckInternetAsyncTask(getApplicationContext()).execute();
Некоторые пояснения: -
-
вам нужно проверить Интернет на AsyncTask
, иначе он может бросить android.os.NetworkOnMainThreadException
в некоторых случаях
-
ConnectivityManager
используемый для проверки доступа к сети, если true отправляет запрос (Ping)
-
Отправьте запрос на http://clients3.google.com/generate_204
, этот известный URL-адрес, как известно, возвращает пустую страницу с HTTP-статусом 204, это быстрее и эффективнее, чем http://www.google.com
, читайте это. если у вас есть сайт, он предпочитает размещать ваш сайт вместо Google, только если вы используете его в приложении
-
Тайм-аут может быть изменен в диапазоне (20 мс → 2000 мс), обычно используется 1500 мс
Ответ 13
Одним из важных вариантов использования мобильных устройств для него является фактическое соединение. Это обычная проблема, когда мобильный пользователь входит в сеть Wifi с "Captive Portal", в котором им нужно войти. Я использую эту функцию блокировки в фоновом режиме, чтобы обеспечить соединение.
/*
* Not Thread safe. Blocking thread. Returns true if it
* can connect to URL, false and exception is logged.
*/
public boolean checkConnectionHttps(String url){
boolean responded = false;
HttpGet requestTest = new HttpGet(url);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 5000);
DefaultHttpClient client = new DefaultHttpClient(params);
try {
client.execute(requestTest);
responded = true;
} catch (ClientProtocolException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
} catch (IOException e) {
Log.w(MainActivity.TAG,"Unable to connect to " + url + " " + e.toString());
e.printStackTrace();
}
return responded;
}
Ответ 14
Вы можете выполнять итерацию по всем сетевым соединениям и проверять, есть ли хотя бы одно доступное соединение:
public boolean isConnected() {
boolean connected = false;
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if ((ni.getTypeName().equalsIgnoreCase("WIFI")
|| ni.getTypeName().equalsIgnoreCase("MOBILE"))
&& ni.isConnected() && ni.isAvailable()) {
connected = true;
}
}
}
return connected;
}
Ответ 15
Это работает для меня. Попробуйте.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
URL url = new URL("http://stackoverflow.com/posts/11642475/edit" );
//URL url = new URL("http://www.nofoundwebsite.com/" );
executeReq(url);
Toast.makeText(getApplicationContext(), "Webpage is available!", Toast.LENGTH_SHORT).show();
}
catch(Exception e) {
Toast.makeText(getApplicationContext(), "oops! webpage is not available!", Toast.LENGTH_SHORT).show();
}
}
private void executeReq(URL urlObject) throws IOException
{
HttpURLConnection conn = null;
conn = (HttpURLConnection) urlObject.openConnection();
conn.setReadTimeout(30000);//milliseconds
conn.setConnectTimeout(3500);//milliseconds
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Start connect
conn.connect();
InputStream response =conn.getInputStream();
Log.d("Response:", response.toString());
}}
Ответ 16
Для меня не было хорошей проверкой состояния подключения в классе Activity, потому что
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
следует вызвать там, или вам нужно нажать экземпляр Activity (контекст) на класс обработчика соединения, чтобы проверить состояние соединения там
Когда нет доступного соединения (wifi, network), я поймаю исключение UnknownHostException:
JSONObject jObj = null;
Boolean responded = false;
HttpGet requestForTest = new HttpGet("http://myserver.com");
try {
new DefaultHttpClient().execute(requestForTest);
responded = true;
} catch (UnknownHostException e) {
jObj = new JSONObject();
try {
jObj.put("answer_code", 1);
jObj.put("answer_text", "No available connection");
} catch (Exception e1) {}
return jObj;
} catch (IOException e) {
e.printStackTrace();
}
Таким образом, я могу обрабатывать этот случай вместе с другими случаями в одном классе (мой сервер всегда возвращает ответ с помощью json-строки)
Ответ 17
Я использую этот код вместо InetAddress:
try {
URL url = new URL("http://"+params[0]);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setRequestProperty("User-Agent", "Android Application:"+Z.APP_VERSION);
urlc.setRequestProperty("Connection", "close");
urlc.setConnectTimeout(1000 * 30); // mTimeout is in seconds
urlc.connect();
if (urlc.getResponseCode() == 200) {
Main.Log("getResponseCode == 200");
return new Boolean(true);
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ответ 18
Не сложно проверить статус подключения к сети Интернет/интернет. Ниже DetectConnection
класс поможет вам проверить этот статус:
import android.content.Context;
import android.net.ConnectivityManager;
public class DetectConnection {
public static boolean checkInternetConnection(Context context) {
ConnectivityManager con_manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (con_manager.getActiveNetworkInfo() != null
&& con_manager.getActiveNetworkInfo().isAvailable()
&& con_manager.getActiveNetworkInfo().isConnected()) {
return true;
} else {
return false;
}
}
}
Подробнее
Как проверить статус сети Android/Интернет
Ответ 19
Лучший подход:
public static boolean isOnline() {
try {
InetAddress.getByName("google.com").isReachable(3);
return true;
} catch (UnknownHostException e){
return false;
} catch (IOException e){
return false;
}
}
Ответ 20
Ниже приведен код из моего класса Utils
:
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
Ответ 21
public class Network {
Context context;
public Network(Context context){
this.context = context;
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
}
Ответ 22
Этот метод можно использовать для определения доступности сети -
public static boolean isDeviceOnline(Context context) {
boolean isConnectionAvail = false;
try {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo.isConnected();
} catch (Exception e) {
e.printStackTrace();
}
return isConnectionAvail;
}
Ответ 23
Я применил решение, предоставленное @Levit, и создал функцию, которая не будет вызывать дополнительный запрос Http.
Он разрешит ошибку Unable to Resolve Host
public static boolean isInternetAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null) return false;
switch (activeNetwork.getType()) {
case ConnectivityManager.TYPE_WIFI:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
case ConnectivityManager.TYPE_MOBILE:
if ((activeNetwork.getState() == NetworkInfo.State.CONNECTED ||
activeNetwork.getState() == NetworkInfo.State.CONNECTING) &&
isInternet())
return true;
break;
default:
return false;
}
return false;
}
private static boolean isInternet() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
Debug.i(exitValue + "");
return (exitValue == 0);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
Теперь назовите это,
if (!isInternetAvailable(getActivity())) {
//Show message
} else {
//Perfoem the api request
}
Ответ 24
Другие ответы, которые используют ConnectivityManager, неверны, потому что наличие сетевого подключения не означает, что у вас есть доступ в Интернет. Например, пользователь может подключиться к порталу WiFi для кофеварки, но не может попасть в Интернет. Чтобы проверить доступность Интернета, вам нужно попытаться подключиться к реальному серверу. Обычно, когда вы хотите сделать это, у вас есть определенный сервер, в который вы хотите подключиться, поэтому продолжайте и проверьте, можете ли вы подключиться к этому серверу. Вот простой способ проверки подключения к серверу.
private boolean isOnTheInternet() {
try {
URLConnection urlConnection = new URL("http://yourserver").openConnection();
urlConnection.setConnectTimeout(400);
urlConnection.connect();
return true;
} catch (Exception e) {
return false;
}
}
Причиной настройки ConnectTimeout является то, что в противном случае по умолчанию используется таймаут TCP, который может длиться много секунд.
Обратите внимание, что Android не позволит вам запускать это в своем основном потоке.
Ответ 25
Этот метод дает вам возможность для очень быстрого метода (для обратной связи в режиме реального времени) или более медленного метода (для однократных проверок, требующих надежности)
public boolean isNetworkAvailable(bool SlowButMoreReliable) {
bool Result = false;
try {
if(SlowButMoreReliable){
ConnectivityManager MyConnectivityManager = null;
MyConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo MyNetworkInfo = null;
MyNetworkInfo = MyConnectivityManager.getActiveNetworkInfo();
Result = MyNetworkInfo != null && MyNetworkInfo.isConnected();
} else
{
Runtime runtime = Runtime.getRuntime();
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int i = ipProcess.waitFor();
Result = i== 0;
}
} catch(Exception ex)
{
//Common.Exception(ex); //This method is one you should have that displays exceptions in your log
}
return Result;
}
Ответ 26
Это описано в андроидных документах
http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html
Ответ 27
Я прошел через все ответы, и я придумал свой собственный ответ, который сначала проверяет, доступен ли Интернет, и доступен ли Интернет, и проверяет, активен он или нет.
Я включил все необходимые методы и классы для проверки активного подключения к Интернету.
NetworkUtils.class
public class NetworkUtils {
public static final int STATUS_CONNECTED = 0 ;
public static boolean isInternetAvailable(Context ctx){
ConnectivityManager cm = (ConnectivityManager)ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public static int isInternetActiveWithPing() {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = process.waitFor();
return exitValue;
} catch (Exception ex) {
return -1;
}
}
public static boolean isInternetActiveWithInetAddress() {
try {
InetAddress inetAddress = InetAddress.getByName("www.google.com");
return inetAddress != null && !inetAddress.toString().equals("");
} catch (Exception ex) {
return false;
}
}
public static void displayInternetConnectionMessage(Context ctx){
Toast.makeText(ctx, "Check Internet Connection", Toast.LENGTH_SHORT).show();
}
}
Вы можете проверить, активен ли Интернет, используя приведенный ниже код:
private void checkInternetConnection() {
if (NetworkUtils.isInternetAvailable(this)) {
new Thread(new Runnable() {
@Override
public void run() {
if (NetworkUtils.isInternetActiveWithPing() == NetworkUtils.STATUS_CONNECTED) {
performNetworkingOperations();
} else {
if (NetworkUtils.isInternetActiveWithInetAddress()) {
performNetworkingOperations();
} else {
displayConnectionMessage();
}
}
}
}).start();
} else {
displayConnectionMessage();
}
}
private void performNetworkingOperations() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Internet is Available", Toast.LENGTH_SHORT).show();
}
});
}
private void displayConnectionMessage() {
runOnUiThread(new Runnable() {
@Override
public void run() {
NetworkUtils.displayInternetConnectionMessage(MainActivity.this);
}
});
}
Ответ 28
Очень важно проверить, есть ли связь с isAvailable(), и если возможно установить соединение с isConnected()
private static ConnectivityManager manager;
public static boolean isOnline(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
}
и вы можете нарушить тип активной сети WiFi:
public static boolean isConnectedWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}
или мобильный Móvil:
public static boolean isConnectedMobile(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
}
Не забывайте разрешения:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Ответ 29
Обновление 29/06/2015
Если вы используете Xamarin.Android и хотите проверить подключение, вы можете использовать пакет Nuget, который предоставит вам эту функцию на нескольких платформах. Хорошие кандидаты здесь и здесь.
[Конец обновления]
Ответы выше неплохие, но все они на Java, и почти все они проверяют возможность подключения. В моем случае мне нужно было подключиться к определенному типу связи, и я развиваюсь на Xamarin.Android. Более того, я не передаю ссылку на мои действия Контекст на аппаратном уровне, я использую контекст приложения. Итак, вот мое решение, если кто-то приходит сюда с аналогичными требованиями. Я еще не прошел полное тестирование, обновляю ответ, как только закончим с тестированием
using Android.App;
using Android.Content;
using Android.Net;
namespace Leopard.Mobile.Hal.Android
{
public class AndroidNetworkHelper
{
public static AndroidNetworkStatus GetWifiConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Wifi);
}
public static AndroidNetworkStatus GetMobileConnectivityStatus()
{
return GetConnectivityStatus(ConnectivityType.Mobile);
}
#region Implementation
private static AndroidNetworkStatus GetConnectivityStatus(ConnectivityType connectivityType)
{
var connectivityManager = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService);
var wifiNetworkInfo = connectivityManager.GetNetworkInfo(connectivityType);
var result = GetNetworkStatus(wifiNetworkInfo);
return result;
}
private static AndroidNetworkStatus GetNetworkStatus(NetworkInfo wifiNetworkInfo)
{
var result = AndroidNetworkStatus.Unknown;
if (wifiNetworkInfo != null)
{
if (wifiNetworkInfo.IsAvailable && wifiNetworkInfo.IsConnected)
{
result = AndroidNetworkStatus.Connected;
}
else
{
result = AndroidNetworkStatus.Disconnected;
}
}
return result;
}
#endregion
}
public enum AndroidNetworkStatus
{
Connected,
Disconnected,
Unknown
}
Ответ 30
Просто создайте следующий класс, который проверяет подключение к Интернету:
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;
}
}
Этот класс просто содержит метод, который возвращает логическое значение состояния соединения. Поэтому в простых терминах, если метод находит правильное соединение с Интернетом, возвращаемое значение true
, иначе false
, если не найдено действительного соединения.
Следующий метод в MainActivity затем вызывает результат из ранее описанного метода и предлагает пользователю действовать соответственно:
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.");
}
}
В приведенном выше коде, если результат является ложным (поэтому нет подключения к Интернету, пользователь отправляется на панель Wi-Fi Android, где ему предлагается подключиться к Wi-Fi-точке доступа.