首页 文章

检测Android设备是否具有Internet连接

提问于
浏览
127

我需要告诉我的设备是否有Internet连接 . 我找到了许多答案,如:

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
         = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null;
}

(摘自检测Android上是否有可用的Internet连接 . )

但这不对,例如,如果我 connected to a wireless network which doesn't have Internet access ,这个方法将返回true ... Is there a way to tell if the device has Internet connection and not if it is only connected to something?

9 回答

  • 176

    你是对的 . 您提供的代码仅检查是否存在网络连接 . 检查是否存在活动Internet连接的最佳方法是尝试通过http连接到已知服务器 .

    public static boolean hasActiveInternetConnection(Context context) {
        if (isNetworkAvailable(context)) {
            try {
                HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
                urlc.setRequestProperty("User-Agent", "Test");
                urlc.setRequestProperty("Connection", "close");
                urlc.setConnectTimeout(1500); 
                urlc.connect();
                return (urlc.getResponseCode() == 200);
            } catch (IOException e) {
                Log.e(LOG_TAG, "Error checking internet connection", e);
            }
        } else {
            Log.d(LOG_TAG, "No network available!");
        }
        return false;
    }
    

    当然,您可以将 http://www.google.com URL替换为您要连接的任何其他服务器,或者您知道的服务器具有良好的正常运行时间 .

    正如Tony Cho在this comment below中指出的那样,请确保您不会获得NetworkOnMainThread异常(在Android 3.0或更高版本中) . 请改用AsyncTask或Runnable .

    如果你想使用google.com,你应该看看Jeshurun的修改 . 在his answer中,他修改了我的代码并使其更有效率 . 如果你连接到

    HttpURLConnection urlc = (HttpURLConnection) 
                (new URL("http://clients3.google.com/generate_204")
                .openConnection());
    

    然后检查204的响应代码

    return (urlc.getResponseCode() == 204 && urlc.getContentLength() == 0);
    

    那么你不必先获取整个谷歌主页 .

  • 82

    我稍微修改了THelper的答案,使用Android已经用来检查连接的WiFi网络是否可以访问Internet的已知黑客 . 这比 grab 整个Google主页更有效率 . 有关详细信息,请参阅herehere .

    public static boolean hasInternetAccess(Context context) {
        if (isNetworkAvailable(context)) {
            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();
                return (urlc.getResponseCode() == 204 &&
                            urlc.getContentLength() == 0);
            } catch (IOException e) {
                Log.e(TAG, "Error checking internet connection", e);
            }
        } else {
            Log.d(TAG, "No network available!");
        }
        return false;
    }
    
  • 8
    public boolean isInternetWorking() {
        boolean success = false;
        try {
            URL url = new URL("https://google.com");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(10000);
            connection.connect();
            success = connection.getResponseCode() == 200;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return success;
    }
    

    如果互联网实际可用,则返回true

    确保您拥有这两项权限

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

    如果您的目标是Lollipop或更高版本,则可以使用新的NetworkCapabilities类,即:

    public static boolean hasInternetConnection(final Context context) {
        final ConnectivityManager connectivityManager = (ConnectivityManager)context.
                getSystemService(Context.CONNECTIVITY_SERVICE);
    
        final Network network = connectivityManager.getActiveNetwork();
        final NetworkCapabilities capabilities = connectivityManager
                .getNetworkCapabilities(network);
    
        return capabilities != null
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
    }
    
  • 3

    试试这个

    public class ConnectionDetector {
        private Context _context;
    
        public ConnectionDetector(Context context) {
            this._context = context;
        }
    
        public boolean isConnectingToInternet() {
            if (networkConnectivity()) {
                try {
                    HttpURLConnection urlc = (HttpURLConnection) (new URL(
                            "http://www.google.com").openConnection());
                    urlc.setRequestProperty("User-Agent", "Test");
                    urlc.setRequestProperty("Connection", "close");
                    urlc.setConnectTimeout(3000);
                    urlc.setReadTimeout(4000);
                    urlc.connect();
                    // networkcode2 = urlc.getResponseCode();
                    return (urlc.getResponseCode() == 200);
                } catch (IOException e) {
                    return (false);
                }
            } else
                return false;
    
        }
    
        private boolean networkConnectivity() {
            ConnectivityManager cm = (ConnectivityManager) _context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = cm.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isConnected()) {
                return true;
            }
            return false;
        }
    }
    

    您必须将以下权限添加到清单文件中:

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

    然后这样打电话:

    if((new ConnectionDetector(MyService.this)).isConnectingToInternet()){
        Log.d("internet status","Internet Access");
    }else{
        Log.d("internet status","no Internet Access");
    }
    
  • 17

    您不一定需要 Build 完整的HTTP连接 . 您可以尝试只打开与已知主机的TCP连接,如果成功,则可以连接互联网 .

    public boolean hostAvailable(String host, int port) {
      try (Socket socket = new Socket()) {
        socket.connect(new InetSocketAddress(host, port), 2000);
        return true;
      } catch (IOException e) {
        // Either we have a timeout or unreachable host or failed DNS lookup
        System.out.println(e);
        return false;
      }
    }
    

    然后检查:

    boolean online = hostAvailable("www.google.com", 80);
    
  • 0

    根据接受的答案,我用一个监听器构建了这个类,所以你可以在主线程中使用它:

    First :InterntCheck类在后台检查互联网连接,然后使用结果调用侦听器方法 .

    public class InternetCheck extends AsyncTask<Void, Void, Void> {
    
    
        private Activity activity;
        private InternetCheckListener listener;
    
        public InternetCheck(Activity x){
    
            activity= x;
    
        }
    
        @Override
        protected Void doInBackground(Void... params) {
    
    
            boolean b = hasInternetAccess();
            listener.onComplete(b);
    
            return null;
        }
    
    
        public void isInternetConnectionAvailable(InternetCheckListener x){
            listener=x;
            execute();
        }
    
        private boolean isNetworkAvailable() {
            ConnectivityManager connectivityManager = (ConnectivityManager) activity.getSystemService(CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null;
        }
        private boolean hasInternetAccess() {
            if (isNetworkAvailable()) {
                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();
                    return (urlc.getResponseCode() == 204 &&
                            urlc.getContentLength() == 0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Log.d("TAG", "No network available!");
            }
            return false;
        }
    
        public interface InternetCheckListener{
            void onComplete(boolean connected);
        }
    
    }
    

    Second :在主线程中实例化一个类的实例并等待响应(如果你已经使用过Firebase api for android,那么你应该熟悉它!) .

    new InternetCheck(activity).isInternetConnectionAvailable(new InternetCheck.InternetCheckListener() {
    
            @Override
            public void onComplete(boolean connected) {
               //proceed!
            }
        });
    

    现在在onComplete方法中,您将获得设备是否已连接到互联网 .

  • 2
    private static NetworkUtil mInstance;
    private volatile boolean mIsOnline;
    
    private NetworkUtil() {
        ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
        exec.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                boolean reachable = false;
                try {
                    Process process = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
                    int returnVal = process.waitFor();
                    reachable = (returnVal==0);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mIsOnline = reachable;
            }
        }, 0, 5, TimeUnit.SECONDS);
    }
    
    public static NetworkUtil getInstance() {
        if (mInstance == null) {
            synchronized (NetworkUtil.class) {
                if (mInstance == null) {
                    mInstance = new NetworkUtil();
                }
            }
        }
        return mInstance;
    }
    
    public boolean isOnline() {
        return mIsOnline;
    }
    

    希望上面的代码可以帮助您,同时确保您在我的应用程序中拥有互联网权限 .

  • 0

    documentation执行此操作的最新方法是使用 ConnectivityManager 查询活动网络并确定它是否具有Internet连接 .

    public boolean hasInternetConnectivity() {
        ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return (activeNetwork != null &&
                          activeNetwork.isConnectedOrConnecting());
    }
    

    将这两个权限添加到AndroidManifest.xml文件中:

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

相关问题