如何在Android上检查互联网访问? InetAddress永不超时 [英] How to check internet access on Android? InetAddress never times out

查看:161
本文介绍了如何在Android上检查互联网访问? InetAddress永不超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了一个AsyncTask,它应该检查对主机名的网络访问.但是doInBackground()永远不会超时.有人有线索吗?

I got a AsyncTask that is supposed to check the network access to a host name. But the doInBackground() is never timed out. Anyone have a clue?

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()(用于大多数答案)检查是否有任何网络连接
  • 要了解这些网络中的任何一个是否具有 internet 访问权限,请使用以下其中一项
  • Network connection / Internet access

    • isConnectedOrConnecting() (used in most answers) checks for any network connection
    • To know whether any of those networks have internet access, use one of the following
    • // 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等)上不起作用,如果没有可用的互联网,则会阻止一段时间.

      - does not work on some old devices (Galays S3, etc.), it blocks a while if no internet is available.

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

      +非常快(无论哪种方式),都可以在所有设备上运行,非常可靠

      + very fast (either way), works on all devices, very reliable

      -无法在UI线程上运行

      - can't run on the UI thread

      这在每个设备上都非常可靠地工作,并且速度非常快.不过,它需要在单独的任务中运行(例如ScheduledExecutorServiceAsyncTask).

      This works very reliably, on every device, and is very fast. It needs to run in a separate task though (e.g. ScheduledExecutorService or AsyncTask).

      • 真的够快吗?

      • Is it really fast enough?

      是的,非常快;-)

      除了在Internet上进行测试以外,没有可靠的方法来检查Internet吗?

      Is there no reliable way to check internet, other than testing something on the internet?

      据我所知,不过请告诉我,我将编辑我的答案.

      如果DNS关闭,该怎么办?

      What if the DNS is down?

      Google DNS(例如8.8.8.8)是世界上最大的公共DNS.截至2013年,它每天处理1300亿个请求.只是说,您的应用可能不会成为今天的话题.

      Google DNS (e.g. 8.8.8.8) is the largest public DNS in the world. As of 2013 it served 130 billion requests a day. Let 's just say, your app would probably not be the talk of the day.

      需要哪些权限?

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

      仅需Internet访问-惊喜^^(顺便说一句,您是否曾想过,如果没有此许可,此处建议的某些方法甚至可能对Internet访问具有遥远的吸引力?)

       

      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示例(科特琳)

      Extra: One-shot RxJava/RxAndroid Example (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 */}
      

      这篇关于如何在Android上检查互联网访问? InetAddress永不超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆