更新记录

1.1.1(2026-08-26)

  • 修复 iOS 运行时报 uts插件[privacy-compliance]编译失败,无法使用:utssdk/app-ios/config.json 补充 "deploymentTarget": "12.0" 声明。插件使用的通知 / 运动等授权状态 API 需 iOS 10+/11+,未声明部署目标时被按 iOS 9.0 编译而报可用性错误。升级后无需改动宿主工程。

1.1.0(2026-08-26)

  • HarmonyOS NEXT 支持(App-Harmony):新增 utssdk/app-harmony/index.uts 原生实现,与 Android/iOS 同一套字符串式 API。
    • 隐私同意状态:@ohos.data.preferences 持久化,键名与 Android SharedPreferences 对齐(agreed / rejected / privacyVersion)。
    • 运行时权限:@ohos.abilityAccessCtrl checkAccessTokenSync 查询 + requestPermissionsFromUser 弹窗申请;授权弹窗只出现一次——检测 dialogShownResults 全 false(用户曾拒绝)时自动降级 requestPermissionOnSetting 拉起权限设置面板二次引导,action=request 语义保持成立(deniedAlways 恒为空)。
    • 声明制校验:读取宿主 module.json5 声明列表,未声明的权限在查询 / 申请前直接返回 HOST_PERMISSION_NOT_DECLARED(status=unsupported),对齐 Android 的 MANIFEST_PERMISSION_MISSING 语义。
    • 权限映射:相机/麦克风/定位(精确+模糊组合)/图库读写(READ/WRITE_IMAGEVIDEO 收敛 photo/video/album 与 saveAlbum 等入口)/音频/通讯录/日历/蓝牙(ACCESS_BLUETOOTH)/手机状态;Android 专有类型返回 PLATFORM_ANDROID_ONLY;鸿蒙未开放类型返回 UNSUPPORTED_PERMISSION。
    • 通知开关:NotificationKit isNotificationEnabled 缓存 + requestEnableNotification;持久化「是否已发起过授权」,首次走系统弹窗、拒绝后引导设置页(NOTIFICATION_SETTINGS_REQUIRED);App 回前台经 ApplicationContext.on('applicationStateChange') 自动刷新开关缓存,系统设置修改后返回页面立即反映。
    • 后台定位:不支持弹窗申请,直接打开应用详情页并返回 OPEN_BACKGROUND_LOCATION_SETTINGS。
    • 设置页跳转:显式 Want 拉起系统设置应用详情页(com.huawei.hmos.settings / application_info_entry / pushParams=包名);纯隐式 action.settings.app.info 在部分 NEXT 版本会打开空白页,勿单独依赖。
    • API 层:UTSHarmony.getUIAbilityContext() 替代全局 getContext()(API 18 起废弃);createAtManager() 替代已废弃的 getAtManager()。
  • 矩阵与文档:permission-matrix.json 新增 harmony.types / sentinels / openSettingsNotes;sync-permission-matrix.js 校验 app-harmony UTS type 与矩阵一致性,并生成 HarmonyOS 映射表与能力分类章节。
  • 工程配置:package.json 平台标记 harmony=y(uni-app / uni-app-x),版本升至 1.1.0;uni_modules.config.json 增加 app-harmony;Demo manifest 增加 app-harmony 节点。
  • 模板:新增 templates/harmony-module-json5-permissions.json5(宿主鸿蒙工程 requestPermissions 声明模板 + string.json reason 示例 + ACL 受限权限说明)。
  • 扫描器鸿蒙覆盖(2026-08-25 增强):privacy-scan.js 新增 HarmonyOS module.json5 扫描——解析 harmony-configs 与鸿蒙构建产物的 requestPermissions;内置 ohos.permission.* 规则表(风险分级 + 受限 ACL 识别:READ/WRITE_IMAGEVIDEO、READ_AUDIO、READ_PHONE_STATE、LOCATION_IN_BACKGROUND);校验 user_grant 权限 reason 字段及 $string 资源在 string.json 中存在、usedScene/when 完整性、LOCATION 必须与 APPROXIMATELY_LOCATION 组合声明;SDK 痕迹新增华为 HMS/AGConnect 规则。
  • Demo:最小接入页与全权限测试台适配鸿蒙平台识别(APP-HARMONY 条件编译)、新增鸿蒙权限测试项与媒体权限联动刷新。

发布提示:市场发布时请勾选「加密」,确保 encrypt 版(试用/普通授权版)为加密文件而非明文源码。

1.0.2(2026-08-20)

  • 文档:README 结构性重写——新增目录导航、兼容性快览、code 语义表(返回码→含义→建议动作)、Android/iOS 分端权限速查表、合规接入清单与 FAQ 六问;接入步骤重组为三步(弹窗接入 → 权限申请 → 上架扫描)。
  • 发布配置修复:修复 HBuilderX uni_modules 操作重置 package.json extVersion 导致 CI 版本校验失败的问题(发布前需复查 extVersion 与插件版本一致)。

发布提示:市场发布时请勾选「加密」,确保 encrypt 版(试用/普通授权版)为加密文件而非明文源码。

查看更多

平台兼容性

uni-app(3.8.2)

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

uni-app x(4.0)

Chrome Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 鸿蒙插件版本 微信小程序
× × 5.0 1.0.0 13 1.0.0 12 1.1.0 ×

其他

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

隐私合规接入助手 privacy-compliance

为 uni-app App 提供隐私合规一站式能力:隐私同意管理 · 三端权限申请 · 上架前静态扫描。纯 UTS 原生实现,Android / iOS / HarmonyOS NEXT 同一套 API。

版本 平台 兼容性
1.1.1 App-Android(minSdk 21+)/ App-iOS(13+)/ App-HarmonyOS NEXT HBuilderX ^4.25.0 · uni-app ^3.8.0 · uni-app-x ^4.0

鸿蒙端要求:HBuilderX 4.66+(uni-app 编译鸿蒙正式版)+ DevEco Studio;宿主需在鸿蒙工程 module.json5 声明权限,模板见 templates/harmony-module-json5-permissions.json5。

⚠️ 本插件辅助规范合规流程,不构成法律意见,也不承诺 100% 通过应用市场审核。安装插件不会自动向宿主 manifest 注入权限,请按业务裁剪并披露。

目录

特性

  • 🛡️ 隐私同意管理:同意 / 拒绝 / 撤回 / 重置;privacyVersion 变化自动重新征求同意;拒绝可退出 App
  • 📱 三端权限申请:Android / iOS / HarmonyOS NEXT 统一字符串式 API,覆盖 40+ 权限映射
  • 🎯 语义化结果:code / status / action 三层口径直接驱动 UI,无需二次映射
  • 🔍 部分授权识别:Android 14+ 照片选择器、iOS 18+ 通讯录的 AUTHORIZED_LIMITED 语义与"调整范围"引导
  • 🧩 即插即用组件:privacy-flow 隐私弹窗 + SDK 延迟初始化,5 行代码接入
  • 🔎 上架前扫描:privacy-scan.js 静态扫描 Android Manifest / iOS plist / HarmonyOS module.json5(含受限 ACL 权限、reason 用途描述与 string.json 资源校验)/ 常见 SDK 痕迹

安装与平台支持

插件市场搜索「隐私合规接入助手」导入项目。

平台 UTS 原生 API privacy-flow 弹窗
App-Android ✅ ✅
App-iOS ✅ ✅
App-Harmony(HarmonyOS NEXT) ✅ ✅
uni-app x(App 端) ⚠️ 仅原生 API ❌ 组件不可用(x 只认 .uvue,本插件组件为 .vue,需自行实现弹窗 UI 后裸调 PrivacyNative API)
H5 / 小程序 ❌ 无 JS fallback ⚠️ 仅 UI,无原生同意状态

快速开始

Step 1 · 首屏接入隐私弹窗

在 App 启动后的首个页面(如首页 pages/index/index.vue)挂载 privacy-flow,用户同意后才允许继续:

<template>
  <privacy-flow
    app-name="我的App"
    privacy-version="2026-06-15"          <!-- 隐私政策版本,更新政策时提升 -->
    privacy-url="https://example.com/privacy"
    agreement-url="https://example.com/agreement"
    @agree="initThirdPartySdks"
    @ready="initThirdPartySdks"
  />
</template>

<script>
import PrivacyFlow from '@/uni_modules/privacy-compliance/components/privacy-flow/privacy-flow.vue'
import * as PrivacyNative from '@/uni_modules/privacy-compliance'

export default {
  components: { PrivacyFlow },
  methods: {
    initThirdPartySdks() {
      if (!PrivacyNative.hasAgreed()) return
      // 统计、推送等第三方 SDK 只在用户同意后初始化
    }
  }
}
</script>

⚠️ 协议详情页注册(必做):弹窗里的《隐私政策》《用户协议》链接默认打开插件自带的内嵌页 uni_modules/privacy-compliance/pages/privacy-webview/privacy-webview,该页不会自动注册到宿主 pages.json。 HBuilderX 导入插件后会提示存在 pages_init.json,请在 pages.json 的 pages 数组手动合并以下条目 (或把 uni_modules/privacy-compliance/pages_init.json 里的 "path" 调整为你自己的协议页后合并):

{
  "path": "uni_modules/privacy-compliance/pages/privacy-webview/privacy-webview",
  "style": { "navigationBarTitleText": "协议详情" }
}

若漏合并,点击链接会因路由未注册而跳转失败(合规弹窗核心路径断裂)。也可以不使用内嵌页, 改用自己已注册的 privacy-page / agreement-page 属性指向现有页面,或 privacy-url / agreement-url 指向站外链接。

Step 2 · 按需申请权限

在用户触发具体功能时(如点击"拍照上传")申请对应权限:

import * as PC from '@/uni_modules/privacy-compliance'

const result = await PC.requestPermission('camera')
if (result.success) {
  // 已授权,调用相机
} else if (result.code === 'PERMISSION_DENIED_ALWAYS') {
  // 已永久拒绝,引导去设置:PC.openPermissionSettings('camera')
}

申请前的用途说明弹窗(uni.showModal)由业务在调用前自行展示;完整示例见 examples/index.vue(需注册为启动页)与 Demo 项目。

Step 3 · 上架前扫描

node uni_modules/privacy-compliance/scripts/privacy-scan.js <项目根目录> \
  --json privacy-scan-report.json --md privacy-scan-report.md

API 参考

统一入口:import * as PC from '@/uni_modules/privacy-compliance'

隐私同意

函数 说明
initPrivacy(version, enforceAgreed) 初始化;enforceAgreed=true 时未同意会拦截权限申请(默认 false)
hasAgreed(): boolean 当前是否已同意当前版本
agree(version) 同意并记录版本
rejectPrivacy() 拒绝
withdrawConsent() 撤回同意(权限申请恢复拦截)
resetPrivacyState() 重置全部隐私状态
getPrivacyStateJson() 调试:返回状态 JSON 字符串

权限

函数 说明
hasPermission(type) 同步查询授权状态,返回 PermissionResult
requestPermission(type) 申请权限,返回 Promise<PermissionResult>
isPermissionSupported(type) 当前平台/版本是否支持该 type
openPermissionSettings(type) 打开对应权限设置页
openAppSettings() 打开应用设置页
getAndroidPermissions(type) 平台权限名列表(Android=系统权限名,iOS=UsageDescription 键,HarmonyOS=ohos.permission.*)

返回值 PermissionResult

{
  success: boolean          // 是否已获得所需权限
  code: string              // 见下表
  status: string            // authorized / denied / denied_forever / not_determined / unsupported
  action: string            // request=可弹系统框,settings=只能去设置,none=无需动作
  message?: string
  granted?: string[]        // 已授权权限(Android=权限名,iOS=UsageDescription 键)
  denied?: string[]
  deniedPresent?: string[]  // 被拒但可再次请求
  deniedAlways?: string[]   // 永久拒绝(iOS 拒绝即写入)
}

常见 code 语义:

code 含义 建议动作
AUTHORIZED 已完整授权 直接使用
AUTHORIZED_LIMITED 部分授权(Android 14+ 媒体 / iOS 18+ 通讯录) 按钮显示「调整范围」
PERMISSION_DENIED 被拒绝,可再次申请 按钮「申请权限」
PERMISSION_DENIED_ALWAYS 永久拒绝 按钮「去设置开启」
PRIVACY_NOT_AGREED 未同意隐私协议(enforceAgreed=true 时) 先弹隐私协议
REQUEST_PERMISSION_TIMEOUT 授权请求超时(5-10s 无响应) 提示重试

privacy-flow 组件

Prop 默认值 说明
appName '' 应用名,替换弹窗文案 {appName}
privacyVersion '1.0.0' 隐私政策版本,变化后自动重新弹窗
privacyUrl / agreementUrl '' 协议外链(无 privacyPage 时用内置 webview 打开)
privacyPage / agreementPage '' 项目内协议页路径
enforceAgreed true 组件场景默认拦截未同意的权限申请(与 UTS API 默认 false 不同)
rejectAction 'exit' 拒绝后 exit 退出 App / stay 留在应用
dialog {} 弹窗文案与样式(title/content/confirmText/cancelText/primaryColor…)
autoShow true 挂载时自动弹出隐私协议

事件:@agree / @reject / @ready(已同意,含启动时已同意)/ @withdraw / @reset 方法:ensureAgreed() · withdrawConsent(showDialog) · resetPrivacyState()

权限类型速查

Android

type 权限 说明
camera CAMERA
record / microphone RECORD_AUDIO
location 前台定位(Fine+Coarse)
backgroundLocation 后台定位 Android 10 起需先有前台定位
photo / video / audio / album 13+ READ_MEDIA_* 拆分;14+ 支持部分授权 album 是组合入口,非独立权限
contacts READ_CONTACTS
notification 13+ POST_NOTIFICATIONS
bluetooth 12+ BLUETOOTH_SCAN/CONNECT
manageStorage 所有文件访问(特殊权限跳设置页) 11+ MANAGE_EXTERNAL_STORAGE;9- 映射旧版权限
storage / readStorage / writeStorage 旧版存储兼容入口 可用性受宿主 targetSdk 与设备版本双重限制,Android 13+ 请用媒体入口
overlay / installPackages / exactAlarm Android 专有特殊权限 均跳系统设置页

iOS

type 实现 说明
camera NSCameraUsageDescription
photo / album / video / media NSPhotoLibraryUsageDescription iOS 14+ 可能 AUTHORIZED_LIMITED
saveAlbum / writeStorage / writePhoto NSPhotoLibraryAddUsageDescription
record / microphone NSMicrophoneUsageDescription
location / backgroundLocation WhenInUse / Always+WhenInUse 后台定位两段式弹窗
notification UNUserNotificationCenter 首次查询基于缓存
contacts NSContactsUsageDescription iOS 18+ 支持 AUTHORIZED_LIMITED
calendar NSCalendarsUsageDescription iOS 17+ 支持仅写入授权
bluetooth NSBluetoothAlwaysUsageDescription iOS 13+
activityRecognition NSMotionUsageDescription
callPhone 无运行时权限 NO_RUNTIME_PERMISSION_REQUIRED
manageStorage 等 Android 专有 PLATFORM_ANDROID_ONLY
packages / fullScreenIntent 审核/配置项 SPECIAL_PERMISSION_REVIEW_REQUIRED

HarmonyOS NEXT

type 实现 说明
camera / record / microphone ohos.permission.CAMERA / MICROPHONE
location LOCATION + APPROXIMATELY_LOCATION 鸿蒙强制精确定位与模糊定位组合申请
backgroundLocation LOCATION_IN_BACKGROUND 不支持弹窗申请,直接引导应用详情页手动开启
photo / video / album / media ohos.permission.READ_IMAGEVIDEO 四个入口共享同一权限,授权后联动刷新
audio ohos.permission.READ_AUDIO
saveAlbum / writePhoto / writeStorage ohos.permission.WRITE_IMAGEVIDEO 保存到图库统一走该权限
contacts / calendar READ_CONTACTS / READ+WRITE_CALENDAR
bluetooth ohos.permission.ACCESS_BLUETOOTH API 12+ 三方应用蓝牙权限
phone ohos.permission.READ_PHONE_STATE 受限 ACL 权限,需 AGC 放宽后可用
notification NotificationKit 开关 系统授权弹窗仅首次出现;拒绝后返回 NOTIFICATION_SETTINGS_REQUIRED
callPhone 无运行时权限 拉起拨号盘无需授权,NO_RUNTIME_PERMISSION_REQUIRED
manageStorage 等 Android 专有 PLATFORM_ANDROID_ONLY
storage / sms / callLog / bodySensors / activityRecognition 等 鸿蒙不向三方开放 UNSUPPORTED_PERMISSION

鸿蒙宿主工程需在 harmony-configs/entry/src/main/module.json5 的 module.requestPermissions 中声明权限(含 $string reason 资源),模板见 templates/harmony-module-json5-permissions.json5。READ_IMAGEVIDEO / WRITE_IMAGEVIDEO / READ_AUDIO 属受限 ACL 权限,正式包需在 AppGallery Connect 申请放宽。

完整映射见 templates/platform-capability-matrix.md(与 permission-matrix.json 自动同步)。

平台已知行为

  • Android「去设置」返回后按钮变回「申请权限」:系统重置 shouldShowRequestPermissionRationale,插件无法读取永久拒绝标记;连拒两次显示「去设置」,业务方可自行持久化拒绝状态
  • Android 14+ photo 全量授权后 video/album 显示「调整范围」:Photo Picker 只授予请求中的权限,插件保守显示,点击后系统自动补授
  • iOS 通知首次查询:冷启动后首次 hasPermission('notification') 可能返回 PERMISSION_NOT_DETERMINED(缓存机制),下次即最新
  • iOS 后台定位两段式:先同意 WhenInUse 会等第二段弹窗,5s 未响应返回 BACKGROUND_LOCATION_UPGRADE_REQUIRED
  • 鸿蒙授权弹窗只出现一次:用户拒绝后系统不再重弹授权框;插件检测 dialogShownResults,未弹窗时自动降级 requestPermissionOnSetting 拉起权限设置面板二次引导,action=request 语义保持成立(deniedAlways 恒为空)
  • 鸿蒙通知弹窗仅首次出现:未发起过授权时 requestPermission 走系统弹窗;用户拒绝过一次后返回 NOTIFICATION_SETTINGS_REQUIRED,只能去应用详情页开启(状态已持久化,重装后重置)
  • 鸿蒙后台定位不可弹窗申请:requestPermission('backgroundLocation') 直接打开应用详情页并返回 OPEN_BACKGROUND_LOCATION_SETTINGS
  • 鸿蒙权限需宿主声明:module.json5 未声明 requestPermissions 时申请会被系统拒绝;插件会读取宿主声明列表,未声明的权限直接返回 HOST_PERMISSION_NOT_DECLARED(status=unsupported),避免出现「可申请」按钮点击必报错的误导状态
  • 超时兜底:蓝牙 / 定位 / 通知请求 5s、Android 权限申请 10s 无回调返回 REQUEST_PERMISSION_TIMEOUT,不会永久 pending

合规接入要点

  • [ ] 隐私弹窗在任何 SDK 初始化前出现;SDK 仅在 @agree / @ready 或 hasAgreed() 为真后初始化
  • [ ] 权限在用户触发相关功能时按需申请,并说明用途
  • [ ] 隐私政策更新时同步提升 privacyVersion
  • [ ] 生产 manifest 裁剪到最小权限集,并在隐私政策中逐一披露(勿直接复制 Demo manifest——Demo 是全权限测试台)
  • [ ] iOS 上架前配置 PrivacyInfo.xcprivacy:cp templates/PrivacyInfo.xcprivacy.template <宿主 iOS 原生资源目录>/PrivacyInfo.xcprivacy 并按业务补充
  • [ ] 扫描报告中的高风险权限逐条确认处理结论

常见问题

Q:H5 / 小程序能用吗? 不能获得原生能力。privacy-flow 仅 UI 可用,隐私状态与权限申请无原生实现;多端共用请自行降级,或仅在 App 端静态 import。

Q:enforceAgreed 默认值为什么两端不同? UTS API initPrivacy 默认 false(不强制拦截),privacy-flow 组件 prop 默认 true(组件场景默认强制合规);集成时按需显式指定。

Q:隐私政策更新后需要重新同意吗? 需要。提升 privacyVersion 后 hasAgreed() 自动变 false,组件会自动重新弹窗征求同意。

Q:如何自定义弹窗样式? 通过 dialog prop 传入 title/content/confirmText/cancelText/primaryColor/borderRadius/backgroundColor 等;如需完全自定义 UI,可只使用 UTS API 自行实现弹窗。

Q:权限申请结果如何区分「可再申请」与「永久拒绝」? 看 PERMISSION_DENIED(可再申请)vs PERMISSION_DENIED_ALWAYS(去设置)。iOS 无法区分首拒/永久拒,被拒即返回 PERMISSION_DENIED_ALWAYS。

Q:为什么 photo 全量授权后 video 还显示「调整范围」? Android 14+ Photo Picker 的系统行为(见「平台已知行为」),点击「调整范围」后系统自动补授,非插件缺陷。

开发者工具

修改 permission-matrix.json 后同步生成文档:

node uni_modules/privacy-compliance/scripts/sync-permission-matrix.js

发版前执行可确保 UTS 实现与矩阵无 drift(CI 同样会校验)。

许可证与更新日志

  • 插件本体授权以插件市场页面 / 购买协议为准;插件不内置三方开源组件,Android 端权限申请委托宿主配置的权限库(如 XXPermissions),其许可由宿主自行管理
  • 更新日志见 changelog.md

隐私、权限声明

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

插件不默认新增权限;宿主 App 请按实际业务在 manifest 中声明并裁剪权限。

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

本插件不采集或上传用户数据;仅在宿主 App 本地保存隐私同意状态。

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

无