Search code examples
androidvpnandroid-networkingandroid-connectivitymanager

Check for WiFi and cellular connection when connected to a VPN


In my Android application, I'm using the following two methods to check if the device is connected to WiFi and if a network connection is available in general. I assume that when the device is connected to WiFi or to a mobile network, also internet is available.

public static boolean wifiConnected(Context context) {
    boolean isWifiConn = false;
    ConnectivityManager connMgr = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        android.net.Network network = connMgr.getActiveNetwork();
        if (network == null) return false;
        NetworkCapabilities capabilities = connMgr.getNetworkCapabilities(network);
        if(capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)){
            isWifiConn = true;
        }
    } else {
        for (android.net.Network network : connMgr.getAllNetworks()) {
            NetworkInfo networkInfo = connMgr.getNetworkInfo(network);
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) {
                isWifiConn = true;
                break;
            }
        }
    }
    return isWifiConn;
}

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

    if (connectivityManager != null) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    return true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    return true;
                } else return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET);
            }
        } else {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return (activeNetworkInfo != null) && activeNetworkInfo.isConnected();
        }
    }

    return false;
}

If the device is connected by VPN the methods return false. Is it possible to extend the methods so that they return true even when the device is connected to a VPN?


Solution

  • There is a specific transport type for a VPN, so all you need to do is add a check for capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN).

    Also you can change your API level check from Build.VERSION_CODES.Q to Build.VERSION_CODES.M. The only problematic line is connectivityManager.getActiveNetwork() but this is available in M (API 23).