更新记录
1.0.0(2026-03-23) 下载此版本
mech1-vpn-detector
mech1-vpn-detector 是一个用于 uni-app x 项目的 UTS API 插件,用来检测当前设备网络是否处于 VPN 环境。
插件信息卡片
| 项目 | 内容 |
|---|---|
| 插件名称 | mech1-vpn-detector |
| 当前版本 | 1.0.0 |
| 最近更新时间 | 2026-03-23 |
| 插件定位 | uni-app x App 侧 VPN 网络环境检测插件 |
| 插件类型 | UTS API 插件 |
| 核心能力 | 同步检测 VPN、支持 Android/iOS、支持项目级二次封装 |
| 适用场景 | 启动提示、回前台复检、设置页手动检测、网络异常排障引导 |
| 真实检测平台 | Android、iOS |
| 可编译调用平台 | Android、iOS、Web、未单独实现平台兜底 |
| 当前 HBuilderX 要求 | 建议使用 3.1.0+ 以支持 uni_modules;当前项目验证环境为 5.04.2026031906-alpha |
核心能力速览
- 提供同步 API
isVpnEnabled(): boolean - Android 基于
ConnectivityManager/NetworkCapabilities.TRANSPORT_VPN判断 - iOS 基于
CFNetworkCopySystemProxySettings()做启发式判断 - Web 与未实现平台可编译、可调用,但默认返回
false - 易于接入启动检测、前后台切回检测、设置页测试入口等业务场景
安装与接入
这一节按更接近插件市场发布页的方式整理,方便开发者快速完成导入、调用和验证。
1. 安装方式
你可以用以下任一方式接入:
方式 A:直接使用当前项目中的现成插件目录
本项目已经包含插件目录:
uni_modules/mech1-vpn-detector
如果你是在本项目内开发,通常不需要额外安装。
方式 B:复制到其他 uni-app x 项目
将以下目录整体复制到目标项目:
uni_modules/mech1-vpn-detector
复制后建议重新打开 HBuilderX 或重新编译一次工程,让 uni_modules 索引刷新。
2. 导入方式
在 .uvue 或 .uts 中按插件根目录导入,不要直接导入平台实现文件:
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
推荐做法:
- 从插件根目录导入
- 通过业务层工具函数二次封装后再在页面使用
不推荐做法:
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector/utssdk/app-android/index.uts'
3. 最小 HBuilderX 要求
参考 uni_modules 规范与 DCloud 插件市场常见要求,建议如下:
uni_modules机制建议使用HBuilderX 3.1.0+- 本插件用于
uni-app x,建议使用较新的 uni-app x / HBuilderX 版本 - 当前项目实际验证环境:
HBuilderX 5.04.2026031906-alpha
如果你在较旧版本 HBuilderX 中遇到以下问题:
uni_modules无法识别- UTS 插件类型提示异常
- 平台入口文件没有正确索引
优先建议升级 HBuilderX 后再验证。
4. 推荐验证步骤
为了更接近真实发布页里的“快速验证”,建议开发者按下面顺序完成验证。
4.1 基础调用验证
在任意页面或工具文件中加入:
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
const vpnEnabled = isVpnEnabled()
console.log('vpnEnabled =', vpnEnabled)
验证目标:
- 工程能正常编译
- 调用无报错
- 能获得布尔值结果
4.2 Android 真机验证
建议步骤:
- 关闭 VPN,进入页面调用一次,确认返回
false - 打开系统 VPN 或 VPN App,等待连接完成
- 再次调用
isVpnEnabled(),确认返回true - 如项目已接入设置页检测按钮,可直接点“立即检测当前 VPN 状态”验证
4.3 iOS 真机验证
建议步骤:
- 关闭 VPN,调用一次,确认返回
false - 打开 VPN 后重新进入页面、切回前台,或手动点检测按钮
- 观察是否命中启发式检测结果
注意:
- iOS 可能因不同 VPN 产品实现差异而出现漏报或误报
- 建议用多种 VPN 连接模式交叉验证
4.4 Web 验证
Web 端验证重点不是“能否检测出 VPN”,而是:
- 工程是否能正常编译
- 调用是否安全
- 返回值是否稳定为
false
4.5 项目级完整接入验证
如果你采用本项目完整接入方案,建议额外验证:
- 启动时是否按预期弹出提示
- 点击“本次启动不再提示”后,本轮启动是否静默
- 设置页总开关关闭后,是否不再弹窗
- 切到后台再回前台后,是否会根据当前 VPN 状态重新检测
- 设置页“立即检测当前 VPN 状态”是否能即时反馈结果
本插件当前已在本项目中完成以下接入能力:
- App 启动时检测 VPN 环境
- App 从后台切回前台时二次检测 VPN 环境
- 配合浮窗组件提示用户当前网络可能影响服务连接
- 支持“本次启动不再提示”
- 支持设置页总开关
- 支持设置页手动测试当前 VPN 状态
如果你是第一次接触本插件,建议按下面顺序阅读:
- 先看“插件能力概览”
- 再看“快速开始”
- 再看“完整接入方案”
- 最后看“文件结构与每个文件的作用”
1. 插件能力概览
1.1 对外 API
本插件当前只对外暴露 1 个同步方法:
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
const vpnEnabled = isVpnEnabled()
返回值:
true:当前检测到设备处于 VPN 环境false:当前未检测到 VPN 环境,或当前平台不支持检测
1.2 平台行为
| 平台 | 实现方式 | 返回结果说明 |
|---|---|---|
| Android | 通过 ConnectivityManager + NetworkCapabilities.TRANSPORT_VPN 判断当前活动网络 |
准确度较高,适合业务提示与运行时检测 |
| iOS | 通过 CFNetworkCopySystemProxySettings() 读取系统网络作用域接口名,并匹配 utun、tap、tun、ppp、ipsec 等前缀 |
启发式判断,适合风险提示,不建议当作强安全校验 |
| Web | 直接返回 false |
Web 不提供原生 VPN 状态判断能力 |
| 其他未单独实现平台 | 通过根入口兜底返回 false |
避免跨端编译报错 |
1.3 平台兼容性
参考 DCloud 插件市场常见展示方式,这里补充一份更直观的平台兼容性说明,便于开发者像查看 hans-blur-view、lime-transition 一样快速判断可用范围。
1.3.1 插件本体兼容性
| 平台 | 是否支持 | 说明 |
|---|---|---|
| Android | √ | 原生检测,基于当前活动网络能力判断 |
| iOS | √ | 启发式检测,基于系统网络作用域接口名判断 |
| 鸿蒙 | - | 当前未实现专用平台入口,默认走兜底返回 false |
| Web Chrome | √ | 可编译可调用,但检测结果固定为 false |
| Web Safari | √ | 可编译可调用,但检测结果固定为 false |
| 微信小程序 | √ | 可编译可调用,但当前无专用实现,默认返回 false |
| 其他未单独实现平台 | √ | 由 utssdk/index.uts 兜底,统一返回 false |
1.3.2 项目内完整接入链路兼容性
| 能力 | Android | iOS | 鸿蒙 | Web |
|---|---|---|---|---|
isVpnEnabled() 插件调用 |
√ | √ | - | √ |
| 返回真实 VPN 检测结果 | √ | √ | - | - |
| 启动时自动检测 | √ | √ | - | - |
| 前后台切回二次检测 | √ | √ | - | - |
| 毛玻璃风险浮窗 | √ | √ | 取决于项目 UI 方案 | √(模拟毛玻璃) |
| 设置页总开关 | √ | √ | 取决于项目接入 | √ |
| 设置页手动检测按钮 | √ | √ | 取决于项目接入 | √(结果固定未检测到) |
1.3.3 与常见插件市场展示风格的对应关系
- 类似
hans-blur-view:会强调“平台兼容性 + 运行效果差异 + 标准基座/自定义基座限制” - 类似
lime-transition:会强调“哪些平台可编译、哪些平台可运行、哪些平台行为一致或退化” - 对于
mech1-vpn-detector,最重要的不是“能不能编译”,而是“返回值是否真实有效” - 因此阅读兼容性时,要区分“支持编译调用”和“支持真实检测”这两个层次
1.4 适用场景
- 在 App 启动后提醒用户当前网络可能影响访问
- 在 WebView / 内嵌网页 / 接口访问异常时,给出“请关闭 VPN 后重试”的引导
- 在设置页中提供网络环境自检能力
- 在前后台切换时做轻量级网络状态复查
2. 快速开始
2.1 目录位置
插件位于:
uni_modules/mech1-vpn-detector
根据 uni-app x UTS 插件规范,插件的核心目录是 utssdk。官方文档中明确说明:
interface.uts用于“声明插件对外暴露的 API,必需”- 分平台目录如
app-android/index.uts、app-ios/index.uts、web/index.uts用于各平台具体实现 - 当根目录和平台目录同时存在时,优先使用平台目录实现
2.2 最简单调用方式
在任意 .uvue / .uts 文件中直接引入:
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
const vpnEnabled = isVpnEnabled()
if (vpnEnabled) {
uni.showToast({
title: '当前处于 VPN 网络环境',
icon: 'none'
})
}
2.3 推荐调用时机
建议在以下节点调用:
- App 首次进入主页面后
- 用户从后台切回前台时
- 打开依赖网络的关键页面前
- 设置页手动检测按钮点击时
不建议高频轮询调用。
3. 完整接入方案
本项目已经做了一套完整接入,你可以直接复用。
3.1 项目内现有接入链路
A. 插件底层检测
文件:uni_modules/mech1-vpn-detector/utssdk/app-android/index.uts
- Android 直接读取当前活动网络能力
- 如果活动网络包含
TRANSPORT_VPN,返回true
文件:uni_modules/mech1-vpn-detector/utssdk/app-ios/index.uts
- iOS 调用 Swift 混编类
Mech1VpnDetectorNative - Swift 侧使用
CFNetwork公开 API 进行启发式判断
B. 项目级状态管理
文件:utils/vpn-notice.uts
这个文件不是插件本体,但它是项目接入插件时最关键的一层封装,负责:
- 统一读取插件检测结果
- 管理“是否开启 VPN 提示”的持久化配置
- 管理“本次启动不再提示”的会话级状态
- 管理 App 前后台切换时触发的检测事件
C. UI 提示浮窗
文件:components/common/VpnNoticePopup.uvue
负责显示:
- 渐变毛玻璃提示卡片
- 5 秒自动关闭倒计时
- 手动关闭按钮
- “本次启动不再提示”按钮
D. 页面联动入口
文件:pages/tabs/layout.uvue
负责:
- 页面首次进入时准备 VPN 检测结果
- 避开隐私说明、更新提示、公告提示等遮罩冲突
- 在合适时机显示 VPN 浮窗
- App 回到前台时执行二次检测
E. App 前后台事件转发
文件:App.uvue
负责:
- 在
onShow中发出VPN_NOTICE_APP_FOREGROUND_EVENT - 通知布局页进行“回前台后的二次检测”
F. 设置页控制入口
文件:pages/tabs/more/settings/settings.uvue
负责:
- 控制总开关“VPN 环境提示”
- 显示“本次启动状态”
- 提供“恢复本次启动提醒”按钮
- 提供“立即检测当前 VPN 状态”测试入口
4. 插件 API 文档
4.1 isVpnEnabled(): boolean
定义文件:uni_modules/mech1-vpn-detector/utssdk/interface.uts
源码如下:
export type IsVpnEnabled = () => boolean
实现导出名称:
export const isVpnEnabled: IsVpnEnabled = function (): boolean {
...
}
参数
无。
返回值
true:检测到 VPNfalse:未检测到 VPN,或当前平台不支持
特点
- 同步调用
- 零配置
- 适合页面逻辑中直接判断
- 适合再次封装到项目级工具中统一管理
5. 各平台实现说明
5.1 Android 实现说明
文件:uni_modules/mech1-vpn-detector/utssdk/app-android/index.uts
当前实现逻辑:
- 通过
UTSAndroid.getAppContext()获取应用上下文 - 通过
Context.CONNECTIVITY_SERVICE获取ConnectivityManager - 读取当前
activeNetwork - 通过
getNetworkCapabilities(activeNetwork)获取网络能力 - 调用
hasTransport(NetworkCapabilities.TRANSPORT_VPN)判断是否为 VPN 网络
核心代码示例:
const activeNetwork = connectivityManager.getActiveNetwork()
if (activeNetwork == null) {
return false
}
const capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
if (capabilities == null) {
return false
}
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
为什么 Android 端没有用 Kotlin 混编?
因为这部分系统 API 逻辑足够简单,直接纯 UTS 即可完成,维护成本更低,编译链更简单。
5.2 iOS 实现说明
文件:
uni_modules/mech1-vpn-detector/utssdk/app-ios/index.utsuni_modules/mech1-vpn-detector/utssdk/app-ios/Mech1VpnDetectorNative.swift
iOS 没有像 Android 一样通用、稳定、面向普通应用的公开 API 来直接返回“当前是否启用 VPN”。
因此当前实现采用启发式方案:
- 通过
CFNetworkCopySystemProxySettings()获取系统网络代理配置 - 读取
kCFNetworkProxiesScoped对应的网络接口集合 - 检查接口名是否存在典型 VPN 虚拟网卡前缀,如:
utuntaptunpppipsec
核心 Swift 逻辑示例:
guard let scoped = proxySettings[kCFNetworkProxiesScoped as String] as? NSDictionary else {
return false
}
let keys = scoped.allKeys.compactMap { $0 as? String }
for key in keys {
let lowercasedKey = key.lowercased()
for prefix in vpnInterfacePrefixes {
if lowercasedKey.hasPrefix(prefix) {
return true
}
}
}
iOS 方案局限性
这很重要,开发者必须明确:
- 这是启发式判断,不是绝对准确的系统级事实判断
- 适合做 UI 提示、风险提醒、排障辅助
- 不适合做强风控、强安全校验、强业务阻断
- 某些 VPN 可能漏报
- 某些特殊网络环境可能误报
5.3 Web 与其他平台实现说明
文件:
uni_modules/mech1-vpn-detector/utssdk/index.utsuni_modules/mech1-vpn-detector/utssdk/web/index.uts
这两个文件统一返回 false,用于:
- 保证 Web 编译通过
- 保证其他未实现平台不会报错
- 明确插件当前主要服务于 App 端
6. 文件结构与每个文件的作用
插件目录结构如下:
uni_modules/
└─ mech1-vpn-detector/
├─ package.json
├─ readme.md
└─ utssdk/
├─ interface.uts
├─ index.uts
├─ web/
│ └─ index.uts
├─ app-android/
│ └─ index.uts
└─ app-ios/
├─ index.uts
└─ Mech1VpnDetectorNative.swift
下面是每个文件的职责说明。
6.1 package.json
路径:uni_modules/mech1-vpn-detector/package.json
作用:
- 声明插件 ID、名称、版本、描述
- 让 uni_modules 正确识别该插件
- 作为插件发布与依赖识别的基础元数据文件
6.2 readme.md
路径:uni_modules/mech1-vpn-detector/readme.md
作用:
- 说明插件怎么用
- 解释每个平台的实现差异
- 帮助项目开发者快速接入或二次维护
6.3 utssdk/interface.uts
路径:uni_modules/mech1-vpn-detector/utssdk/interface.uts
作用:
- 定义插件对外暴露的类型签名
- 让 HBuilderX 为调用方提供类型提示
- 作为“声明层”,与各平台
index.uts对应
6.4 utssdk/index.uts
路径:uni_modules/mech1-vpn-detector/utssdk/index.uts
作用:
- 作为非 App / 未单独实现平台的兜底入口
- 默认返回
false - 避免平台缺失实现时报错
6.5 utssdk/web/index.uts
路径:uni_modules/mech1-vpn-detector/utssdk/web/index.uts
作用:
- 明确 Web 平台行为
- 统一返回
false - 让 Web 端编译表现更明确、更易理解
6.6 utssdk/app-android/index.uts
路径:uni_modules/mech1-vpn-detector/utssdk/app-android/index.uts
作用:
- Android 平台的核心检测实现
- 直接操作 Android 系统网络能力 API
- 不依赖 Kotlin 混编
6.7 utssdk/app-ios/index.uts
路径:uni_modules/mech1-vpn-detector/utssdk/app-ios/index.uts
作用:
- iOS 平台的 UTS 入口
- 负责桥接到 Swift 混编类
6.8 utssdk/app-ios/Mech1VpnDetectorNative.swift
路径:uni_modules/mech1-vpn-detector/utssdk/app-ios/Mech1VpnDetectorNative.swift
作用:
- iOS 平台原生混编实现
- 使用
Foundation与CFNetwork进行启发式检测 - 暴露
Mech1VpnDetectorNative.isVpnEnabled()给 UTS 调用
7. 在项目中单独使用插件
如果你不需要本项目现有的浮窗、设置页、会话状态管理,只想单独使用插件做一次检测,可以这样写。
7.1 在页面中直接调用
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
export default {
onShow() {
const vpnEnabled = isVpnEnabled()
if (vpnEnabled) {
uni.showToast({
title: '检测到 VPN 网络环境',
icon: 'none'
})
}
}
}
7.2 在工具函数中封装
import { isVpnEnabled } from '@/uni_modules/mech1-vpn-detector'
export function checkVpnAndNotify(): boolean {
const enabled = isVpnEnabled() == true
if (enabled) {
uni.showToast({
title: '当前网络处于 VPN 环境',
icon: 'none'
})
}
return enabled
}
8. 本项目完整使用教程
如果你想按本项目现有方式完整接入,请按下面步骤理解。
第一步:保留插件本体
确保以下文件存在:
uni_modules/mech1-vpn-detector/package.jsonuni_modules/mech1-vpn-detector/utssdk/interface.utsuni_modules/mech1-vpn-detector/utssdk/app-android/index.utsuni_modules/mech1-vpn-detector/utssdk/app-ios/index.utsuni_modules/mech1-vpn-detector/utssdk/app-ios/Mech1VpnDetectorNative.swift
第二步:增加项目级状态封装
项目使用的是 utils/vpn-notice.uts 这一层封装,而不是在页面里到处直接调用插件。
这样做的好处:
- 页面层更干净
- 提示开关可统一管理
- 会话免打扰可统一管理
- 回前台二次检测逻辑只写一次
第三步:增加提示浮窗 UI
在 components/common/VpnNoticePopup.uvue 中维护统一样式与交互。
这样做的好处:
- UI 统一
- 可以单独演进视觉效果
- 页面里只处理显示时机,不关心具体样式细节
第四步:在主布局页做显示调度
本项目在 pages/tabs/layout.uvue 中做调度,原因是这里最适合作为全局主内容层。
当前调度职责包括:
- 首次进入时准备结果
- 避开隐私说明弹窗
- 避开更新弹窗
- 避开公告弹窗
- 在不冲突时显示 VPN 提示
- 在 App 回前台时做再检测
第五步:在 App 生命周期里发出前台事件
本项目在 App.uvue 的 onShow 中发出前台事件,代码思路如下:
uni.$emit(VPN_NOTICE_APP_FOREGROUND_EVENT)
这样布局页无需直接依赖 App 生命周期,也方便后续扩展成更多前台恢复逻辑。
第六步:在设置页提供手动控制入口
本项目在 pages/tabs/more/settings/settings.uvue 中提供了 3 个能力:
- 总开关:是否自动提示 VPN 环境
- 会话恢复:恢复本次启动提醒
- 手动检测:立即检测当前 VPN 状态
9. 示例:本项目中的典型调用方式
9.1 启动时准备 VPN 检测结果
this.pendingVpnPrompt = shouldShowVpnNotice(getVpnEnabledAtLaunch())
作用:
- 只在启动阶段检测一次
- 自动考虑“是否已关闭提示”“本次启动是否已免打扰”
9.2 前台恢复时再次检测
const currentVpnEnabled = detectCurrentVpnEnabled()
if (shouldShowVpnNotice(currentVpnEnabled) == true) {
this.vpnPromptVisible = true
this.startVpnPromptCountdown()
}
作用:
- 用户切到系统设置打开/关闭 VPN 后,再回到 App 能立即反映最新状态
9.3 设置页即时检测
checkCurrentVpnState() {
const vpnEnabled = detectCurrentVpnEnabled()
if (vpnEnabled) {
this.showNotice('检测结果:当前处于 VPN 网络环境', 'error')
return
}
this.showNotice('检测结果:当前未发现 VPN 网络环境', 'success')
}
作用:
- 给开发者、测试人员、运维演示时快速验证插件是否正常工作
10. 常见问题
10.1 为什么 Web 总是返回 false?
因为 Web 环境没有统一、可靠的浏览器级原生 VPN 状态 API。
10.2 为什么 iOS 检测不是 100% 准确?
因为 iOS 不向普通应用公开稳定、统一的“当前系统 VPN 已开启”接口,本插件采用的是公开 API 范围内较常见的启发式实现。
10.3 为什么建议把插件能力再包一层 utils/vpn-notice.uts?
因为原始插件只负责“检测”,而业务真正需要的是:
- 是否显示
- 什么时候显示
- 是否本次启动免打扰
- 是否在前台恢复时再次检测
这些都属于业务层逻辑,不适合直接写进插件本体。
10.4 可以只保留插件,不要浮窗和设置页吗?
可以。插件是独立可用的,浮窗和设置页只是本项目给出的完整接入示例。
11. FAQ 排障清单
这一节用于回答开发者最常遇到的问题,方便排查“为什么检测结果和预期不一致”。
11.1 为什么 iOS 检测不到 VPN?
可能原因:
- 当前 iOS 实现是启发式判断,不是 Apple 官方公开的绝对 VPN 状态接口
- 你当前使用的 VPN 产品没有暴露
utun、tap、tun、ppp、ipsec这类常见接口名前缀 - 设备当前网络状态变化较快,而你的页面没有在合适时机重新触发检测
建议排查:
- 先确认是在真机环境验证,而不是只看静态代码逻辑
- 尝试切换不同 VPN 应用或不同连接模式再测试
- 确认是否在 App 回前台或手动点击“立即检测当前 VPN 状态”后重新获取结果
11.2 为什么 Web 永远是 false?
原因很简单:
- 浏览器环境没有统一、可靠、公开的 VPN 状态 API
- 本插件在 Web 端的设计目标是“保证可编译、可调用、行为明确”,而不是伪造一个不可靠的检测结果
因此:
- Web 端固定返回
false是设计行为,不是 bug - 如果你要在 Web 端给用户做网络风险提示,需要另外设计业务层启发式方案
11.3 为什么只建议做提示,不建议做阻断?
原因如下:
- Android 虽然相对可靠,但本质仍然是网络环境判断,不代表业务请求一定失败
- iOS 是启发式检测,天然存在漏报和误报可能
- Web 和未实现平台没有真实检测能力
所以更合理的使用方式是:
- 用它提醒用户“VPN 可能影响服务连接”
- 引导用户在加载失败时关闭 VPN 重试
- 不要直接因为
isVpnEnabled() == true就拒绝用户进入核心业务流程
11.4 为什么某些平台可以调用,但不代表支持真实检测?
这是因为插件分成两个层次:
- 第一层是“接口可用”:项目能正常 import、编译、运行
- 第二层是“能力真实”:平台确实有有效检测逻辑
例如:
- Web 可以调用,但返回固定
false - 其他未实现平台可以调用,但依赖兜底实现,返回固定
false - Android / iOS 才是当前真正有检测逻辑的平台
11.5 为什么我开着 VPN,但 Android 没提示?
建议检查:
- 当前 VPN 是否真的接管了系统活动网络
- 是否在连接完成前就提前调用了检测方法
- 是否被业务层的“本次启动不再提示”或“总开关关闭”状态拦截了浮窗显示
快速验证方法:
- 打开设置页的“立即检测当前 VPN 状态”按钮直接测试
- 恢复“本次启动提醒”后再切到后台、重新回前台验证二次检测
11.6 为什么我开着 VPN,但浮窗没出现?
这不一定是插件问题,也可能是业务层调度问题。
请检查:
- 是否已关闭设置页中的“VPN 环境提示”总开关
- 是否已经点过“本次启动不再提示”
- 当前是否被隐私说明弹窗、更新弹窗、公告弹窗等遮罩拦住
- 当前页面是否真的走到了
layout.uvue中的显示调度逻辑
11.7 为什么只做一次启动检测还不够?
因为用户可能在以下场景改变 VPN 状态:
- 启动 App 后切到系统设置打开 VPN
- 启动 App 后切到其他 VPN 应用连接/断开 VPN
- 页面停留时间较长,期间网络环境已变化
所以本项目才额外补了“前后台切回时二次检测”与“设置页手动检测入口”。
12. 维护建议
- 如果后续要支持更多平台,优先在
utssdk下增加对应平台目录实现 - 如果 iOS 后续出现更稳定的公开 API,可以只替换
Mech1VpnDetectorNative.swift - 如果要扩展更多网络环境识别能力,例如代理、蜂窝、弱网、内网环境,建议继续沿用“插件负责检测、业务层负责调度”的架构
13. 更新日志
13.1 v1.0.0
当前版本:1.0.0
本版本为首个项目内可用版本,已经包含以下能力:
- 新增
isVpnEnabled()同步检测 API - 新增 Android 原生 VPN 检测实现,基于
ConnectivityManager与NetworkCapabilities.TRANSPORT_VPN - 新增 iOS 启发式 VPN 检测实现,基于
CFNetworkCopySystemProxySettings()与网络接口名前缀匹配 - 新增 Web 与默认平台兜底实现,统一返回
false - 完成项目侧启动检测、前后台切回二次检测、提示浮窗、会话免打扰、设置页总开关、手动检测入口等完整接入
如果后续插件逻辑有变化,建议同时更新:
uni_modules/mech1-vpn-detector/package.jsonuni_modules/mech1-vpn-detector/CHANGELOG.mduni_modules/mech1-vpn-detector/readme.md
14. 已知限制
在正式用于业务前,建议开发者先了解这些限制:
14.1 Android 限制
- 当前实现以“当前活动网络”作为判断基础,如果系统存在复杂多网络并行场景,本插件只关注当前活动网络是否带有 VPN 传输能力
- 插件设计目标是“业务提醒”,不是“强风控阻断”;如果你的业务要求更严格的网络审计,需要结合更多系统信号
14.2 iOS 限制
- iOS 方案为启发式检测,不是 Apple 官方提供的“绝对准确 VPN 状态 API”
- 某些 VPN 软件可能不会暴露常见接口名前缀,导致漏报
- 某些特殊网络代理或企业网络环境,理论上存在误报可能
- 因此 iOS 结果更适合提示用户“当前网络可能影响访问”,不建议直接作为安全判定依据
14.3 Web 限制
- Web 端没有统一可靠的浏览器级 VPN 状态接口
- 因此本插件在 Web 端固定返回
false - 如果你希望在 Web 端做网络风险提示,需要考虑其他业务层启发式手段,而不是依赖本插件
14.4 跨平台限制
- 当前插件 API 只有一个同步布尔返回值,不包含 VPN 类型、连接来源、代理详情等高级信息
- 当前插件不提供事件监听;若 VPN 状态发生变化,需要业务层自己选择合适时机再次调用
- 当前插件不负责 UI,不负责提示文案,不负责会话状态管理,这些能力应由业务层封装
15. 后续规划
以下是推荐的插件演进方向,便于后续维护或二次开发:
15.1 短期规划
- 增加更清晰的错误与状态表达,例如区分“不支持检测”“未检测到 VPN”“检测失败”
- 补充独立的
CHANGELOG.md版本维护规范 - 补充更多开发态示例,例如设置页测试入口、启动检测模板、前后台恢复模板
15.2 中期规划
- 增加更多平台支持,例如小程序侧的兜底策略说明或平台特化实现
- 增加更丰富的网络环境检测能力,例如代理、弱网、网络切换、证书异常前置感知
- 将当前项目中的
utils/vpn-notice.uts抽象成更通用的业务封装模板
15.3 长期规划
- 如果 iOS 后续出现更稳定、更公开的官方 API,可替换当前启发式实现
- 如果业务需要更强的联网诊断能力,可以扩展为“网络环境诊断插件”,将 VPN、代理、DNS、网络可达性统一纳入一套检测体系
16. 相关文件索引
16.1 插件本体
uni_modules/mech1-vpn-detector/package.jsonuni_modules/mech1-vpn-detector/CHANGELOG.mduni_modules/mech1-vpn-detector/readme.mduni_modules/mech1-vpn-detector/utssdk/interface.utsuni_modules/mech1-vpn-detector/utssdk/index.utsuni_modules/mech1-vpn-detector/utssdk/web/index.utsuni_modules/mech1-vpn-detector/utssdk/app-android/index.utsuni_modules/mech1-vpn-detector/utssdk/app-ios/index.utsuni_modules/mech1-vpn-detector/utssdk/app-ios/Mech1VpnDetectorNative.swift
16.2 项目内业务接入示例
utils/vpn-notice.utscomponents/common/VpnNoticePopup.uvuepages/tabs/layout.uvuepages/tabs/more/settings/settings.uvueApp.uvue
平台兼容性
uni-app x(3.7.1)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| √ | √ | √ | √ | - | √ |
mech1-***-detector
mech1-***-detector 是一个用于 uni-app x 项目的 UTS API 插件,用来检测当前设备网络是否处于 *** 环境。
插件信息卡片
| 项目 | 内容 |
|---|---|
| 插件名称 | mech1-***-detector |
| 当前版本 | 1.0.0 |
| 最近更新时间 | 2026-03-23 |
| 插件定位 | uni-app x App 侧 *** 网络环境检测插件 |
| 插件类型 | UTS API 插件 |
| 核心能力 | 同步检测 ***、支持 Android/iOS、支持项目级二次封装 |
| 适用场景 | 启动提示、回前台复检、设置页手动检测、网络异常排障引导 |
| 真实检测平台 | Android、iOS |
| 可编译调用平台 | Android、iOS、Web、未单独实现平台兜底 |
| 当前 HBuilderX 要求 | 建议使用 3.1.0+ 以支持 uni_modules;当前项目验证环境为 5.04.2026031906-alpha |
核心能力速览
- 提供同步 API
is***Enabled(): boolean - Android 基于
ConnectivityManager/NetworkCapabilities.TRANSPORT_***判断 - iOS 基于
CFNetworkCopySystemProxySettings()做启发式判断 - Web 与未实现平台可编译、可调用,但默认返回
false - 易于接入启动检测、前后台切回检测、设置页测试入口等业务场景
安装与接入
这一节按更接近插件市场发布页的方式整理,方便开发者快速完成导入、调用和验证。
1. 安装方式
你可以用以下任一方式接入:
方式 A:直接使用当前项目中的现成插件目录
本项目已经包含插件目录:
uni_modules/mech1-***-detector
如果你是在本项目内开发,通常不需要额外安装。
方式 B:复制到其他 uni-app x 项目
将以下目录整体复制到目标项目:
uni_modules/mech1-***-detector
复制后建议重新打开 HBuilderX 或重新编译一次工程,让 uni_modules 索引刷新。
2. 导入方式
在 .uvue 或 .uts 中按插件根目录导入,不要直接导入平台实现文件:
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
推荐做法:
- 从插件根目录导入
- 通过业务层工具函数二次封装后再在页面使用
不推荐做法:
import { is***Enabled } from '@/uni_modules/mech1-***-detector/utssdk/app-android/index.uts'
3. 最小 HBuilderX 要求
参考 uni_modules 规范与 DCloud 插件市场常见要求,建议如下:
uni_modules机制建议使用HBuilderX 3.1.0+- 本插件用于
uni-app x,建议使用较新的 uni-app x / HBuilderX 版本 - 当前项目实际验证环境:
HBuilderX 5.04.2026031906-alpha
如果你在较旧版本 HBuilderX 中遇到以下问题:
uni_modules无法识别- UTS 插件类型提示异常
- 平台入口文件没有正确索引
优先建议升级 HBuilderX 后再验证。
4. 推荐验证步骤
为了更接近真实发布页里的“快速验证”,建议开发者按下面顺序完成验证。
4.1 基础调用验证
在任意页面或工具文件中加入:
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
const ***Enabled = is***Enabled()
console.log('***Enabled =', ***Enabled)
验证目标:
- 工程能正常编译
- 调用无报错
- 能获得布尔值结果
4.2 Android 真机验证
建议步骤:
- 关闭 ***,进入页面调用一次,确认返回
false - 打开系统 或 App,等待连接完成
- 再次调用
is***Enabled(),确认返回true - 如项目已接入设置页检测按钮,可直接点“立即检测当前 *** 状态”验证
4.3 iOS 真机验证
建议步骤:
- 关闭 ***,调用一次,确认返回
false - 打开 *** 后重新进入页面、切回前台,或手动点检测按钮
- 观察是否命中启发式检测结果
注意:
- iOS 可能因不同 *** 产品实现差异而出现漏报或误报
- 建议用多种 *** 连接模式交叉验证
4.4 Web 验证
Web 端验证重点不是“能否检测出 ***”,而是:
- 工程是否能正常编译
- 调用是否安全
- 返回值是否稳定为
false
4.5 项目级完整接入验证
如果你采用本项目完整接入方案,建议额外验证:
- 启动时是否按预期弹出提示
- 点击“本次启动不再提示”后,本轮启动是否静默
- 设置页总开关关闭后,是否不再弹窗
- 切到后台再回前台后,是否会根据当前 *** 状态重新检测
- 设置页“立即检测当前 *** 状态”是否能即时反馈结果
本插件当前已在本项目中完成以下接入能力:
- App 启动时检测 *** 环境
- App 从后台切回前台时二次检测 *** 环境
- 配合浮窗组件提示用户当前网络可能影响服务连接
- 支持“本次启动不再提示”
- 支持设置页总开关
- 支持设置页手动测试当前 *** 状态
如果你是第一次接触本插件,建议按下面顺序阅读:
- 先看“插件能力概览”
- 再看“快速开始”
- 再看“完整接入方案”
- 最后看“文件结构与每个文件的作用”
1. 插件能力概览
1.1 对外 API
本插件当前只对外暴露 1 个同步方法:
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
const ***Enabled = is***Enabled()
返回值:
true:当前检测到设备处于 *** 环境false:当前未检测到 *** 环境,或当前平台不支持检测
1.2 平台行为
| 平台 | 实现方式 | 返回结果说明 |
|---|---|---|
| Android | 通过 ConnectivityManager + NetworkCapabilities.TRANSPORT_*** 判断当前活动网络 |
准确度较高,适合业务提示与运行时检测 |
| iOS | 通过 CFNetworkCopySystemProxySettings() 读取系统网络作用域接口名,并匹配 utun、tap、tun、ppp、ipsec 等前缀 |
启发式判断,适合风险提示,不建议当作强安全校验 |
| Web | 直接返回 false |
Web 不提供原生 *** 状态判断能力 |
| 其他未单独实现平台 | 通过根入口兜底返回 false |
避免跨端编译报错 |
1.3 平台兼容性
参考 DCloud 插件市场常见展示方式,这里补充一份更直观的平台兼容性说明,便于开发者像查看 hans-blur-view、lime-transition 一样快速判断可用范围。
1.3.1 插件本体兼容性
| 平台 | 是否支持 | 说明 |
|---|---|---|
| Android | √ | 原生检测,基于当前活动网络能力判断 |
| iOS | √ | 启发式检测,基于系统网络作用域接口名判断 |
| 鸿蒙 | - | 当前未实现专用平台入口,默认走兜底返回 false |
| Web Chrome | √ | 可编译可调用,但检测结果固定为 false |
| Web Safari | √ | 可编译可调用,但检测结果固定为 false |
| 微信小程序 | √ | 可编译可调用,但当前无专用实现,默认返回 false |
| 其他未单独实现平台 | √ | 由 utssdk/index.uts 兜底,统一返回 false |
1.3.2 项目内完整接入链路兼容性
| 能力 | Android | iOS | 鸿蒙 | Web |
|---|---|---|---|---|
is***Enabled() 插件调用 |
√ | √ | - | √ |
| 返回真实 *** 检测结果 | √ | √ | - | - |
| 启动时自动检测 | √ | √ | - | - |
| 前后台切回二次检测 | √ | √ | - | - |
| 毛玻璃风险浮窗 | √ | √ | 取决于项目 UI 方案 | √(模拟毛玻璃) |
| 设置页总开关 | √ | √ | 取决于项目接入 | √ |
| 设置页手动检测按钮 | √ | √ | 取决于项目接入 | √(结果固定未检测到) |
1.3.3 与常见插件市场展示风格的对应关系
- 类似
hans-blur-view:会强调“平台兼容性 + 运行效果差异 + 标准基座/自定义基座限制” - 类似
lime-transition:会强调“哪些平台可编译、哪些平台可运行、哪些平台行为一致或退化” - 对于
mech1-***-detector,最重要的不是“能不能编译”,而是“返回值是否真实有效” - 因此阅读兼容性时,要区分“支持编译调用”和“支持真实检测”这两个层次
1.4 适用场景
- 在 App 启动后提醒用户当前网络可能影响访问
- 在 WebView / 内嵌网页 / 接口访问异常时,给出“请关闭 *** 后重试”的引导
- 在设置页中提供网络环境自检能力
- 在前后台切换时做轻量级网络状态复查
2. 快速开始
2.1 目录位置
插件位于:
uni_modules/mech1-***-detector
根据 uni-app x UTS 插件规范,插件的核心目录是 utssdk。官方文档中明确说明:
interface.uts用于“声明插件对外暴露的 API,必需”- 分平台目录如
app-android/index.uts、app-ios/index.uts、web/index.uts用于各平台具体实现 - 当根目录和平台目录同时存在时,优先使用平台目录实现
2.2 最简单调用方式
在任意 .uvue / .uts 文件中直接引入:
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
const ***Enabled = is***Enabled()
if (***Enabled) {
uni.showToast({
title: '当前处于 *** 网络环境',
icon: 'none'
})
}
2.3 推荐调用时机
建议在以下节点调用:
- App 首次进入主页面后
- 用户从后台切回前台时
- 打开依赖网络的关键页面前
- 设置页手动检测按钮点击时
不建议高频轮询调用。
3. 完整接入方案
本项目已经做了一套完整接入,你可以直接复用。
3.1 项目内现有接入链路
A. 插件底层检测
文件:uni_modules/mech1-***-detector/utssdk/app-android/index.uts
- Android 直接读取当前活动网络能力
- 如果活动网络包含
TRANSPORT_***,返回true
文件:uni_modules/mech1-***-detector/utssdk/app-ios/index.uts
- iOS 调用 Swift 混编类
Mech1***DetectorNative - Swift 侧使用
CFNetwork公开 API 进行启发式判断
B. 项目级状态管理
文件:utils/***-notice.uts
这个文件不是插件本体,但它是项目接入插件时最关键的一层封装,负责:
- 统一读取插件检测结果
- 管理“是否开启 *** 提示”的持久化配置
- 管理“本次启动不再提示”的会话级状态
- 管理 App 前后台切换时触发的检测事件
C. UI 提示浮窗
文件:components/common/***NoticePopup.uvue
负责显示:
- 渐变毛玻璃提示卡片
- 5 秒自动关闭倒计时
- 手动关闭按钮
- “本次启动不再提示”按钮
D. 页面联动入口
文件:pages/tabs/layout.uvue
负责:
- 页面首次进入时准备 *** 检测结果
- 避开隐私说明、更新提示、公告提示等遮罩冲突
- 在合适时机显示 *** 浮窗
- App 回到前台时执行二次检测
E. App 前后台事件转发
文件:App.uvue
负责:
- 在
onShow中发出***_NOTICE_APP_FOREGROUND_EVENT - 通知布局页进行“回前台后的二次检测”
F. 设置页控制入口
文件:pages/tabs/more/settings/settings.uvue
负责:
- 控制总开关“*** 环境提示”
- 显示“本次启动状态”
- 提供“恢复本次启动提醒”按钮
- 提供“立即检测当前 *** 状态”测试入口
4. 插件 API 文档
4.1 is***Enabled(): boolean
定义文件:uni_modules/mech1-***-detector/utssdk/interface.uts
源码如下:
export type Is***Enabled = () => boolean
实现导出名称:
export const is***Enabled: Is***Enabled = function (): boolean {
...
}
参数
无。
返回值
true:检测到 ***false:未检测到 ***,或当前平台不支持
特点
- 同步调用
- 零配置
- 适合页面逻辑中直接判断
- 适合再次封装到项目级工具中统一管理
5. 各平台实现说明
5.1 Android 实现说明
文件:uni_modules/mech1-***-detector/utssdk/app-android/index.uts
当前实现逻辑:
- 通过
UTSAndroid.getAppContext()获取应用上下文 - 通过
Context.CONNECTIVITY_SERVICE获取ConnectivityManager - 读取当前
activeNetwork - 通过
getNetworkCapabilities(activeNetwork)获取网络能力 - 调用
hasTransport(NetworkCapabilities.TRANSPORT_***)判断是否为 *** 网络
核心代码示例:
const activeNetwork = connectivityManager.getActiveNetwork()
if (activeNetwork == null) {
return false
}
const capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
if (capabilities == null) {
return false
}
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_***) == true
为什么 Android 端没有用 Kotlin 混编?
因为这部分系统 API 逻辑足够简单,直接纯 UTS 即可完成,维护成本更低,编译链更简单。
5.2 iOS 实现说明
文件:
uni_modules/mech1-***-detector/utssdk/app-ios/index.utsuni_modules/mech1-***-detector/utssdk/app-ios/Mech1***DetectorNative.swift
iOS 没有像 Android 一样通用、稳定、面向普通应用的公开 API 来直接返回“当前是否启用 ***”。
因此当前实现采用启发式方案:
- 通过
CFNetworkCopySystemProxySettings()获取系统网络代理配置 - 读取
kCFNetworkProxiesScoped对应的网络接口集合 - 检查接口名是否存在典型 *** 虚拟网卡前缀,如:
utuntaptunpppipsec
核心 Swift 逻辑示例:
guard let scoped = proxySettings[kCFNetworkProxiesScoped as String] as? NSDictionary else {
return false
}
let keys = scoped.allKeys.compactMap { $0 as? String }
for key in keys {
let lowercasedKey = key.lowercased()
for prefix in ***InterfacePrefixes {
if lowercasedKey.hasPrefix(prefix) {
return true
}
}
}
iOS 方案局限性
这很重要,开发者必须明确:
- 这是启发式判断,不是绝对准确的系统级事实判断
- 适合做 UI 提示、风险提醒、排障辅助
- 不适合做强风控、强安全校验、强业务阻断
- 某些 *** 可能漏报
- 某些特殊网络环境可能误报
5.3 Web 与其他平台实现说明
文件:
uni_modules/mech1-***-detector/utssdk/index.utsuni_modules/mech1-***-detector/utssdk/web/index.uts
这两个文件统一返回 false,用于:
- 保证 Web 编译通过
- 保证其他未实现平台不会报错
- 明确插件当前主要服务于 App 端
6. 文件结构与每个文件的作用
插件目录结构如下:
uni_modules/
└─ mech1-***-detector/
├─ package.json
├─ readme.md
└─ utssdk/
├─ interface.uts
├─ index.uts
├─ web/
│ └─ index.uts
├─ app-android/
│ └─ index.uts
└─ app-ios/
├─ index.uts
└─ Mech1***DetectorNative.swift
下面是每个文件的职责说明。
6.1 package.json
路径:uni_modules/mech1-***-detector/package.json
作用:
- 声明插件 ID、名称、版本、描述
- 让 uni_modules 正确识别该插件
- 作为插件发布与依赖识别的基础元数据文件
6.2 readme.md
路径:uni_modules/mech1-***-detector/readme.md
作用:
- 说明插件怎么用
- 解释每个平台的实现差异
- 帮助项目开发者快速接入或二次维护
6.3 utssdk/interface.uts
路径:uni_modules/mech1-***-detector/utssdk/interface.uts
作用:
- 定义插件对外暴露的类型签名
- 让 HBuilderX 为调用方提供类型提示
- 作为“声明层”,与各平台
index.uts对应
6.4 utssdk/index.uts
路径:uni_modules/mech1-***-detector/utssdk/index.uts
作用:
- 作为非 App / 未单独实现平台的兜底入口
- 默认返回
false - 避免平台缺失实现时报错
6.5 utssdk/web/index.uts
路径:uni_modules/mech1-***-detector/utssdk/web/index.uts
作用:
- 明确 Web 平台行为
- 统一返回
false - 让 Web 端编译表现更明确、更易理解
6.6 utssdk/app-android/index.uts
路径:uni_modules/mech1-***-detector/utssdk/app-android/index.uts
作用:
- Android 平台的核心检测实现
- 直接操作 Android 系统网络能力 API
- 不依赖 Kotlin 混编
6.7 utssdk/app-ios/index.uts
路径:uni_modules/mech1-***-detector/utssdk/app-ios/index.uts
作用:
- iOS 平台的 UTS 入口
- 负责桥接到 Swift 混编类
6.8 utssdk/app-ios/Mech1***DetectorNative.swift
路径:uni_modules/mech1-***-detector/utssdk/app-ios/Mech1***DetectorNative.swift
作用:
- iOS 平台原生混编实现
- 使用
Foundation与CFNetwork进行启发式检测 - 暴露
Mech1***DetectorNative.is***Enabled()给 UTS 调用
7. 在项目中单独使用插件
如果你不需要本项目现有的浮窗、设置页、会话状态管理,只想单独使用插件做一次检测,可以这样写。
7.1 在页面中直接调用
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
export default {
onShow() {
const ***Enabled = is***Enabled()
if (***Enabled) {
uni.showToast({
title: '检测到 *** 网络环境',
icon: 'none'
})
}
}
}
7.2 在工具函数中封装
import { is***Enabled } from '@/uni_modules/mech1-***-detector'
export function check***AndNotify(): boolean {
const enabled = is***Enabled() == true
if (enabled) {
uni.showToast({
title: '当前网络处于 *** 环境',
icon: 'none'
})
}
return enabled
}
8. 本项目完整使用教程
如果你想按本项目现有方式完整接入,请按下面步骤理解。
第一步:保留插件本体
确保以下文件存在:
uni_modules/mech1-***-detector/package.jsonuni_modules/mech1-***-detector/utssdk/interface.utsuni_modules/mech1-***-detector/utssdk/app-android/index.utsuni_modules/mech1-***-detector/utssdk/app-ios/index.utsuni_modules/mech1-***-detector/utssdk/app-ios/Mech1***DetectorNative.swift
第二步:增加项目级状态封装
项目使用的是 utils/***-notice.uts 这一层封装,而不是在页面里到处直接调用插件。
这样做的好处:
- 页面层更干净
- 提示开关可统一管理
- 会话免打扰可统一管理
- 回前台二次检测逻辑只写一次
第三步:增加提示浮窗 UI
在 components/common/***NoticePopup.uvue 中维护统一样式与交互。
这样做的好处:
- UI 统一
- 可以单独演进视觉效果
- 页面里只处理显示时机,不关心具体样式细节
第四步:在主布局页做显示调度
本项目在 pages/tabs/layout.uvue 中做调度,原因是这里最适合作为全局主内容层。
当前调度职责包括:
- 首次进入时准备结果
- 避开隐私说明弹窗
- 避开更新弹窗
- 避开公告弹窗
- 在不冲突时显示 *** 提示
- 在 App 回前台时做再检测
第五步:在 App 生命周期里发出前台事件
本项目在 App.uvue 的 onShow 中发出前台事件,代码思路如下:
uni.$emit(***_NOTICE_APP_FOREGROUND_EVENT)
这样布局页无需直接依赖 App 生命周期,也方便后续扩展成更多前台恢复逻辑。
第六步:在设置页提供手动控制入口
本项目在 pages/tabs/more/settings/settings.uvue 中提供了 3 个能力:
- 总开关:是否自动提示 *** 环境
- 会话恢复:恢复本次启动提醒
- 手动检测:立即检测当前 *** 状态
9. 示例:本项目中的典型调用方式
9.1 启动时准备 *** 检测结果
this.pending***Prompt = shouldShow***Notice(get***EnabledAtLaunch())
作用:
- 只在启动阶段检测一次
- 自动考虑“是否已关闭提示”“本次启动是否已免打扰”
9.2 前台恢复时再次检测
const current***Enabled = detectCurrent***Enabled()
if (shouldShow***Notice(current***Enabled) == true) {
this.***PromptVisible = true
this.start***PromptCountdown()
}
作用:
- 用户切到系统设置打开/关闭 *** 后,再回到 App 能立即反映最新状态
9.3 设置页即时检测
checkCurrent***State() {
const ***Enabled = detectCurrent***Enabled()
if (***Enabled) {
this.showNotice('检测结果:当前处于 *** 网络环境', 'error')
return
}
this.showNotice('检测结果:当前未发现 *** 网络环境', 'success')
}
作用:
- 给开发者、测试人员、运维演示时快速验证插件是否正常工作
10. 常见问题
10.1 为什么 Web 总是返回 false?
因为 Web 环境没有统一、可靠的浏览器级原生 *** 状态 API。
10.2 为什么 iOS 检测不是 100% 准确?
因为 iOS 不向普通应用公开稳定、统一的“当前系统 *** 已开启”接口,本插件采用的是公开 API 范围内较常见的启发式实现。
10.3 为什么建议把插件能力再包一层 utils/***-notice.uts?
因为原始插件只负责“检测”,而业务真正需要的是:
- 是否显示
- 什么时候显示
- 是否本次启动免打扰
- 是否在前台恢复时再次检测
这些都属于业务层逻辑,不适合直接写进插件本体。
10.4 可以只保留插件,不要浮窗和设置页吗?
可以。插件是独立可用的,浮窗和设置页只是本项目给出的完整接入示例。
11. FAQ 排障清单
这一节用于回答开发者最常遇到的问题,方便排查“为什么检测结果和预期不一致”。
11.1 为什么 iOS 检测不到 ***?
可能原因:
- 当前 iOS 实现是启发式判断,不是 Apple 官方公开的绝对 *** 状态接口
- 你当前使用的 *** 产品没有暴露
utun、tap、tun、ppp、ipsec这类常见接口名前缀 - 设备当前网络状态变化较快,而你的页面没有在合适时机重新触发检测
建议排查:
- 先确认是在真机环境验证,而不是只看静态代码逻辑
- 尝试切换不同 *** 应用或不同连接模式再测试
- 确认是否在 App 回前台或手动点击“立即检测当前 *** 状态”后重新获取结果
11.2 为什么 Web 永远是 false?
原因很简单:
- 浏览器环境没有统一、可靠、公开的 *** 状态 API
- 本插件在 Web 端的设计目标是“保证可编译、可调用、行为明确”,而不是伪造一个不可靠的检测结果
因此:
- Web 端固定返回
false是设计行为,不是 bug - 如果你要在 Web 端给用户做网络风险提示,需要另外设计业务层启发式方案
11.3 为什么只建议做提示,不建议做阻断?
原因如下:
- Android 虽然相对可靠,但本质仍然是网络环境判断,不代表业务请求一定失败
- iOS 是启发式检测,天然存在漏报和误报可能
- Web 和未实现平台没有真实检测能力
所以更合理的使用方式是:
- 用它提醒用户“*** 可能影响服务连接”
- 引导用户在加载失败时关闭 *** 重试
- 不要直接因为
is***Enabled() == true就拒绝用户进入核心业务流程
11.4 为什么某些平台可以调用,但不代表支持真实检测?
这是因为插件分成两个层次:
- 第一层是“接口可用”:项目能正常 import、编译、运行
- 第二层是“能力真实”:平台确实有有效检测逻辑
例如:
- Web 可以调用,但返回固定
false - 其他未实现平台可以调用,但依赖兜底实现,返回固定
false - Android / iOS 才是当前真正有检测逻辑的平台
11.5 为什么我开着 ***,但 Android 没提示?
建议检查:
- 当前 *** 是否真的接管了系统活动网络
- 是否在连接完成前就提前调用了检测方法
- 是否被业务层的“本次启动不再提示”或“总开关关闭”状态拦截了浮窗显示
快速验证方法:
- 打开设置页的“立即检测当前 *** 状态”按钮直接测试
- 恢复“本次启动提醒”后再切到后台、重新回前台验证二次检测
11.6 为什么我开着 ***,但浮窗没出现?
这不一定是插件问题,也可能是业务层调度问题。
请检查:
- 是否已关闭设置页中的“*** 环境提示”总开关
- 是否已经点过“本次启动不再提示”
- 当前是否被隐私说明弹窗、更新弹窗、公告弹窗等遮罩拦住
- 当前页面是否真的走到了
layout.uvue中的显示调度逻辑
11.7 为什么只做一次启动检测还不够?
因为用户可能在以下场景改变 *** 状态:
- 启动 App 后切到系统设置打开 ***
- 启动 App 后切到其他 应用连接/断开
- 页面停留时间较长,期间网络环境已变化
所以本项目才额外补了“前后台切回时二次检测”与“设置页手动检测入口”。
12. 维护建议
- 如果后续要支持更多平台,优先在
utssdk下增加对应平台目录实现 - 如果 iOS 后续出现更稳定的公开 API,可以只替换
Mech1***DetectorNative.swift - 如果要扩展更多网络环境识别能力,例如代理、蜂窝、弱网、内网环境,建议继续沿用“插件负责检测、业务层负责调度”的架构
13. 更新日志
13.1 v1.0.0
当前版本:1.0.0
本版本为首个项目内可用版本,已经包含以下能力:
- 新增
is***Enabled()同步检测 API - 新增 Android 原生 检测实现,基于
ConnectivityManager与 `NetworkCapabilities.TRANSPORT_` - 新增 iOS 启发式 *** 检测实现,基于
CFNetworkCopySystemProxySettings()与网络接口名前缀匹配 - 新增 Web 与默认平台兜底实现,统一返回
false - 完成项目侧启动检测、前后台切回二次检测、提示浮窗、会话免打扰、设置页总开关、手动检测入口等完整接入
如果后续插件逻辑有变化,建议同时更新:
uni_modules/mech1-***-detector/package.jsonuni_modules/mech1-***-detector/CHANGELOG.mduni_modules/mech1-***-detector/readme.md
14. 已知限制
在正式用于业务前,建议开发者先了解这些限制:
14.1 Android 限制
- 当前实现以“当前活动网络”作为判断基础,如果系统存在复杂多网络并行场景,本插件只关注当前活动网络是否带有 *** 传输能力
- 插件设计目标是“业务提醒”,不是“强风控阻断”;如果你的业务要求更严格的网络审计,需要结合更多系统信号
14.2 iOS 限制
- iOS 方案为启发式检测,不是 Apple 官方提供的“绝对准确 *** 状态 API”
- 某些 *** 软件可能不会暴露常见接口名前缀,导致漏报
- 某些特殊网络代理或企业网络环境,理论上存在误报可能
- 因此 iOS 结果更适合提示用户“当前网络可能影响访问”,不建议直接作为安全判定依据
14.3 Web 限制
- Web 端没有统一可靠的浏览器级 *** 状态接口
- 因此本插件在 Web 端固定返回
false - 如果你希望在 Web 端做网络风险提示,需要考虑其他业务层启发式手段,而不是依赖本插件
14.4 跨平台限制
- 当前插件 API 只有一个同步布尔返回值,不包含 *** 类型、连接来源、代理详情等高级信息
- 当前插件不提供事件监听;若 *** 状态发生变化,需要业务层自己选择合适时机再次调用
- 当前插件不负责 UI,不负责提示文案,不负责会话状态管理,这些能力应由业务层封装
15. 后续规划
以下是推荐的插件演进方向,便于后续维护或二次开发:
15.1 短期规划
- 增加更清晰的错误与状态表达,例如区分“不支持检测”“未检测到 ***”“检测失败”
- 补充独立的
CHANGELOG.md版本维护规范 - 补充更多开发态示例,例如设置页测试入口、启动检测模板、前后台恢复模板
15.2 中期规划
- 增加更多平台支持,例如小程序侧的兜底策略说明或平台特化实现
- 增加更丰富的网络环境检测能力,例如代理、弱网、网络切换、证书异常前置感知
- 将当前项目中的
utils/***-notice.uts抽象成更通用的业务封装模板
15.3 长期规划
- 如果 iOS 后续出现更稳定、更公开的官方 API,可替换当前启发式实现
- 如果业务需要更强的联网诊断能力,可以扩展为“网络环境诊断插件”,将 ***、代理、DNS、网络可达性统一纳入一套检测体系
16. 相关文件索引
16.1 插件本体
uni_modules/mech1-***-detector/package.jsonuni_modules/mech1-***-detector/CHANGELOG.mduni_modules/mech1-***-detector/readme.mduni_modules/mech1-***-detector/utssdk/interface.utsuni_modules/mech1-***-detector/utssdk/index.utsuni_modules/mech1-***-detector/utssdk/web/index.utsuni_modules/mech1-***-detector/utssdk/app-android/index.utsuni_modules/mech1-***-detector/utssdk/app-ios/index.utsuni_modules/mech1-***-detector/utssdk/app-ios/Mech1***DetectorNative.swift
16.2 项目内业务接入示例
utils/***-notice.utscomponents/common/***NoticePopup.uvuepages/tabs/layout.uvuepages/tabs/more/settings/settings.uvueApp.uvue

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 0
赞赏 0
下载 11538812
赞赏 1882
赞赏
京公网安备:11010802035340号