Ali
Ali

Reputation: 1532

Detect behind VPN in android

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

Upvotes: 8

Views: 16489

Answers (6)

DiLDoST
DiLDoST

Reputation: 372

Nothing worked for me so i created my own. It's workin for me on Android 11 (although deprecated)

static boolean checkVpn(Context context){
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
    for(NetworkInfo o:cm.getAllNetworkInfo()){
        if(o.getTypeName().toLowerCase().contains("vpn")&&o.isConnected()){
            return true;
        }
    }
    return false;
}

Upvotes: 0

Rajesh Dalsaniya
Rajesh Dalsaniya

Reputation: 2127

You can detect VPN with following code in android. Code will work in new and older version of android. Below code is in Kotlin.

    class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if(checkVPNStatus()) {
            Log.d("VPN-RAJ", "is VPN Connected YES")
        } else {
            Log.d("VPN-RAJ", "is VPN Connected NO")
        }
    }


    private fun checkVPNStatus(): Boolean {
        val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork
            val capabilities = connectivityManager.getNetworkCapabilities(network)
            Log.d("VPN-RAJ", "in New Android Version")

            capabilities!= null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)

        } else {
            Log.d("VPN-RAJ", "in Old Android Version")

            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)!!.isConnectedOrConnecting
        }


    }


}

Upvotes: 1

Almer
Almer

Reputation: 1199

I guess for most use-cases you want to check if the actively used network is using VPN instead of if just any network available is using VPN.

connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)

... is returning a NetworkInfo for an available VPN Network. This might not be the active Network! Instead you could use the following snippet to test if the active Network is using VPN:

Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
boolean vpnInUse = caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

Upvotes: 0

TomPax
TomPax

Reputation: 120

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

Upvotes: 2

Christian
Christian

Reputation: 747

This works :

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

Upvotes: 7

Phil Haigh
Phil Haigh

Reputation: 4591

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.

Upvotes: 1

Related Questions