ConnectivityManager missing when a VPN is connected

Viewed 815

i have a function that returns connectivity state of device and it works fine all the time except when device is connected to the VPN , it gives false Positive when network is not available


    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
    }

3 Answers

If you want to confirm that your network has internet, you can't only test connectivityManager.activeNetwork and actNw.hasTransport.

connectivityManager.activeNetwork will return the VPN as it is the active network whether it has internet or not. actNw.hasTransport just lets you know the transport of the connection. If you don't care about the transport, you can probably remove that code completely.

What you should check for are NET_CAPABILITY_INTERNET and NET_CAPABILITY_VALIDATED.

NET_CAPABILITY_INTERNET

Indicates that this network should be able to reach the internet.

NET_CAPABILITY_VALIDATED

Indicates that connectivity on this network was successfully validated. For example, for a network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully detected.

Therefore what you really need is to check if the active network has both of those capabilities to determine if you are connected to a network with internet connectivity.

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

Did You Try to add this:

actNw.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> true

I also faced the same issue, when VPN is connected and WiFi was OFF, still NET_CAPABILITY_VALIDATED and TRANSPORT_VPN was returning true.

instead of connectivityManager.activeNetwork use connectivityManager.allNetworks

if WiFi toggle is ON and connected to a network connectivityManager.allNetworks will return 2 networks else it will return 1 network as the VPN is the active default network.

Related