programing

Android에서 인터넷 액세스를 확인하는 방법은 무엇입니까?

nasanasas 2020. 10. 2. 22:30
반응형

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

네트워크 연결 / 인터넷 액세스

  • 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 등)에서는 작동하지 않으며 인터넷을 사용할 수없는 경우 잠시 차단됩니다.

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

+매우 빠르고 (어느 쪽이든) 모든 장치에서 작동하며 매우 안정적입니다.

- UI 스레드에서 실행할 수 없습니다.

이것은 모든 장치에서 매우 안정적으로 작동하며 매우 빠릅니다. 그러나 별도의 작업 (예 : ScheduledExecutorService또는 AsyncTask) 에서 실행해야합니다 .

가능한 질문

  • 정말 충분히 빠르나요?

    예, 매우 빠릅니다 ;-)

  • 인터넷에서 무언가를 테스트하는 것 외에 인터넷을 확인할 수있는 신뢰할 수있는 방법이 없습니까?

    내가 아는 한 알려 주시면 답변을 수정하겠습니다.

  • DNS가 다운되면 어떻게됩니까?

    Google DNS (예 8.8.8.8:)는 세계에서 가장 큰 공용 DNS입니다. 2013 년 현재 하루에 1,300 억 건의 요청을 처리했습니다. 당신의 앱은 아마도 오늘의 화제가 아닐 것입니다.

  • 어떤 권한이 필요합니까?

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

    그냥 인터넷 액세스-놀랍습니다 ^^ (Btw 당신은 여기에서 제안한 방법 중 일부 가이 허가없이 인터넷 액세스에 대한 원격 접착제를 가질 수 있는지 생각해 본 적이 있습니까?)

 

추가 : 원샷 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예 (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 */}

장치가 비행기 모드 (또는 아마도 사용 가능한 네트워크가 없습니다 다른 상황에서)하면 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. 그러나 이것은 개별 사용 사례에 달려 있다고 생각합니다.


복잡 할 필요가 없습니다. 가장 간단하고 프레임 워크 방식은 ACCESS_NETWORK_STATE권한 을 사용 하고 연결된 방법을 만드는 것입니다.

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

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

requestRouteToHost특정 호스트 및 연결 유형 (wifi / 모바일)을 염두에두고있는 경우 에도 사용할 수 있습니다 .

또한 다음이 필요합니다.

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

당신의 안드로이드 매니페스트에서.


getActiveNetworkInfo()작동 하려면 매니페스트에 다음을 추가해야합니다.

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

이 코드를 확인하십시오 ... 그것은 나를 위해 일했습니다 :)

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

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) 

반환 된 NetworkInfo 개체의 DetailedState 열거 형을 구문 분석합니다.

편집 편집 : 호스트에 액세스 할 수 있는지 확인하려면 다음을 사용할 수 있습니다.

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

분명히 Context.getSystemService (Context.CONNECTIVITY_SERVICE)를 프록시로 사용하고 있습니다.

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

링크 에서 발견되고 수정 된 (!) :

매니페스트 파일에 최소한 다음을 추가하십시오.

<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(안정적인 연결)가 표시됩니다.

올바른 추가 확인 INTERNETACCESS_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 대신 웹 사이트를 배치하는 것이 좋습니다.

  • 타임 아웃은 범위 변경 가능 (20ms-> 2000ms), 일반적으로 1500ms 사용


내가 지금까지 본 모든 것 중에서 가장 짧고 깨끗한 방법은 다음과 같습니다.

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

추신 : 이것은 어떤 호스트도 핑하지 않고 연결 상태를 확인하기 때문에 라우터가 인터넷에 연결되어 있지 않고 장치가 연결된 경우 인터넷이 없어도이 방법은 true를 반환 합니다 .
실제 테스트를 위해 HttpHead 요청 (예 : www.google.com)을 실행 하고 상태를 확인하는 것이 좋습니다. 200 OK 모든 것이 정상 이고 장치가 인터넷에 연결되어 있는지 확인 합니다.


내가 사용하는 방법은 다음과 같습니다.

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

https://stackoverflow.com/a/16124915/950427


실제 연결이 존재하는지 확인하기위한 모바일 장치의 중요한 사용 사례 중 하나입니다. 이것은 모바일 사용자가 로그인해야하는 "Captive Portal"을 사용하여 Wifi 네트워크에 들어갈 때 흔히 발생하는 문제입니다.이 차단 ​​기능을 백그라운드에서 사용하여 연결이 있는지 확인합니다.

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

나에게 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 문자열로 응답).


그것은 나를 위해 작동합니다. 그것을 시도하십시오.

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

이 방법은 매우 빠른 방법 (실시간 피드백 용) 또는 느린 방법 (신뢰성이 필요한 일회성 검사 용)에 대한 옵션을 제공합니다.

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

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 네트워크 / 인터넷 연결 상태를 확인하는 것은 복잡하지 않습니다. 아래 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 네트워크 / 인터넷 연결 상태를 확인하는 방법을 참조하십시오.


최선의 접근 방식 :

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

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

다음은 내 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();
}

}

이 방법을 사용하여 네트워크 가용성을 감지 할 수 있습니다.

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

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

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는 메인 스레드에서 이것을 실행할 수 없습니다.


이것은 안드로이드 문서 http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html 에서 다룹니다.


나는 모든 답변을 검토하고 인터넷을 사용할 수 있는지 먼저 확인하고 인터넷을 사용할 수 있는지 확인한 다음 활성화 여부를 확인하는 내 답변을 내놓았습니다.

활성 인터넷 연결을 확인하는 데 필요한 모든 방법과 수업을 포함했습니다.

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

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

또는 모바일 모빌 :

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

위 코드에서 결과가 거짓이면 (따라서 인터넷에 연결되어 있지 않으면 사용자가 Android Wi-Fi 패널로 이동하여 Wi-Fi 핫스팟에 연결하라는 메시지가 표시됩니다.


업데이트 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
    }

참고 URL : https://stackoverflow.com/questions/1560788/how-to-check-internet-access-on-android-inetaddress-never-times-out

반응형