连接 VPN 时缺少 ConnectivityManager

问题描述

我有一个返回设备连接状态的函数,它一直工作正常,除非设备连接到 VPN,当网络不可用时它会给出 false Positive


    fun isConnected(): 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
                actNw.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> true

                else -> false
            }
        } else {
            connectivityManager.run {
                connectivityManager.activeNetworkInfo?.run {
                    result = when (type) {
                        ConnectivityManager.TYPE_WIFI -> true
                        ConnectivityManager.TYPE_MOBILE -> true
                        ConnectivityManager.TYPE_ETHERNET -> true
                        ConnectivityManager.TYPE_VPN -> true
                        else -> false
                    }

                }
            }
        }
        return result
    }

解决方法

您是否尝试添加此内容:

actNw.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> true
,

如果你想确认你的网络有互联网,你不能只测试connectivityManager.activeNetworkactNw.hasTransport

connectivityManager.activeNetwork 将返回 VPN,因为它是活动网络,无论是否有互联网。 actNw.hasTransport 只是让您知道连接的传输。如果您不关心传输,您可能可以完全删除该代码。

您应该检查 NET_CAPABILITY_INTERNETNET_CAPABILITY_VALIDATED

NET_CAPABILITY_INTERNET

表示该网络应该能够访问互联网。

NET_CAPABILITY_VALIDATED

表示此网络连接成功 验证。例如,对于具有 NET_CAPABILITY_INTERNET 的网络,它 表示已成功检测到 Internet 连接。

因此,您真正需要的是检查活动网络是否具有这两种功能,以确定您是否已连接到具有互联网连接的网络。

actNw.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
actNw.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);