androidkotlininternet-connection

ConnectivityManager missing when a VPN is connected


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
    }


Solution

  • 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);