카테고리 보관물: Android

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예 (코 틀린)

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 ‘s solution ) :

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 / mobile)을 염두에두고 사용할 수도 있습니다.

또한 다음이 필요합니다.

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

반환 된 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();

답변

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

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