Check if a VPN connection is active in Android?
An alternative to check if the active Network is using VPN:
Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
boolean vpnInUse = caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
Using NetworkCapabilities
worked for me. You have to loop over all existing networks and check which has VPN_TRANSPORT
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
Log.i(TAG, "Network count: " + networks.length);
for(int i = 0; i < networks.length; i++) {
NetworkCapabilities caps = cm.getNetworkCapabilities(networks[i]);
Log.i(TAG, "Network " + i + ": " + networks[i].toString());
Log.i(TAG, "VPN transport is: " + caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN));
Log.i(TAG, "NOT_VPN capability is: " + caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN));
}
Late answer, tested on Android 16 <-> 29
:
public boolean vpn() {
String iface = "";
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if (networkInterface.isUp())
iface = networkInterface.getName();
Log.d("DEBUG", "IFACE NAME: " + iface);
if ( iface.contains("tun") || iface.contains("ppp") || iface.contains("pptp")) {
return true;
}
}
} catch (SocketException e1) {
e1.printStackTrace();
}
return false;
}
The above doesn't work with wireguard because the interface name can be anything (normally the connection's name).
This is works for me: Tested from API 16 to 23:
List<String> networkList = new ArrayList<>();
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if (networkInterface.isUp())
networkList.add(networkInterface.getName());
}
} catch (Exception ex) {
Timber.d("isVpnUsing Network List didn't received");
}
return networkList.contains("tun0");
P.S. Also it can be another networkInterface with name "ppp0", but in my tests with different VPN apps it's always was "tun0"