连接到 VPN 时检查 WiFi 和蜂窝网络连接

Check for WiFi and cellular connection when connected to a VPN

在我的 Android 应用程序中,我使用以下两种方法检查设备是否已连接到 WiFi 以及网络连接是否可用。我假设当设备连接到 WiFi 或移动网络时,互联网也可用。

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;
}

如果设备通过 VPN 连接,方法 return 错误。是否可以扩展这些方法,使它们 return 即使在设备连接到 VPN 时也是如此?

VPN 有特定的传输类型,因此您需要做的就是为 capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) 添加一个检查。

您还可以将 API 级别检查从 Build.VERSION_CODES.Q 更改为 Build.VERSION_CODES.M。唯一有问题的行是 connectivityManager.getActiveNetwork() 但这在 M (API 23) 中可用。