检测 Android 上是否配置了永远在线的 VPN

Tim*_*rry 1 vpn android network-programming

我有一个 Android VPN 应用程序。当我触发启动 VPN 的意图(通过VPNService.prepare)时,如果设备上已配置始终在线的 VPN,它会立即失败。这看起来很合理,但我希望能够轻松检测到这种情况,这样我就可以向用户显示有用的消息。

我所说的“始终在线”是指特定的 VPN 始终在线 Android VPN 标志: https: //developer.android.com/guide/topics/connectivity/vpn#always-on

我似乎无法找到一种方法来访问该信息,即使它在 Android 内部使用(例如,这里,但getAlwaysOnVpnPackage似乎没有公开 AFAICT)。

我见过的最好的选择是检查 Android 中的 VPN 连接是否处于活动状态?,它会告诉您当前是否有任何 VPN 连接处于活动状态,但这还不够,因为:

  • 我不想了解临时 VPN 连接:我只对始终在线的VPN 连接感兴趣。
  • 有时“永远在线”的连接实际上并不总是在线。如果您的连接已断开并将其设置为“始终开启”,则它会按此配置,并阻止所有其他 VPN 安装,但不会创建任何网络连接(Android 会显示持续警告,这会将您带到其他应用程序激活连接)。由于没有连接,因此上述技术不起作用。我仍然需要检测这种情况,因为它仍然阻止我的 VPN 设置。

有什么方法可以检查设备当前是否将 VPN 配置为“始终开启”?

小智 5

你可以使用这个方法

private fun isVpnAlwaysOn(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
        val alwaysOn = Settings.Secure.getString(contentResolver, "always_on_vpn_app")
        return !alwaysOn.isNullOrEmpty()
    } else false
}
Run Code Online (Sandbox Code Playgroud)

“alwaysOn”包含配置了always-on的应用程序的包名称。

  • 这将不再适用于 Android 12 及更高版本。如果你使用这个,你将得到`java.lang.SecurityException:设置密钥:<always_on_vpn_app>不可读。从 S+ 开始,用 @hide 注释的设置键仅限于 system_server 和系统应用程序,除非它们用 @Readable 注释。 (4认同)