Detect if Android device has Internet connection

后端 未结 15 2471
野性不改
野性不改 2020-11-22 08:54

I need to tell if my device has Internet connection or not. I found many answers like:

private boolean isNetworkAvailable() {
    ConnectivityManager connect         


        
相关标签:
15条回答
  • 2020-11-22 09:42

    Check wifi type in connectivity manager:

       //check network connection
        ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean hasNetworkConnection = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        System.out.println("Connection ? : " + hasNetworkConnection);
        //check wifi
        boolean hasWifiConnection = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
        System.out.println("Wifi ? : " + hasWifiConnection);
    

    Android Documentation describes 'TYPE_WIFI' as 'A WIFI data connection. Devices may support more than one.'

    0 讨论(0)
  • 2020-11-22 09:45
    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;
    }
    

    Hope the above code helps you, also make sure you have internet permission in ur app.

    0 讨论(0)
  • 2020-11-22 09:46

    I have modified THelper's answer slightly, to use a known hack that Android already uses to check if the connected WiFi network has Internet access. This is a lot more efficient over grabbing the entire Google home page. See here and here for more info.

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 09:48

    You don't necessarily need to make a full HTTP connection. You could try just opening a TCP connection to a known host and if it succeeds you have internet connectivity.

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

    Then just check with:

    boolean online = hostAvailable("www.google.com", 80);
    
    0 讨论(0)
  • 2020-11-22 09:48

    Based on the accepted answers, I have built this class with a listener so you can use it in the main thread:

    First: InterntCheck class which checks for internet connection in the background then call a listener method with the result.

    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: instantiate an instance of the class in the main thread and wait for the response (if you have worked with Firebase api for android before this should be familiar to you!).

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

    Now inside onComplete method you will get whether the device is connected to the internet or not.

    0 讨论(0)
  • 2020-11-22 09:51

    You are right. The code you've provided only checks if there is a network connection. The best way to check if there is an active Internet connection is to try and connect to a known server via 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;
    }
    

    Of course you can substitute the http://www.google.com URL for any other server you want to connect to, or a server you know has a good uptime.

    As Tony Cho also pointed out in this comment below, make sure you don't run this code on the main thread, otherwise you'll get a NetworkOnMainThread exception (in Android 3.0 or later). Use an AsyncTask or Runnable instead.

    If you want to use google.com you should look at Jeshurun's modification. In his answer he modified my code and made it a bit more efficient. If you connect to

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

    and then check the responsecode for 204

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

    then you don't have to fetch the entire google home page first.

    0 讨论(0)
提交回复
热议问题