Как проверить доступ в интернет на 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();
    }   
}

64 ответа

Решение

Сетевое подключение / доступ в интернет

  • isConnectedOrConnecting() (используется в большинстве ответов) проверяет любое сетевое соединение
  • Чтобы узнать, есть ли у какой-либо из этих сетей доступ в Интернет, воспользуйтесь одним из следующих

A) Пинг сервера (легко)

// 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 и т. д.), он блокируется некоторое время, если интернет недоступен.

Б) Подключение к сокету в интернете (дополнительно)

// 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 Пример (Котлин)

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

Если устройство находится в режиме полета (или, по-видимому, в других ситуациях, когда нет доступной сети), cm.getActiveNetworkInfo() будет nullтак что вам нужно добавить null проверять.

Модифицировано ( решение Эдди) ниже:

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, Я думаю, что это зависит от индивидуального варианта использования.

Не нужно быть сложным. Самый простой и каркасный способ - это использовать ACCESS_NETWORK_STATE разрешение и просто сделать подключенный метод

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    return cm.getActiveNetworkInfo() != null && 
       cm.getActiveNetworkInfo().isConnectedOrConnecting();
}

Вы также можете использовать requestRouteToHost Если у вас есть конкретный хост и тип подключения (Wi-Fi/ мобильный).

Вам также понадобится:

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

в вашем андроид манифесте.

Получить getActiveNetworkInfo() Для работы необходимо добавить следующее в манифест.

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

Посмотрите на класс ConnectivityManager. Вы можете использовать этот класс для получения информации об активных соединениях на хосте. http://developer.android.com/reference/android/net/ConnectivityManager.html

РЕДАКТИРОВАТЬ: Вы можете использовать

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE) 

или же

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .getNetworkInfo(ConnectivityManager.TYPE_WIFI) 

и проанализировать перечисление DetailState возвращенного объекта NetworkInfo

РЕДАКТИРОВАТЬ РЕДАКТИРОВАТЬ: чтобы узнать, можете ли вы получить доступ к хосту, вы можете использовать

Context.getSystemService(Context.CONNECTIVITY_SERVICE)
    .requestRouteToHost(TYPE_WIFI, int hostAddress)

Очевидно, я использую Context.getSystemService(Context.CONNECTIVITY_SERVICE) в качестве прокси, чтобы сказать

ConnectivityManager cm = Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.yourMethodCallHere();

Проверь этот код... у меня сработало:)

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

Найден и изменен (!) По этой ссылке:

В своем файле манифеста добавьте как минимум:

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

Возможно, у вас уже есть разрешение на доступ в Интернет, если вы обращаетесь к нему. Тогда логическая функция, которая позволяет проверять наличие соединения:

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;
    }
}

Я сделал этот код, он самый простой и просто логический. спрашивая 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;
}

Это работает для меня:

Чтобы проверить доступность сети:

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;
}

Там больше, чем один способ

Во-первых, самый короткий, но неэффективный способ

Требуется только разрешение состояния сети

<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 мс

Котлин и сопрограммы

Я поместил функцию в ViewModel, который имеет viewModelScope. Используя наблюдаемыйLiveData Сообщаю активность о подключении.

ViewModel

 fun checkInternetConnection() {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                try {
                    val timeoutMs = 3000
                    val socket = Socket()
                    val socketAddress = InetSocketAddress("8.8.8.8", 53)

                    socket.connect(socketAddress, timeoutMs)
                    socket.close()

                    withContext(Dispatchers.Main) {
                        _connection.value = true
                    }
                }
                catch(ex: IOException) {
                    withContext(Main) {
                        _connection.value = false
                    }
                }
            }
        }
    }

 private val _connection = MutableLiveData<Boolean>()
 val connection: LiveData<Boolean> = _connection

Деятельность

 private fun checkInternetConnection() {
     viewModel.connection.observe(this) { hasInternet ->
         if(!hasInternet) {
             //hasn't connection
         }
         else {
            //has connection
         }
     }
  }

Вот метод, который я использую:

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" />

/questions/11883942/android-proverit-internet-soedinenie/11883948#11883948

Один важный случай использования на мобильных устройствах, чтобы убедиться, что фактическое соединение существует. Это обычная проблема, когда мобильный пользователь входит в сеть 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;
}

Из всего, что я видел до сих пор, самый короткий и чистый путь должен быть:

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 в порядке, все в порядке и ваше устройство подключено к Интернету.

Это работает для меня. Попробуйте это.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
        URL url = new URL("http://stackru.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());
}}

Для меня не было хорошей практикой проверять состояние соединения в классе Activity, потому что

ConnectivityManager cm =
    (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

должен быть вызван там, или вам нужно передать ваш экземпляр Activity (контекст) в класс обработчика соединения, чтобы можно было там проверить состояние соединения. Когда нет доступного соединения (wifi, сеть), я ловлю исключение 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)

Очень важно проверить, есть ли у нас соединение с 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" />

Вы можете перебрать все сетевые подключения и проверить, есть ли хотя бы одно доступное подключение:

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;
}

Этот метод дает вам возможность действительно быстрого метода (для обратной связи в реальном времени) или более медленного метода (для однократных проверок, требующих надежности)

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;
}

Вы можете использовать этот метод для определения доступности сети

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;
    }

Я использую этот код вместо 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();
    }

Это описано в документации для Android http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html

Лучший подход:

public static boolean isOnline() {
    try {
    InetAddress.getByName("google.com").isReachable(3);

    return true;
    } catch (UnknownHostException e){
    return false;
    } catch (IOException e){
    return false;
    }
    }

Нетрудно проверить состояние сети Android / интернет-соединения. Нижеприведенное 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 / подключения к Интернету.

Я применил решение, предоставленное @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
}

Ниже приведен код из моего Utils учебный класс:

public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
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();
}

}

Я просмотрел все ответы и нашел свой собственный ответ, который сначала проверяет, доступен ли Интернет и доступен ли он, а затем проверяет, активен он или нет.

Я включил все необходимые методы и классы для проверки активного подключения к Интернету.

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

Обновление 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
    }

Используйте это расширение Kotlin:

/**
 * Check whether network is available
 *
 * @param context
 * @return Whether device is connected to Network.
 */
fun Context.isNetworkAvailable(): Boolean {
    with(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //Device is running on Marshmallow or later Android OS.
            with(getNetworkCapabilities(activeNetwork)) {
                return hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || hasTransport(
                    NetworkCapabilities.TRANSPORT_CELLULAR
                )
            }
        } else {
            activeNetworkInfo?.let {
                // connected to the internet
                @Suppress("DEPRECATION")
                return listOf(ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_MOBILE).contains(it.type)
            }
        }
    }
    return false
}
Другие вопросы по тегам