【问题标题】:ConnectivityManager getNetworkInfo(int) deprecated不推荐使用 ConnectivityManager getNetworkInfo(int)
【发布时间】:2015-12-09 09:42:18
【问题描述】:

使用 compileSdkVersion 23,但尝试支持早至 9。

getNetworkInfo(int) 在 23 中已弃用。建议改用 getAllNetworks()getNetworkInfo(Network)。然而,这两个都需要至少 API 21。

是否有我们可以在支持包中使用的类来帮助解决这个问题?

我知道有人提出了解决方案 before,但是我的最低 API 要求为 9 的挑战带来了问题。

【问题讨论】:

标签: android networking android-6.0-marshmallow android-connectivitymanager


【解决方案1】:

你可以使用:

getActiveNetworkInfo();

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
        // connected to wifi
    } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // connected to mobile data
    }
} else {
    // not connected to the internet
}

或者在开关盒中

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            // connected to wifi
            break;
        case ConnectivityManager.TYPE_MOBILE:
            // connected to mobile data
            break;
        default:
            break;
    }
} else {
    // not connected to the internet
}

【讨论】:

  • @ShirishHerwade - 是的,在这种情况下不需要广播接收器。如果包含上下文引用,getActiveNetworkInfo() 可以放在它自己的方法中。
  • 从 Android 9 开始,SDK 28 现已弃用。
  • activeNetwork.getType() 已弃用,ConnectivityManager.TYPE_WIFI 已弃用
  • 现在替换为cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
  • 厌倦了这种不断的弃用周期
【解决方案2】:

2020 年 2 月更新:

接受的答案在28 (Android P) 中再次被弃用,但其替换方法仅适用于23 (Android M)。为了支持旧设备,我用 Kotlin 和 Java 编写了一个辅助函数。

使用方法:

int type = getConnectionType(getApplicationContext());

它返回一个int,您可以在代码中将其更改为enum

0:没有可用的互联网(可能处于飞行模式,或者正在加入 wi-fi)。

1:蜂窝网络(移动数据、3G/4G/LTE 等)。

2:无线网络。

3:VPN

您可以复制 Kotlin 或 Java 版本的辅助函数。

科特林:

@IntRange(from = 0, to = 3)
fun getConnectionType(context: Context): Int {
    var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi; 3: vpn
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm?.run {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                if (hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_VPN)){
                    result = 3
                }
            }
        }
    } else {
        cm?.run {
            cm.activeNetworkInfo?.run {
                if (type == ConnectivityManager.TYPE_WIFI) {
                    result = 2
                } else if (type == ConnectivityManager.TYPE_MOBILE) {
                    result = 1
                } else if(type == ConnectivityManager.TYPE_VPN) {
                    result = 3
                }
            }
        }
    }
    return result
}

Java:

@IntRange(from = 0, to = 3)
public static int getConnectionType(Context context) {
    int result = 0; // Returns connection type. 0: none; 1: mobile data; 2: wifi; 3: vpn
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
                    result = 3;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = 2;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = 1;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_VPN) {
                    result = 3;
                }
            }
        }
    }
    return result;
}

【讨论】:

  • 由于可能有 2 个结果,因此最好使用布尔值而不是返回整数...
  • @Christian 如黄色部分所述,此辅助函数返回 3 种可能的状态:No InternetCellularWi-Fi。如果您不关心连接类型,请随意修改代码以适合您的应用程序。
  • 上述解决方案中的评论“如果您连接到 Wi-Fi 和 VPN,那么您当前的状态可能是 TRANSPORT_VPN,因此您可能还想检查它。”?
  • @Lukas 如果您使用 Boolean 包装类而不是原始的 boolean,则必须小心。在 if 语句中,您必须添加对 null 的检查。另外,如果明天在 NetworkCapabilities 中引入另一种新的传输模式怎么办......所以使用整数进行分支会有所帮助,您也可以使用 switch case。
  • 厌倦了这种不断的弃用周期
【解决方案3】:

至于 2018 年 10 月,已弃用接受的答案。

getType() 和类型本身现在在 API 级别 28 中已弃用。来自 Javadoc:

调用者应该切换到检查 NetworkCapabilities#hasTransport 而不是使用 NetworkCapabilities#TRANSPORT* 常量之一

为了使用NetworkCapabilities,您需要将Network 实例传递给getNetworkCapabilities() 方法。要获取该实例,您需要调用 API 级别 23 中添加的getActiveNetwork()

所以我认为目前安全检查您是否连接到 Wi-Fi 或蜂窝网络的正确方法是:

public static boolean isNetworkConnected() {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
            final NetworkInfo ni = cm.getActiveNetworkInfo();

            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI || ni.getType() == ConnectivityManager.TYPE_MOBILE));
            }
        } else {
            final Network n = cm.getActiveNetwork();

            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } 
    }

    return false; 
}

您还可以查看其他类型的TRANSPORT,您可以找到here

重要提示:如果您连接到 Wi-Fi连接到 VPN,那么您当前的状态可能是 TRANSPORT_VPN,因此您可能还需要检查为了它。

不要忘记将以下权限添加到您的 AndroidManifest 文件中:

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

【讨论】:

  • hasTransport(NetworkCapabilities.TRANSPORT_WIFI) 是否等同于 ni.isConnected() && (ni.getType() == ConnnectivityManager.TYPE_WIFI) ?我的意思是 hasTransport() 函数还检查设备是否已连接或正在尝试连接?
  • 又一次,NetworkInfo 被贬值了,你不能再使用NetWorkInfo,那么这如何提供替代方案?
  • @PrescottChartier 此代码 sn-p 仅访问 SDK
【解决方案4】:

更新答案 (19:07:2018):

此方法将帮助您检查互联网连接是否可用。

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        return (activeNetwork != null && activeNetwork.isConnectedOrConnecting());
    } else {
        return false;
    }
}

旧答案:

为了获得最佳代码重用实践,即兴芝士面包答案。

public static boolean isNetworkAvailable(Context context) {
    int[] networkTypes = {ConnectivityManager.TYPE_MOBILE,
            ConnectivityManager.TYPE_WIFI};
    try {
        ConnectivityManager connectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        for (int networkType : networkTypes) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null &&
                    activeNetworkInfo.getType() == networkType)
                return true;
        }
    } catch (Exception e) {
        return false;
    }
    return false;
}

代码可以放在 Util 类中,可用于检查手机是否通过 Wifi 或移动互联网从应用程序的任何部分连接到互联网。

【讨论】:

  • 我建议将活动网络的获取移到 for 循环之外。
  • activeNetwork.isConnectedOrConnecting() 现已弃用
  • 我将 activeNetwork.isConnectedOrConnecting() 更改为 activeNetwork.isConnected
  • NetworkInfo 现已弃用。需要再次更新!
【解决方案5】:

截至 2020 年 3 月,此答案有更新,支持 API.15 到 API.29,您可以在原始答案之后找到它

回答 2019 年 2 月

检查您是否在线:

boolean isOnline() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
    }
    return activeNetwork != null;
}

科特林:

fun isOnline(): Boolean {
    val connectivityMgr = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
        return connectivityMgr.activeNetworkInfo != null

    } else {

        for (network in connectivityMgr.allNetworks) { // added in API 21 (Lollipop)
            val networkCapabilities: NetworkCapabilities? =
                connectivityMgr.getNetworkCapabilities(network)
            return (networkCapabilities!!.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                    networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) &&
                    (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)))
        }
    }
    return false
}

获取android M之前/之后的互联网连接类型

void internetType() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities nc = connectivityMgr.getNetworkCapabilities(connectivityMgr.getActiveNetwork());
            if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
            } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
            }
        } else {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                // connected to wifi
            } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                // connected to mobile data
            }
        }
    }
}

所有情况都需要访问网络状态的权限

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

2020 年 12 月更新

由于NetworkInfo 已被弃用,并且从现在开始API 29,我们必须使用ConnectivityManager.NetworkCallback 及其网络状态更改onAvailable()onLost() 回调。

用法:

  • 可以使用this library,也可以直接使用下面的 实用程序类,它是该库的一部分。

特点

  • 通过在 onDestroy() 方法中进行一些清理来避免内存泄漏,实现 LifecycleObserver 是生命周期意识。
  • 它支持从 API 15(冰淇淋三明治)到 API 29 (Android Q)
  • 对于 API 21 之前的 API,它使用基于上下文的 BoradcastReceiverNetworkInfo,对于 API 21 及更高版本使用 ConnectivityManager.NetworkCallback
  • 当 WiFi 和蜂窝网络都打开时,连接侦听器不会在 WiFi 断开连接时中断,同时过渡到蜂窝网络。
  • 当蜂窝网络开启时,连接监听器不会在 WiFi 已连接且处于活动网络(因为这是首选网络)时中断。
  • 如果您要使用该库,则无需包含此权限android.permission.ACCESS_NETWORK_STATE;但如果要使用实用程序类,则必须包含它。

能力

  • 获取当前连接状态(在线/离线)。
  • 持续检查/收听互联网连接和 设备离线或在线时触发回调。
  • 获取活动互联网连接的类型(WiFi 或蜂窝网络)。
  • 获取所有可用网络的类型(WiFi 或蜂窝网络)。 >> 只有 API 21+ 支持
  • 获取所有可用网络的数量 >> 仅支持 API 21+
@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public class ConnectionUtil implements LifecycleObserver {

    private static final String TAG = "LOG_TAG";
    private ConnectivityManager mConnectivityMgr;
    private Context mContext;
    private NetworkStateReceiver mNetworkStateReceiver;
    
    /*
     * boolean indicates if my device is connected to the internet or not
     * */
    private boolean mIsConnected = false;
    private ConnectionMonitor mConnectionMonitor;


    /**
     * Indicates there is no available network.
     */
    private static final int NO_NETWORK_AVAILABLE = -1;


    /**
     * Indicates this network uses a Cellular transport.
     */
    public static final int TRANSPORT_CELLULAR = 0;


    /**
     * Indicates this network uses a Wi-Fi transport.
     */
    public static final int TRANSPORT_WIFI = 1;


    public interface ConnectionStateListener {
        void onAvailable(boolean isAvailable);
    }


    public ConnectionUtil(Context context) {
        mContext = context;
        mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        ((AppCompatActivity) mContext).getLifecycle().addObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mConnectionMonitor = new ConnectionMonitor();
            NetworkRequest networkRequest = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    .build();
            mConnectivityMgr.registerNetworkCallback(networkRequest, mConnectionMonitor);
        }

    }


    /**
     * Returns true if connected to the internet, and false otherwise
     *
     * <p>
     * NetworkInfo is deprecated in API 29
     * https://developer.android.com/reference/android/net/NetworkInfo
     * <p>
     * getActiveNetworkInfo() is deprecated in API 29
     * https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetworkInfo()
     * <p>
     * getNetworkInfo(int) is deprecated as of API 23
     * https://developer.android.com/reference/android/net/ConnectivityManager#getNetworkInfo(int)
     */
    public boolean isOnline() {

        mIsConnected = false;

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // Checking internet connectivity
            NetworkInfo activeNetwork = null;
            if (mConnectivityMgr != null) {
                activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
            }
            mIsConnected = activeNetwork != null;

        } else {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)

            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                            networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED))
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                                || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                                || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
                            mIsConnected = true;
                }
            }

        }

        return mIsConnected;

    }


    /**
     * Returns
     * <p> <p>
     * <p><p> NO_NETWORK_AVAILABLE >>> when you're offline
     * <p><p> TRANSPORT_CELLULAR >> When Cellular is the active network
     * <p><p> TRANSPORT_WIFI >> When Wi-Fi is the Active network
     * <p>
     */
    public int getActiveNetwork() {

        NetworkInfo activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
        if (activeNetwork != null)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                NetworkCapabilities capabilities = mConnectivityMgr.getNetworkCapabilities(mConnectivityMgr.getActiveNetwork());
                if (capabilities != null)
                    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                        // connected to mobile data
                        return TRANSPORT_CELLULAR;

                    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                        // connected to wifi
                        return TRANSPORT_WIFI;
                    }

            } else {
                if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // Deprecated in API 28
                    // connected to mobile data
                    return TRANSPORT_CELLULAR;

                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // Deprecated in API 28
                    // connected to wifi
                    return TRANSPORT_WIFI;
                }
            }
        return NO_NETWORK_AVAILABLE;
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public int getAvailableNetworksCount() {

        int count = 0;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null)
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        count++;
            }

        }

        return count;
    }
    

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public List<Integer> getAvailableNetworks() {

        List<Integer> activeNetworks = new ArrayList<>();

        Network[] allNetworks; // added in API 21 (Lollipop)
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            allNetworks = mConnectivityMgr.getAllNetworks();
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                        activeNetworks.add(TRANSPORT_WIFI);

                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        activeNetworks.add(TRANSPORT_CELLULAR);

                }
            }
        }

        return activeNetworks;
    }


    public void onInternetStateListener(ConnectionStateListener listener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mNetworkStateReceiver = new NetworkStateReceiver(listener);
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            mContext.registerReceiver(mNetworkStateReceiver, intentFilter);

        } else {
            mConnectionMonitor.setOnConnectionStateListener(listener);
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        ((AppCompatActivity) mContext).getLifecycle().removeObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mConnectionMonitor != null)
                mConnectivityMgr.unregisterNetworkCallback(mConnectionMonitor);
        } else {
            if (mNetworkStateReceiver != null)
                mContext.unregisterReceiver(mNetworkStateReceiver);
        }

    }


    public class NetworkStateReceiver extends BroadcastReceiver {

        ConnectionStateListener mListener;

        public NetworkStateReceiver(ConnectionStateListener listener) {
            mListener = listener;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getExtras() != null) {

                NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo(); // deprecated in API 29

                /*
                 * activeNetworkInfo.getState() deprecated in API 28
                 * NetworkInfo.State.CONNECTED deprecated in API 29
                 * */
                if (!mIsConnected && activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
                    Log.d(TAG, "onReceive: " + "Connected To: " + activeNetworkInfo.getTypeName());
                    mIsConnected = true;
                    mListener.onAvailable(true);

                } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                    if (!isOnline()) {
                        mListener.onAvailable(false);
                        mIsConnected = false;
                    }

                }

            }
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public class ConnectionMonitor extends ConnectivityManager.NetworkCallback {

        private ConnectionStateListener mConnectionStateListener;

        void setOnConnectionStateListener(ConnectionStateListener connectionStateListener) {
            mConnectionStateListener = connectionStateListener;
        }

        @Override
        public void onAvailable(@NonNull Network network) {

            if (mIsConnected)
                return;

            Log.d(TAG, "onAvailable: ");

            if (mConnectionStateListener != null) {
                mConnectionStateListener.onAvailable(true);
                mIsConnected = true;
            }

        }

        @Override
        public void onLost(@NonNull Network network) {

            if (getAvailableNetworksCount() == 0) {
                if (mConnectionStateListener != null)
                    mConnectionStateListener.onAvailable(false);
                mIsConnected = false;
            }

        }

    }

}

Kotlin 版本


class ConnectionUtil(var mContext: Context) : LifecycleObserver {

    private val TAG = "LOG_TAG"

    companion object NetworkType {

        /**
         * Indicates this network uses a Cellular transport.
         */
        const val TRANSPORT_CELLULAR = 0

        /**
         * Indicates this network uses a Wi-Fi transport.
         */
       const val TRANSPORT_WIFI = 1

    }

    private var mConnectivityMgr: ConnectivityManager? = null

    //    private var mContext: Context? = null
    private var mNetworkStateReceiver: NetworkStateReceiver? = null

    /*
     * boolean indicates if my device is connected to the internet or not
     * */
    private var mIsConnected = false
    private var mConnectionMonitor: ConnectionMonitor? = null


    /**
     * Indicates there is no available network.
     */
    private val NO_NETWORK_AVAILABLE = -1


    interface ConnectionStateListener {
        fun onAvailable(isAvailable: Boolean)
    }

    init {
        mConnectivityMgr =
            mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        (mContext as AppCompatActivity?)!!.lifecycle.addObserver(this)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mConnectionMonitor = ConnectionMonitor()
            val networkRequest = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .build()
            mConnectivityMgr!!.registerNetworkCallback(networkRequest, mConnectionMonitor!!)
        }
    }


    /**
     * Returns true if connected to the internet, and false otherwise
     *
     * NetworkInfo is deprecated in API 29
     * https://developer.android.com/reference/android/net/NetworkInfo
     *
     * getActiveNetworkInfo() is deprecated in API 29
     * https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetworkInfo()
     *
     * getNetworkInfo(int) is deprecated as of API 23
     * https://developer.android.com/reference/android/net/ConnectivityManager#getNetworkInfo(int)
     */
    fun isOnline(): Boolean {
        mIsConnected = false
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // Checking internet connectivity
            var activeNetwork: NetworkInfo? = null
            if (mConnectivityMgr != null) {
                activeNetwork = mConnectivityMgr!!.activeNetworkInfo // Deprecated in API 29
            }
            mIsConnected = activeNetwork != null
        } else {
            val allNetworks = mConnectivityMgr!!.allNetworks // added in API 21 (Lollipop)
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                        networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
                    ) 
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
                        ) mIsConnected = true
                }
            }
        }
        return mIsConnected
    }


    /**
     * Returns:
     *
     * NO_NETWORK_AVAILABLE >>> when you're offline
     * TRANSPORT_CELLULAR >> When Cellular is the active network
     * TRANSPORT_WIFI >> When Wi-Fi is the Active network
     */
    fun getActiveNetwork(): Int {
        val activeNetwork = mConnectivityMgr!!.activeNetworkInfo // Deprecated in API 29
        if (activeNetwork != null) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val capabilities = mConnectivityMgr!!.getNetworkCapabilities(
                mConnectivityMgr!!.activeNetwork
            )
            if (capabilities != null) if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
                return TRANSPORT_CELLULAR
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
                return TRANSPORT_WIFI
            }
        } else {
            if (activeNetwork.type == ConnectivityManager.TYPE_MOBILE) { // Deprecated in API 28
                // connected to mobile data
                return TRANSPORT_CELLULAR
            } else if (activeNetwork.type == ConnectivityManager.TYPE_WIFI) { // Deprecated in API 28
                // connected to wifi
                return TRANSPORT_WIFI
            }
        }
        return NO_NETWORK_AVAILABLE
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    fun getAvailableNetworksCount(): Int {
        var count = 0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val allNetworks = mConnectivityMgr!!.allNetworks // added in API 21 (Lollipop)
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) if (networkCapabilities.hasTransport(
                        NetworkCapabilities.TRANSPORT_WIFI
                    )
                    || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                ) count++
            }
        }
        return count
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    fun getAvailableNetworks(): List<Int> {
        val activeNetworks: MutableList<Int> = ArrayList()
        val allNetworks: Array<Network> // added in API 21 (Lollipop)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            allNetworks = mConnectivityMgr!!.allNetworks
            for (network in allNetworks) {
                val networkCapabilities = mConnectivityMgr!!.getNetworkCapabilities(network)
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) activeNetworks.add(
                        TRANSPORT_WIFI
                    )
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) activeNetworks.add(
                        TRANSPORT_CELLULAR
                    )
                }
            }
        }
        return activeNetworks
    }


    fun onInternetStateListener(listener: ConnectionStateListener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mNetworkStateReceiver = NetworkStateReceiver(listener)
            val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
            mContext.registerReceiver(mNetworkStateReceiver, intentFilter)
        } else {
            mConnectionMonitor!!.setOnConnectionStateListener(listener)
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        Log.d(TAG, "onDestroy")
        (mContext as AppCompatActivity?)!!.lifecycle.removeObserver(this)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mConnectionMonitor != null) mConnectivityMgr!!.unregisterNetworkCallback(
                mConnectionMonitor!!
            )
        } else {
            if (mNetworkStateReceiver != null) mContext.unregisterReceiver(mNetworkStateReceiver)
        }
    }


    inner class NetworkStateReceiver(var mListener: ConnectionStateListener) :
        BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.extras != null) {
                val activeNetworkInfo: NetworkInfo? =
                    mConnectivityMgr?.getActiveNetworkInfo() // deprecated in API 29

                /*
                 * activeNetworkInfo.getState() deprecated in API 28
                 * NetworkInfo.State.CONNECTED deprecated in API 29
                 * */if (!mIsConnected && activeNetworkInfo != null && activeNetworkInfo.state == NetworkInfo.State.CONNECTED) {
                    mIsConnected = true
                    mListener.onAvailable(true)
                } else if (intent.getBooleanExtra(
                        ConnectivityManager.EXTRA_NO_CONNECTIVITY,
                        java.lang.Boolean.FALSE
                    )
                ) {
                    if (!isOnline()) {
                        mListener.onAvailable(false)
                        mIsConnected = false
                    }
                }
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    inner class ConnectionMonitor : NetworkCallback() {
        private var mConnectionStateListener: ConnectionStateListener? = null
        fun setOnConnectionStateListener(connectionStateListener: ConnectionStateListener?) {
            mConnectionStateListener = connectionStateListener
        }

        override fun onAvailable(network: Network) {
            if (mIsConnected) return
            Log.d(TAG, "onAvailable: ")
            if (mConnectionStateListener != null) {
                mConnectionStateListener!!.onAvailable(true)
                mIsConnected = true
            }
        }

        override fun onLost(network: Network) {
            if (getAvailableNetworksCount() == 0) {
                mConnectionStateListener?.onAvailable(false)
                mIsConnected = false
            }
        }
    }

}

【讨论】:

  • @Rasel 请检查更新后的答案,希望对您有所帮助
  • 如果用户同时连接到 Wifi 和移动数据,并且其中一个失去连接,onLost 将被调用。 onLost 并不意味着设备失去了互联网连接,而是网络失去了连接。
  • @Gokhan Arik.. 很好,我正在努力解决它
  • @GokhanArik 感谢您的帮助.. 我刚刚更新了我的答案并扩展了 API 的使用,如果您发现任何错误,请告诉我
【解决方案6】:

已接受的答案在版本 28 中已弃用,因此这是我在项目中使用的解决方案。

返回连接类型。 false:没有互联网连接;真实:手机 数据 ||无线网络

public static boolean isNetworkConnected(Context context) { 
    boolean result = false; 
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = true;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = true;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = true;
                }
            }
        }
    }
    return result;
}

【讨论】:

  • activeNetwork.getType() 也被弃用了。您可以使用 activeNetwork.isConnected();
【解决方案7】:

这可以帮助某人 科特林

fun isNetworkConnected(context: Context) : Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val capabilities =  connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        capabilities.also {
            if (it != null){
                if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                    return true
                else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)){
                    return true
                }
            }
        }
        return false
    }

【讨论】:

  • 完善此代码并返回互联网的真实值应该获得wifi或数据包。谢谢!!
  • 从 api 23+ 可用
【解决方案8】:

许多答案仍然使用低于 23 的 getNetworkType 已弃用;使用下面的代码检查设备是否有互联网连接。

public static boolean isNetworkConnected(Context context) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
        } else {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnected();
        }
    }

    return false;
}

..

而且,不要忘记在 Manifest 中添加这一行

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

【讨论】:

    【解决方案9】:

    最好检查一下你的网络是否连接到互联网:

    @Suppress("DEPRECATION")
    fun isNetworkAvailable(context: Context): Boolean {
        try {
            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            return if (Build.VERSION.SDK_INT > 22) {
                val an = cm.activeNetwork ?: return false
                val capabilities = cm.getNetworkCapabilities(an) ?: return false
                capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            } else {
                val a = cm.activeNetworkInfo ?: return false
                a.isConnected && (a.type == ConnectivityManager.TYPE_WIFI || a.type == ConnectivityManager.TYPE_MOBILE)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }
    

    【讨论】:

    【解决方案10】:

    Kotlin 版本:

    fun isInternetOn(context: Context): Boolean {
       val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
       val activeNetwork = cm?.activeNetworkInfo
       return activeNetwork != null && activeNetwork.isConnected
    }
    

    【讨论】:

      【解决方案11】:

      作为Cheese Bread suggested,使用 getActiveNetworkInfo()

      getActiveNetworkInfo

      在 API 级别 1 中添加

      NetworkInfo getActiveNetworkInfo()

      返回有关当前活动的默认数据网络的详细信息。连接后,此网络是传出连接的默认路由。在启动网络流量之前,您应该始终检查 isConnected()。当没有默认网络时,这可能会返回 null。 此方法要求调用者持有权限 ACCESS_NETWORK_STATE。 退货 网络信息 当前默认网络的 NetworkInfo 对象;如果当前没有默认网络处于活动状态,则为 null。

      参考:Android Studio

       public final boolean isInternetOn() {
      
          // get Connectivity Manager object to check connection
          ConnectivityManager connec =
                  (ConnectivityManager)getSystemService(getBaseContext().CONNECTIVITY_SERVICE);
      
          // Check for network connections
          if ( connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTED ||
                  connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTING ) {
      
              // if connected with internet
      
              Toast.makeText(this, connec.getActiveNetworkInfo().getTypeName(), Toast.LENGTH_LONG).show();
              return true;
      
          } else if (
                  connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED ||
                          connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED  ) {
      
              Toast.makeText(this, " Not Connected ", Toast.LENGTH_LONG).show();
              return false;
          }
          return false;
      }
      

      现在调用方法,为了安全使用try catch

      try {
          if (isInternetOn()) { /* connected actions */ }
          else { /* not connected actions */ }
      } catch (Exception e){
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
      }
      

      别忘了补充:

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

      【讨论】:

      • 谢谢它很有用。当我们检查网络状态以及 wifi 和数据是否都关闭时 - 那时应用程序崩溃但尝试 catch 解决问题..
      • 但是,如果我想检查是否存在特定类型的网络,这不起作用枚举所有存在的网络,即getNetworkInfo(ConnectivityManager.TYPE_ETHERNET).isAvailable
      • getState() 已弃用!
      • 几个不推荐使用的指令!
      【解决方案12】:

      connectivityManager.getActiveNetwork() 在以下 android M (API 28) 中找不到。 networkInfo.getState() 在 android L 之上已弃用。

      所以,最终答案是:

      public static boolean isConnectingToInternet(Context mContext) {
          if (mContext == null) return false;
      
          ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
          if (connectivityManager != null) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                  final Network network = connectivityManager.getActiveNetwork();
                  if (network != null) {
                      final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);
      
                      return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                              nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
                  }
              } else {
                  NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
                  for (NetworkInfo tempNetworkInfo : networkInfos) {
                      if (tempNetworkInfo.isConnected()) {
                          return true;
                      }
                  }
              }
          }
          return false;
      }
      

      【讨论】:

      • 你说 getActiveNetwork() 在低于 M 的 Android 中找不到,但你的代码在 Lollipop 上使用它!?
      【解决方案13】:

      检查互联网是否可用:

      @RequiresPermission(allOf = [
          Manifest.permission.ACCESS_NETWORK_STATE, 
          Manifest.permission.INTERNET
      ])
      fun isInternetAvailable(context: Context): Boolean {
          val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
          val activeNetworkInfo = connectivityManager!!.activeNetworkInfo
          return activeNetworkInfo != null && activeNetworkInfo.isConnected
      }
      

      【讨论】:

        【解决方案14】:

        为了安全起见,我建议也使用方法

        NetworkInfo.isConnected()

        整个方法如下:

        /**
         * Checking whether network is connected
         * @param context Context to get {@link ConnectivityManager}
         * @return true if Network is connected, else false
         */
        public static boolean isConnected(Context context){
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null && activeNetwork.isConnected()) {
                int networkType = activeNetwork.getType();
                return networkType == ConnectivityManager.TYPE_WIFI || networkType == ConnectivityManager.TYPE_MOBILE;
            } else {
                return false;
            }
        }
        

        【讨论】:

        • activeNetwork.getType() 已弃用,ConnectivityManager.TYPE_WIFI 已弃用
        【解决方案15】:

        以下是我在最新的 Android 版本上检查当前网络是否使用蜂窝网络的方法:

        val isCellular: Boolean get() {
            val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
            } else {
                cm.activeNetworkInfo?.type == ConnectivityManager.TYPE_MOBILE
            }
        }
        

        【讨论】:

          【解决方案16】:

          (几乎)所有答案在 Android P 中都已弃用,所以这里是 C# 解决方案(Java 开发人员很容易理解

          public bool IsOnline(Context context)
          {
              var cm = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);
          
              if (cm == null) return false;
          
              if (Build.VERSION.SdkInt < BuildVersionCodes.M)
              {
                  var ni = cm.ActiveNetworkInfo;
          
                  if (ni == null) return false;
          
                  return ni.IsConnected && (ni.Type == ConnectivityType.Wifi || ni.Type == ConnectivityType.Mobile);
              }
          
              return cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Wifi)
                  || cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Cellular);
          }   
          

          这里的关键是Android.Net.TransportType

          【讨论】:

          • Aaaannnndddd 此处所有内容均已弃用!
          • @PrescottChartier 在哪个版本中?
          【解决方案17】:

          我们可能需要多次检查互联网连接。所以如果我们将代码块写在Context的扩展方法中,对我们来说会更容易。下面是我的 ContextFragment 的辅助扩展。

          检查互联网连接

          fun Context.hasInternet(): Boolean {
              val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
              return if (Build.VERSION.SDK_INT < 23) {
                  val activeNetworkInfo = connectivityManager.activeNetworkInfo
                  activeNetworkInfo != null && activeNetworkInfo.isConnected
              } else {
                  val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
                  if (nc == null) {
                      false
                  } else {
                      nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                              nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                  }
              }
          }
          

          其他扩展

          fun Context.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) {
              if (hasInternet()) {
                  trueFunc(true)
              } else if (notifyNoInternet) {
                  Toast.makeText(this, "No Internet Connection!", Toast.LENGTH_SHORT).show()
              }
          }
          
          fun Context.hasInternet(
              trueFunc: (internet: Boolean) -> Unit,
              falseFunc: (internet: Boolean) -> Unit
          ) {
              if (hasInternet()) {
                  trueFunc(true)
              } else {
                  falseFunc(true)
              }
          }
          
          fun Fragment.hasInternet(): Boolean = context!!.hasInternet()
          
          fun Fragment.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) =
              context!!.hasInternet(notifyNoInternet, trueFunc)
          
          fun Fragment.hasInternet(
              trueFunc: (internet: Boolean) -> Unit, falseFunc: (internet: Boolean) -> Unit
          ) = context!!.hasInternet(trueFunc, falseFunc)
          

          【讨论】:

            【解决方案18】:

            以下代码适用于所有 API。(Kotlin)

            但是,getActiveNetworkInfo() 仅在 API 29 中被弃用,并且适用于所有 API,因此我们可以在所有低于 29 的 API 中使用它

            fun isInternetAvailable(context: Context): Boolean {
                        var result = false
                        val connectivityManager =
                            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            val networkCapabilities = connectivityManager.activeNetwork ?: return false
                            val actNw =
                                connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
                            result = when {
                                actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                                actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                                actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                                else -> false
                            }
                        } else {
                            connectivityManager.run {
                                connectivityManager.activeNetworkInfo?.run {
                                    result = when (type) {
                                        ConnectivityManager.TYPE_WIFI -> true
                                        ConnectivityManager.TYPE_MOBILE -> true
                                        ConnectivityManager.TYPE_ETHERNET -> true
                                        else -> false
                                    }
            
                                }
                            }
                        }
            
                        return result
                    }
            

            【讨论】:

              【解决方案19】:

              这也适用于 Android 10。如果连接到互联网,它将返回 true,否则返回 false。

              private fun isOnline(): Boolean {
                      val connectivityManager =
                              getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                      val capabilities =
                              connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
                      if (capabilities != null) {
                          when {
                              capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                                  Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                                  return true
                              }
                              capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                                  Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                                  return true
                              }
                              capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                                  Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                                  return true
                              }
                          }
                      }
                      return false
                  }
              

              【讨论】:

              • 从 api 23+ 可用
              【解决方案20】:

              由于发布的答案只允许您查询活动网络,以下是获取任何网络的NetworkInfo 的方法,而不仅仅是活动网络(例如 Wifi 网络)(抱歉,Kotlin 代码提前)

              (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
                  allNetworks.find { getNetworkInfo(it).type == ConnectivityManager.TYPE_WIFI }?.let { network -> getNetworkInfo(network) }
              //    getNetworkInfo(ConnectivityManager.TYPE_WIFI).isAvailable // This is the deprecated API pre-21
              }
              

              这需要 API 21 或更高版本以及android.permission.ACCESS_NETWORK_STATE 权限

              【讨论】:

              • currentNetwork.getType() 和 ConnectivityManager.TYPE_WIFI 在 API 28 中均已弃用。
              • @Abushawish API 28 的推荐解决方案是什么?
              • 现在替换为cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
              【解决方案21】:

              NetManager,可用于通过 Kotlin

              检查 Android 上的互联网连接

              如果您使用 minSdkVersion >= 23

              class NetManager @Inject constructor(var applicationContext: Context) {
                  val isConnectedToInternet: Boolean?
                      get() = with(
                          applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                                  as ConnectivityManager
                      ) {
                          isConnectedToInternet()
                      }
              }
              
              fun ConnectivityManager.isConnectedToInternet() = isConnected(getNetworkCapabilities(activeNetwork))
              
              fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
                  return when (networkCapabilities) {
                      null -> false
                      else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
                  }
              }
              

              如果您使用 minSdkVersion

              class NetManager @Inject constructor(var applicationContext: Context) {
                  val isConnectedToInternet: Boolean?
                      get() = with(
                          applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                                  as ConnectivityManager
                      ) {
                          isConnectedToInternet()
                      }
              }
              
              fun ConnectivityManager.isConnectedToInternet(): Boolean = if (Build.VERSION.SDK_INT < 23) {
                  isConnected(activeNetworkInfo)
              } else {
                  isConnected(getNetworkCapabilities(activeNetwork))
              }
              
              
              fun isConnected(network: NetworkInfo?): Boolean {
                  return when (network) {
                      null -> false
                      else -> with(network) { isConnected && (type == TYPE_WIFI || type == TYPE_MOBILE) }
                  }
              }
              
              fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
                  return when (networkCapabilities) {
                      null -> false
                      else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
                  }
              }
              

              【讨论】:

                【解决方案22】:

                https://www.agnosticdev.com/content/how-detect-network-connectivity-android

                请遵循本教程,它应该可以帮助任何寻找答案的人。

                注意 networkInfo 已被弃用,因此将其替换为 isNetworkRacheable() 下面有@vidha 的答案 将 getApplicationContext() 作为参数传递

                  public static boolean isNetworkReacheable(Context context) {
                    boolean result = false;
                    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        if (cm != null) {
                            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
                            if (capabilities != null) {
                                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                                    result = true;
                                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                                    result = true;
                                }
                            }
                        }
                    } else {
                        if (cm != null) {
                            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                            if (activeNetwork != null) {
                                // connected to the internet
                                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                                    result = true;
                                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                                    result = true;
                                }
                            }
                        }
                    }
                    return result;
                }
                

                【讨论】:

                  【解决方案23】:

                  类似这样的:

                  public boolean hasConnection(final Context context){
                      ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
                      NetworkInfo activeNW = cm.getActiveNetworkInfo();
                      if (activeNW != null && activeNW.isConnected())
                      {
                          return true;
                      }
                      return false;
                  }
                  

                  在主程序体中:

                  if(hasConnection(this)) {
                      Toast.makeText(this, "Active networks OK ", Toast.LENGTH_LONG).show();
                      getAccountData(token, tel);
                  }
                  else  Toast.makeText(this, "No active networks... ", Toast.LENGTH_LONG).show();
                  

                  【讨论】:

                    【解决方案24】:
                    public boolean isConnectedToWifi(Context context) {
                        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                        if (connectivityManager == null) {
                            return false;
                        }
                    
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                            Network network = connectivityManager.getActiveNetwork();
                            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
                            if (capabilities == null) {
                                return false;
                            }
                            return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
                        } else {
                            NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                            if (networkInfo == null) {
                                return false;
                            }
                            return networkInfo.isConnected();
                        }
                    }
                    

                    【讨论】:

                      【解决方案25】:

                      这在 Kotlin 中适用于我。网络管理器类中不推荐使用许多 API,因此以下答案涵盖了所有 API 支持。

                      fun isNetworkAvailable(context: Context): Boolean {
                          var result = false
                          (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
                                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                      result = isCapableNetwork(this,this.activeNetwork)
                                  } else {
                                      val networkInfos = this.allNetworks
                                      for (tempNetworkInfo in networkInfos) {
                                          if(isCapableNetwork(this,tempNetworkInfo))
                                              result =  true
                                      }
                                  }
                              }
                      
                          return result
                      }
                      
                      fun isCapableNetwork(cm: ConnectivityManager,network: Network?): Boolean{
                           cm.getNetworkCapabilities(network)?.also {
                              if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                                  return true
                              } else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                                  return true
                              }
                          }
                          return false
                      }
                      

                      您还将在下面添加

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

                      【讨论】:

                        【解决方案26】:

                        使用 target sdk 29 检查网络状态:

                         @IntRange(from = 0, to = 3)
                        fun getConnectionType(context: Context): Int {
                            var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi
                            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        
                                val capabilities =
                                    cm.getNetworkCapabilities(cm.activeNetwork)
                                if (capabilities != null) {
                                    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                                        result = 2
                                    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                                        result = 1
                                    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
                                        result = 3
                                    }
                        
                                }
                            } else {
                        
                                val activeNetwork = cm.activeNetworkInfo
                                if (activeNetwork != null) {
                                    // connected to the internet
                                    if (activeNetwork.type === ConnectivityManager.TYPE_WIFI) {
                                        result = 2
                                    } else if (activeNetwork.type === ConnectivityManager.TYPE_MOBILE) {
                                        result = 1
                                    } else if (activeNetwork.type === ConnectivityManager.TYPE_VPN) {
                                        result = 3
                                    }
                                }
                            }
                            return result
                        }
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-04-22
                          • 2012-11-14
                          • 2019-11-08
                          • 2019-11-08
                          相关资源
                          最近更新 更多