更新记录

1.1.6(2026-09-30)

  • 适配vapor模式。

1.1.5(2026-09-30)

  • 修复已知问题。

1.1.4(2026-09-30)

  • 修复已知问题。
查看更多

平台兼容性

uni-app(4.83)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ × × √ √ √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(4.83)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × √ √ √ ×

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

umi-risk

设备风险检测插件,适用于 uni-app x。在本机判断开发者模式、USB / 无线调试、系统 HTTP 转发、虚拟专网,以及调用方配置的风险应用是否存在。检测结果不上传,也不扫描全部已安装应用。

支持平台:uni-app x 和 uni-app 的 Android、iOS、鸿蒙。不支持 Web、小程序、元服务。

环境 要求
HBuilderX 4.83 及以上
uni-app x 4.83 及以上
Android minSdk 21
iOS 12.0 及以上

引入

插件放在工程的 uni_modules/umi-risk 后即可使用,无需额外配置依赖。

import { checkDeviceRisk } from '@/uni_modules/umi-risk'

快速使用

const report = checkDeviceRisk({
  packages: [
    { packageName: 'com.example.riskapp', name: '自定义规则' }
  ]
})

if (report.risky) {
  console.log(report.developerMode, report.usbDebug, report.httpProxy, report.vpn, report.riskApps)
}

packages 与内置名单合并。不需要追加时传 null,或把 packages 设为 null。

checkDeviceRisk(null)

checkDeviceRisk

function checkDeviceRisk(options: RiskCheckOptions | null): DeviceRiskResult

同步返回。risky 为 developerMode、usbDebug、usbDebugWifi、httpProxy、vpn、riskApps 任一命中。

RiskCheckOptions

字段 类型 说明
packages RiskAppRule[] \| null 追加的风险应用。null 时只用内置名单

RiskAppRule

字段 类型 说明
packageName string Android 包名。iOS、鸿蒙传 URL Scheme,或传已在内置 scheme 表中的包名,见下方「自定义应用」。不要把具体产品名写进商店文案
name string 命中后回传的展示名

DeviceRiskResult

字段 类型 说明
supported boolean 当前三端均为 true
developerMode boolean 开发者选项是否打开。读不到时为 false,语义见平台差异
usbDebug boolean 有线调试或调试器是否处于可检测状态,语义见平台差异
usbDebugWifi boolean 无线调试。Android 11 以下和 iOS 恒为 false。鸿蒙读取 adb_wifi_enabled,读不到时为 false
httpProxy boolean 系统 HTTP 或 HTTPS 转发已配置且端口有效
proxyHost string 转发主机。未命中时为空字符串
proxyPort number 转发端口。未命中时为 0
vpn boolean 系统虚拟专网,或网卡名命中隧道前缀
vpnHints string[] 命中依据。可能是 TRANSPORT_VPN、BEARER_VPN,或 tun0 这类网卡名
riskApps RiskAppHit[] 已安装或可唤起的风险应用
risky boolean 任一项命中

RiskAppHit

字段 类型 说明
packageName string 命中规则上的包名或 scheme
name string 规则上的展示名

单独调用

需要只查一项时,可以直接用下面的函数。返回值与 checkDeviceRisk 对应字段一致。

函数 返回 说明
isDeveloperModeEnabled() boolean 同 developerMode
isUsbDebugEnabled() boolean 同 usbDebug
isUsbDebugWifiEnabled() boolean 同 usbDebugWifi
readHttpProxy() string[] [host, port]。未命中为 ['', '0']
isVpnOnline() string[] 同 vpnHints。空数组表示未检测到虚拟专网
findRiskApps(extra) RiskAppHit[] extra 为追加规则,null 表示只用内置名单

平台差异

Android

  • developerMode:读取 development_settings_enabled,先 Global,再 Secure。值为 1 视为打开。
  • usbDebug:读取 ADB_ENABLED,先 Global,再 Secure。
  • usbDebugWifi:Android 11(API 30)及以上读取 adb_wifi_enabled。
  • HTTP 转发:优先 ConnectivityManager.getDefaultProxy()(API 23+),否则依次读 http.proxyHost / http.proxyPort、https.proxyHost / https.proxyPort。
  • 虚拟专网:当前默认网络的 TRANSPORT_VPN(API 23 及以上),或已启用且名称以 tun、ppp、pptp 开头的网卡。
  • 风险应用:PackageManager.getPackageInfo 能取到即视为已安装。只查内置名单和 packages,不枚举全部应用。

iOS

系统没有 ADB 开关,调试项的含义与 Android 不同。

  • developerMode:iOS 16 及以上读取 AMFI 开发者模式状态。读不到,或系统没有这项开关时为 false。只表示开发者模式是否打开,不表示当前有调试器附加。
  • usbDebug:当前进程是否被调试器附加(P_TRACED)。Xcode 有线或无线调试附加后为 true;只打开开发者模式、未附加调试器时为 false。
  • usbDebugWifi:恒为 false。
  • HTTP 转发:读系统设置里已启用的 HTTP,没有再读 HTTPS。
  • 虚拟专网:系统设置 __SCOPED__ 里名称包含 tap、tun、ppp、pptp、ipsec 的接口。这是网卡特征,不是 NetworkExtension 的官方虚拟专网状态。
  • 风险应用:canOpenURL。packageName 回传规则里的包名或 scheme,不代表能读到真实 Bundle ID。

canOpenURL 只能查询写入 LSApplicationQueriesSchemes 的 scheme。内置 scheme 和运行时追加的 scheme 都要写在宿主 manifest.json 的 app-ios.distribute.urlschemewhitelist,否则稳定返回未安装。Apple 对可查询 scheme 数量有上限(当前为 50)。写法见「权限配置」。

鸿蒙

  • developerMode:先读 settings.general.DEVELOPMENT_SETTINGS_STATUS,值为 1 或 true 视为打开。读不到再读 development_settings_enabled。上下文用全局 getContext(),先 DEVICE_SHARED,再 USER_PROPERTY。读不到、抛错或拿不到上下文时为 false。
  • usbDebug:settings.getValueSync 读 adb_enabled,先 DEVICE_SHARED,再 USER_PROPERTY。值为 1 或 true 视为打开。上下文用全局 getContext()。读不到、抛错或拿不到上下文时为 false。
  • usbDebugWifi:同样方式读 adb_wifi_enabled。
  • HTTP 转发:只用 connection.getDefaultHttpProxy() 的缓存。排除列表为 ['*'] 时视为未启用转发。该 API 异步,模块加载时会先请求一次;缓存尚未返回时,当次调用可能暂时看不到转发。
  • 虚拟专网:BEARER_VPN,或接口名以 tun、utun、ppp、pptp、ipsec 开头。
  • 风险应用:canOpenLink。scheme 必须写在宿主 harmony-configs/entry/src/main/module.json5 的 querySchemes,否则检测无效。

自定义应用

packages 在三端都会并入检测,但识别方式不同。

写法 Android iOS 鸿蒙
com.example.app 按包名查询 仅当该包名已在内置 scheme 表中才查;未知包名跳过 仅当该包名已在内置 scheme 表中才用对应 scheme 做 canOpenLink;未知包名跳过
customscheme(不含 .) 按包名查询,通常查不到 当作 scheme 当作 scheme,做 canOpenLink
myapp:// 整串当作包名 取 :// 前的 myapp 作为 scheme 同上

iOS 追加 scheme、鸿蒙追加 canOpenLink 时,记得同步改宿主的查询名单,见「权限配置」。

内置名单

Android 按包名检测。iOS、鸿蒙按 URL Scheme 检测。名单在 utssdk/common/rules.uts,同一包名或同一 scheme 只记一次。

上架说明、应用商店文案和隐私政策正文用「风险应用」统称,不要粘贴具体产品名、包名或 scheme。宿主查询配置仍须与 rules.uts 一致。

权限配置

读取开发者模式、USB / 无线调试不弹授权框,也不需要额外权限。系统 HTTP 转发和虚拟专网在 Android、鸿蒙需要声明网络状态;按包名或 scheme 查询风险应用需要包可见性或 scheme 白名单。iOS 读转发和虚拟专网不用额外权限。

Android、iOS 写在宿主工程根目录的 manifest.json。鸿蒙的 ohos.permission.GET_NETWORK_INFO 插件已写在 utssdk/app-harmony/module.json5,否则云编译 HAR 会报 10505001。这项权限还要再写进宿主 harmony-configs/entry/src/main/module.json5,安装时才真正授予。querySchemes 只写在宿主,不配置则对应 scheme 检测无效。

Android

写在 manifest.json 的 app-android.distribute.permissions。

权限 作用
android.permission.ACCESS_NETWORK_STATE 读取当前网络是否为虚拟专网,以及系统默认 HTTP 转发
android.permission.QUERY_ALL_PACKAGES Android 11 及以上按包名查询风险应用。没有这项、且包名不在 <queries> 里时,已安装也会被当成未安装

宿主完整示例:

{
  "app-android": {
    "distribute": {
      "permissions": [
        "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
        "<uses-permission android:name=\"android.permission.QUERY_ALL_PACKAGES\"/>"
      ]
    }
  }
}

android:name 里的双引号前面要加反斜杠。改完后需重新云端打包。

上架 Google Play 时,QUERY_ALL_PACKAGES 审核很严。应改成写死要查询的包名,并去掉该权限。manifest.json 里强制移除:

{
  "app-android": {
    "distribute": {
      "permissions": [
        "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>"
      ],
      "excludePermissions": [
        "<uses-permission android:name=\"android.permission.QUERY_ALL_PACKAGES\"/>"
      ]
    }
  }
}

包名可见性写在工程根目录的 AndroidManifest.xml(HBuilderX 里对项目右键「新建」→「自定义文件」)。只保留实际要查的包名,与 rules.uts 对齐。下面是占位示例,不要把真实包名写进商店文案:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  package="替换为云打包使用的 Android 包名">
  <queries>
    <package android:name="com.example.risk.one" />
    <package android:name="com.example.risk.two" />
  </queries>
</manifest>

运行时通过 packages 传入、但没写进 <queries> 的包名,在 Android 11 及以上查不到。

国内应用商店通常把读取已安装应用列表视为个人信息。隐私政策需要写明:仅在本机判断开发者模式、USB 调试、系统 HTTP 转发、虚拟专网,以及调用方配置的风险应用是否安装,不上传应用列表。隐私政策里同样不要写具体产品名。

iOS

没有需要填写用途说明的系统权限。风险应用走 canOpenURL,scheme 必须在应用访问白名单 LSApplicationQueriesSchemes 里。

内置 scheme 和运行时追加的 scheme 都要写在 manifest.json 的 app-ios.distribute.urlschemewhitelist,多个 scheme 用英文逗号分隔,总数不超过 50。漏掉的 scheme,canOpenURL 稳定返回未安装。

{
  "app-ios": {
    "distribute": {
      "urlschemewhitelist": "scheme1,scheme2"
    }
  }
}

追加自定义 scheme 时接到逗号后面,例如再加 myapp:

{
  "app-ios": {
    "distribute": {
      "urlschemewhitelist": "scheme1,scheme2,myapp"
    }
  }
}

改完后需重新云端打包。不在白名单里的 scheme,canOpenURL 稳定返回未安装。

鸿蒙

ohos.permission.GET_NETWORK_INFO 插件 HAR 和宿主 entry 都要声明。querySchemes 只写在宿主 harmony-configs/entry/src/main/module.json5。

配置 作用
ohos.permission.GET_NETWORK_INFO 读取网络承载类型,判断是否为虚拟专网,并读取默认 HTTP 转发。普通权限,安装时授予,不弹窗
querySchemes canOpenLink 允许查询的 scheme。没写在这里的 scheme,链路检测无效。数量上限 50

DEVELOPMENT_SETTINGS_STATUS、adb_enabled 一类调试开关经常因普通应用没有读取权限而读不到,读不到时结果为 false,不能据此判断开发者模式或调试已关闭。系统没有给普通应用开放的对应权限可配。

在现有 entry 的 module 上补这两处。querySchemes 需要覆盖内置名单;通过 packages 追加的 scheme 也要加进来。

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO"
      }
    ],
    "querySchemes": [
      "scheme1",
      "scheme2"
    ]
  }
}

ohos.permission.INTERNET 是应用访问网络用的,插件检测本身不依赖它。已有工程只追加 GET_NETWORK_INFO 和 querySchemes,不要整文件覆盖掉自己的 abilities。

结果怎么用

命中表示环境里存在对应特征,不表示用户正在监听流量或设备已被入侵。企业虚拟专网、系统调试开关、合法的网络转发应用都会让 risky 为 true。业务上建议展示具体命中项,由产品决定是提示、限制还是放行。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android manifest.json:QUERY_ALL_PACKAGES、ACCESS_NETWORK_STATE。iOS manifest.json:urlschemewhitelist(LSApplicationQueriesSchemes)。鸿蒙插件 module.json5 已声明 ohos.permission.GET_NETWORK_INFO,宿主 harmony-configs 的 module.json5 仍须声明同一权限,并配置 querySchemes。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

仅在本机判断开发者模式、USB 调试、系统 HTTP 转发、虚拟专网和调用方配置的风险应用是否安装,不上传应用列表。Android 11+ 配置包名能在运行时生效需要 QUERY_ALL_PACKAGES;上架 Google Play 时应改为 manifest queries 写死包名。国内应用商店把读取已安装应用列表视为个人信息,隐私政策需写明用途,且不要写具体产品名。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。