Detect if Android device has Internet connection

后端 未结 15 2729
野性不改
野性不改 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:55

    Use the following class, updated to the last API level: 29.

    // License: MIT
    // http://opensource.org/licenses/MIT
    package net.i2p.android.router.util;
    
    import android.content.Context;
    import android.net.ConnectivityManager;
    import android.net.Network;
    import android.net.NetworkCapabilities;
    import android.net.NetworkInfo;
    import android.os.AsyncTask;
    import android.os.Build;
    import android.telephony.TelephonyManager;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.ArrayList;
    import java.util.concurrent.CancellationException;
    
    
    
    /**
     * Check device's network connectivity and speed.
     *
     * @author emil http://stackoverflow.com/users/220710/emil
     * @author str4d
     * @author rodrigo https://stackoverflow.com/users/5520417/rodrigo
     */
    public class ConnectivityAndInternetAccessCheck {
    
        private static ArrayList < String > hosts = new ArrayList < String > () {
            {
                add("google.com");
                add("facebook.com");
                add("apple.com");
                add("amazon.com");
                add("twitter.com");
                add("linkedin.com");
                add("microsoft.com");
            }
        };
        /**
         * Get the network info.
         *
         * @param context the Context.
         * @return the active NetworkInfo.
         */
        private static NetworkInfo getNetworkInfo(Context context) {
            NetworkInfo networkInfo = null;
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (cm != null) {
                networkInfo = cm.getActiveNetworkInfo();
            }
            return networkInfo;
        }
    
        /**
         * Gets the info of all networks
         * @param context The context
         * @return an array of @code{{@link NetworkInfo}}
         */
        private static NetworkInfo[] getAllNetworkInfo(Context context) {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getAllNetworkInfo();
        }
    
        /**
         * Gives the connectivity manager
         * @param context The context
         * @return the @code{{@link ConnectivityManager}}
         */
        private static ConnectivityManager getConnectivityManager(Context context) {
            return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        }
    
        /**
         * Check if there is any connectivity at all.
         *
         * @param context the Context.
         * @return true if we are connected to a network, false otherwise.
         */
        public static boolean isConnected(Context context) {
            boolean isConnected = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
                Network[] networks = connectivityManager.getAllNetworks();
                networksloop: for (Network network: networks) {
                    if (network == null) {
                        isConnected = false;
                    } else {
                        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                        if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                            isConnected = true;
                            break networksloop;
                        }
                        else {
                            isConnected = false;
                        }
                    }
                }
    
            } else {
                NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
                networkinfosloop: for (NetworkInfo info: networkInfos) {
                    // Works on emulator and devices.
                    // Note the use of isAvailable() - without this, isConnected() can
                    // return true when Wifi is disabled.
                    // http://stackoverflow.com/a/2937915
                    isConnected = info != null && info.isAvailable() && info.isConnected();
                    if (isConnected) {
                        break networkinfosloop;
                    }
                }
    
            }
            return isConnected;
        }
    
        /**
         * Check if there is any connectivity to a Wifi network.
         *
         * @param context the Context.
         * @return true if we are connected to a Wifi network, false otherwise.
         */
        public static boolean isConnectedWifi(Context context) {
            boolean isConnectedWifi = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
                Network[] networks = connectivityManager.getAllNetworks();
                networksloop: for (Network network: networks) {
                    if (network == null) {
                        isConnectedWifi = false;
                    } else {
                        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                        if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                                isConnectedWifi = true;
                                break networksloop;
                            } else {
                                isConnectedWifi = false;
                            }
                        }
                    }
    
                }
    
    
            } else {
                NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
                networkinfosloop: for (NetworkInfo n: networkInfos) {
                    isConnectedWifi = n != null && n.isAvailable() && n.isConnected() && n.getType() == ConnectivityManager.TYPE_WIFI;
                    if (isConnectedWifi) {
                        break networkinfosloop;
                    }
    
                }
            }
            return isConnectedWifi;
        }
    
        /**
         * Check if there is any connectivity to a mobile network.
         *
         * @param context the Context.
         * @return true if we are connected to a mobile network, false otherwise.
         */
        public static boolean isConnectedMobile(Context context) {
            boolean isConnectedMobile = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                ConnectivityManager connectivityManager = ConnectivityAndInternetAccessCheck.getConnectivityManager(context);
                Network[] allNetworks = connectivityManager.getAllNetworks();
                networksloop: for (Network network: allNetworks) {
                    if (network == null) {
                        isConnectedMobile = false;
                    } else {
                        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
                        if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)){
                            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                                isConnectedMobile = true;
                                break networksloop;
                            } else {
                                isConnectedMobile = false;
                            }
                        }
                    }
    
                }
    
            } else {
                NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
                networkinfosloop: for (NetworkInfo networkInfo: networkInfos) {
                    isConnectedMobile = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
                    if (isConnectedMobile) {
                        break networkinfosloop;
                    }
                }
            }
            return isConnectedMobile;
        }
    
        /**
         * Check if there is fast connectivity.
         *
         * @param context the Context.
         * @return true if we have "fast" connectivity, false otherwise.
         */
        public static boolean isConnectedFast(Context context) {
            boolean isConnectedFast = false;
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                NetworkInfo[] networkInfos = ConnectivityAndInternetAccessCheck.getAllNetworkInfo(context);
                networkInfosloop:
                for (NetworkInfo networkInfo: networkInfos) {
                    isConnectedFast = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected() && isConnectionFast(networkInfo.getType(), networkInfo.getSubtype());
                    if (isConnectedFast) {
                        break networkInfosloop;
                    }
                }
            } else {
                throw new UnsupportedOperationException();
            }
            return isConnectedFast;
        }
    
        /**
         * Check if the connection is fast.
         *
         * @param type the network type.
         * @param subType the network subtype.
         * @return true if the provided type/subtype combination is classified as fast.
         */
        private static boolean isConnectionFast(int type, int subType) {
            if (type == ConnectivityManager.TYPE_WIFI) {
                return true;
            } else if (type == ConnectivityManager.TYPE_MOBILE) {
                switch (subType) {
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                        return false; // ~ 50-100 kbps
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                        return false; // ~ 14-64 kbps
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                        return false; // ~ 50-100 kbps
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                        return true; // ~ 400-1000 kbps
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                        return true; // ~ 600-1400 kbps
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                        return false; // ~ 100 kbps
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                        return true; // ~ 2-14 Mbps
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                        return true; // ~ 700-1700 kbps
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                        return true; // ~ 1-23 Mbps
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                        return true; // ~ 400-7000 kbps
                    /*
                     * Above API level 7, make sure to set android:targetSdkVersion
                     * to appropriate level to use these
                     */
                    case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11
                        return true; // ~ 1-2 Mbps
                    case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                        return true; // ~ 5 Mbps
                    case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                        return true; // ~ 10-20 Mbps
                    case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                        return false; // ~25 kbps
                    case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                        return true; // ~ 10+ Mbps
                    // Unknown
                    case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                    default:
                        return false;
                }
            } else {
                return false;
            }
        }
    
        public ArrayList < String > getHosts() {
            return hosts;
        }
    
        public void setHosts(ArrayList < String > hosts) {
            this.hosts = hosts;
        }
        //TODO Debug on devices
        /**
         * Checks that Internet is available by pinging DNS servers.
         */
        private static class InternetConnectionCheckAsync extends AsyncTask < Void, Void, Boolean > {
    
            private Context context;
    
            /**
             * Creates an instance of this class
             * @param context The context
             */
            public InternetConnectionCheckAsync(Context context) {
                this.setContext(context);
            }
    
            /**
             * Cancels the activity if the device is not connected to a network.
             */
            @Override
            protected void onPreExecute() {
                if (!ConnectivityAndInternetAccessCheck.isConnected(getContext())) {
                    cancel(true);
                }
            }
    
            /**
             * Tells whether there is Internet access
             * @param voids The list of arguments
             * @return True if Internet can be accessed
             */
            @Override
            protected Boolean doInBackground(Void...voids) {
                return isConnectedToInternet(getContext());
            }
    
            @Override
            protected void onPostExecute(Boolean aBoolean) {
                super.onPostExecute(aBoolean);
            }
    
            /**
             * The context
             */
            public Context getContext() {
                return context;
            }
    
            public void setContext(Context context) {
                this.context = context;
            }
        } //network calls shouldn't be called from main thread otherwise it will throw //NetworkOnMainThreadException
    
        /**
         * Tells whether Internet is reachable
         * @return true if Internet is reachable, false otherwise
         * @param context The context
         */
        public static boolean isInternetReachable(Context context) {
            try {
                return new InternetConnectionCheckAsync(context).execute().get();
            } catch (CancellationException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }
    
        /**
         * Tells whether there is Internet connection
         * @param context The context
         * @return @code {true} if there is Internet connection
         */
        private static boolean isConnectedToInternet(Context context) {
            boolean isAvailable = false;
            if (!ConnectivityAndInternetAccessCheck.isConnected(context)) {
                isAvailable = false;
            } else {
                try {
                    foreachloop: for (String h: new ConnectivityAndInternetAccessCheck().getHosts()) {
                        if (isHostAvailable(h)) {
                            isAvailable = true;
                            break foreachloop;
                        }
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return isAvailable;
    
        }
    
        /**
         * Checks if the host is available
         * @param hostName
         * @return
         * @throws IOException
         */
        private static boolean isHostAvailable(String hostName) throws IOException {
            try (Socket socket = new Socket()) {
                int port = 80;
                InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
                socket.connect(socketAddress, 3000);
    
                return true;
            } catch (UnknownHostException unknownHost) {
                return false;
            }
        }
    }
    

提交回复
热议问题