Detect behind VPN in android

2019-02-17 16:43发布

问题:

How to detect programatically if traffic is going through VPN without using intent to connect to VPNService. Is there some system call?

回答1:

This works :

private boolean checkVPN() {
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting();
}


回答2:

The Android OS is aware of when a VPN connection is active (as it shows an icon in the status bar for the duration of a VPN connection) but there is no public API method (which would appear on the VpnService) to check for an active connection.

Two solutions occur. If you are dealing with a specific situation where you know the network topology, run 'ping' to see if a particular IP address is available - use System.exec. the ping command is present on Android devices with stock ROMs, I've used it as part of a solution to to provide a more granular view of the state of a data connection (ip address not allocated, ip address allocated but can't access the internet, can access the internet)

A better solution would be to run a traceroute instead and analyse the output. I've not checked if traceroute is present on Android devices with stock ROMs, I'll edit this answer later with more complete information.



回答3:

It is possible to check it in Android API 21 an higher, but it seems doesn't work (on nexus 5 @ 5.0.1, nexus 7 @ 5.0.2). Why its not working?

Snippet of new API for check it (and all traffic is routed by vpn if connected):

@Inject
boolean checkVPN(ConnectivityManager connMgr) {
    //don't know why always returns null:
    NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_VPN);

    boolean isVpnConn = networkInfo == null ? false : networkInfo.isConnected();
    return isVpnConn;
}