适用条件
本文只说明 Clash Meta 手机端在 Android 上从 Wi-Fi 切到蜂窝数据后,怎样核对连接是否仍由系统 VPN 服务接管。适用前提是:设备满足 Clash Meta for Android 仓库给出的运行条件(最低 Android 5.0,文档建议 Android 7.0 及以上,并属于所列 CPU 架构),应用包名为 com.github.metacubex.clash.meta,用户已在系统连接请求对话框中确认信任该 VPN,并且当前变化仅是承载网络从 WLAN 变为移动数据。Clash Meta for Android 是 Clash.Meta 的图形界面,流量入口建立在 Android VpnService 上,不覆盖系统内置 PPTP、L2TP/IPSec 客户端。
切换后应核对的系统层状态
Android 用固定界面提示 VPN 是否活动,这些界面是官方文档给出的判断入口。切到蜂窝后,先看状态栏是否仍有表示活动 VPN 的钥匙图标;再打开快捷设置,确认是否出现活动连接信息面板(点按标签会显示更多信息并提供进入设置的链接)。接着打开「设置 > 网络和互联网 > VPN」,确认此前已接受连接请求的应用仍在列表中,且没有被断开或忘记。文档要求 VPN 应用在服务活动时展示不可清除通知,通知可呈现连接状态或网络统计,点按后回到应用前台;服务停止后应移除该通知。若钥匙图标、快捷设置面板与不可清除通知同时缺失,应判定系统层活动连接不存在,而不能只根据蜂窝信号格下结论。
若开启了 Android 7.0 起提供的 always-on VPN,系统负责在开机后拉起并维持服务生命周期,应用仍负责到网关的隧道。Android 8.0 及以上在 always-on 断开或无法连接时会给出不可清除通知。切换网络后若出现该通知,说明系统认为隧道未维持,需要把“蜂窝链路是否可用”和“VPN 服务是否活动”分成两层看待。
结合服务生命周期的判断依据
每个用户或工作资料同一时刻只能有一个活动 VPN 服务,启动新服务会自动停止旧服务。文档写明:系统调用 onRevoke() 时,替代网络接口已经在转发流量,此时应关闭已用 VpnService.protect() 保护的隧道套接字,以及 establish() 返回的 ParcelFileDescriptor。因此“蜂窝能打开网页”只说明替代接口或运营商网络可用,不能单独证明本地 TUN 仍在接管。
仍应视为经 VPN 连接的依据需同时核对:VpnService.prepare() 在已授权时返回 null(未授权会返回系统授权 Intent;且每次都要调用,因为用户可能已改选其他 VPN 应用);VpnService.Builder 已配置地址、路由并以 establish() 成功建立本地 TUN(未准备或权限被收回时返回 null);通往网关的套接字已 protect(),以免被系统 VPN 吞回形成环路。仓库记载可向 com.github.kr328.clash.ExternalControlActivity 发送 com.github.metacubex.clash.meta.action.START_CLASH、STOP_CLASH 或 TOGGLE_CLASH 来启停服务。检查时应先完成系统界面核对,再决定是否按这些 action 重新拉起,而不能默认切换蜂窝后隧道仍保持。
核对未通过时的下一步
若状态栏无钥匙图标、VPN 列表未处于活动或通知已消失:到系统 VPN 页确认应用未被忘记;核 always-on 以及“阻止不使用 VPN 的连接”是否仍符合预期(开启后者时,未走 VPN 的流量会被拦截,设置应用会警告在 VPN 连通前可能没有互联网)。若 prepare() 再次弹出授权框,需要重新确认信任。若蜂窝数据本身不可用,应先恢复运营商网络,再谈 VPN。若系统提示 always-on 无法连接,按文档应等待其重连,或在设置中关闭该选项后再以应用侧启动服务。不要把“蜂窝网页能打开”当成 Clash Meta 隧道仍有效的充分条件。
资料: https://developer.android.com/develop/connectivity/vpn https://github.com/MetaCubeX/ClashMetaForAndroid