5

如何在不使用意图连接到 VPNService 的情况下以编程方式检测流量是否通过 VPN。有系统调用吗?

4

5 回答 5

7

这有效:

private boolean checkVPN() {
    ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting();
}
于 2017-05-14T18:39:22.030 回答
2

可以在更高版本的 Android API 21 中检查它,但它似乎不起作用(在 nexus 5 @ 5.0.1、nexus 7 @ 5.0.2 上)。为什么它不起作用?

用于检查的新 API 的片段(如果连接,所有流量都由 vpn 路由):

@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;
}
于 2015-04-02T17:22:55.567 回答
1

Android 操作系统知道 VPN 连接何时处于活动状态(因为它在 VPN 连接期间在状态栏中显示一个图标),但没有公共 API 方法(将出现在 VpnService 上)来检查活动联系。

出现两种解决方案。如果您正在处理您知道网络拓扑的特定情况,请运行“ping”以查看特定 IP 地址是否可用 - 使用System.exec. ping 命令存在于具有库存 ROM 的 Android 设备上,我已将其用作解决方案的一部分,以提供更精细的数据连接状态视图(未分配 IP 地址,已分配 IP 地址但无法访问互联网,可以上网)

更好的解决方案是运行跟踪路由并分析输出。我没有检查过带有库存 ROM 的 Android 设备上是否存在 traceroute,稍后我将使用更完整的信息编辑此答案。

于 2013-05-14T15:41:16.537 回答
1

您可以在 android 中使用以下代码检测 VPN。代码将在新旧版本的 android 中运行。下面的代码在 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
        }


    }


}
于 2019-06-27T10:49:20.820 回答
0

我想对于大多数用例,您想检查积极使用的网络是否正在使用 VPN,而不是是否只有任何可用的网络正在使用 VPN。

connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)

... 正在返回可用 VPN 网络的NetworkInfo。这可能不是活动网络!相反,您可以使用以下代码段来测试活动网络是否正在使用 VPN:

Network activeNetwork = connectivityManager.getActiveNetwork();
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(activeNetwork);
boolean vpnInUse = caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
于 2019-04-10T09:20:33.997 回答