旧 VPN 设置为什么会带到新应用
Android 对第三方 VPN 的约束是全局性的:同一用户或工作资料只能有一个当前已准备的 VPN 应用,也只能有一个活动 VpnService。启动新服务会自动停止旧服务。可是“停止服务”不等于清除系统选项。始终开启、阻止不使用 VPN 的连接、已接受的连接请求,都登记在 Settings > Network & Internet > VPN。旧应用若仍被设为始终开启,系统仍可能在开机或断线后再次拉起它;若拦截仍开而新应用还没 establish() 成功,就会出现更换过程中完全无网。
Clash Meta for Android 作为 Clash.Meta 的图形界面,包名 com.github.metacubex.clash.meta,建议 Android 7.0 及以上。更换到它或从它换走之前,需要先解除旧应用在系统侧的授权与策略,而不是只停掉前台界面。文档还要求始终开启场景下由系统和设置应用控制连接,旧应用的断开按钮在始终开启仍开启时并不能可靠地结束系统策略。
更换前解除影响的顺序
适用条件:准备启用另一个 VPN 应用(或重装 Clash Meta);旧应用曾确认过连接请求对话框;设备版本支持始终开启(7.0+)或你曾打开过拦截。按下面做,每步用系统可见状态确认,而不是假设卸载等于清理。
- 打开 Settings > Network & Internet > VPN,找到旧应用。先关闭始终开启,避免系统在你操作中途再次
onStartCommand()拉起旧服务。 - 关闭“Block connections without VPN”。官方说明打开该项时,设置应用会警告连通前没有互联网。更换过程中新应用尚未成为已准备 VPN 时,拦截会让所有未走隧道的流量失败。
- 在同一页面断开或忘记旧 VPN。忘记用于撤销该应用作为已接受解决方案的记录。系统在断开、忘记或关闭始终开启时停止活动连接,并调用
onRevoke();回调发生时,替代网络接口已经在转发流量,这是旧隧道被真正让出的判断依据。 - 确认状态栏钥匙图标和快捷设置信息面板消失。Android 8.0 及以上,与始终开启相关的不可消除通知也应在关闭该选项后消失。图标还在,说明仍有活动服务,可能来自旧应用被再次拉起,或第三方应用已成为新的活动服务。
- 再安装或首次启动新应用。新应用必须调用
VpnService.prepare():若返回 Intent,需要走系统连接请求对话框;若返回空,表示它已成为当前已准备 VPN。不要在旧应用仍占用已准备状态时跳过这一步。
Clash Meta 仓库提供向 ExternalControlActivity 发送 STOP_CLASH 的方式停止自身服务,这只能处理本应用,不能忘记其他 VPN,也不能关拦截。跨应用更换必须走系统 VPN 页。
解除不彻底时如何判断与补救
若新应用无法弹出连接请求或 establish() 返回空:回到 VPN 列表,看旧应用是否仍在、始终开启是否被重新打开、是否存在工作资料下的另一套 VPN。每个资料可运行不同 VPN 应用,只清理主用户不够。若忘记后列表仍出现该应用,说明连接请求被再次接受,需要重复关闭系统选项。
若已忘记旧应用但开机后旧隧道又出现:检查是否有设备管理或托管配置在远程写入 VPN 策略;文档提到托管配置可用来远程配置连接。若新应用声明不支持始终开启(清单中 android.net.VpnService.SUPPORTS_ALWAYS_ON 为 false),系统会禁用始终开启控件,此时不要期待开机自启,只按手动准备与连接流程使用。
补救顺序保持单向:先保证拦截关闭以恢复基础网络,再确认无活动钥匙图标,最后才让新应用 prepare() 并建立接口。两头同时开始终开启,只会让后启动的服务挤掉先启动的服务,并留下难以解释的断连通知。
参考资料: https://developer.android.com/develop/connectivity/vpn https://github.com/MetaCubeX/ClashMetaForAndroid