更新记录
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.abilityAccessCtrlcheckAccessTokenSync查询 +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.jsonextVersion导致 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中声明权限(含$stringreason 资源),模板见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

收藏人数:
购买源码授权版(
试用
使用 HBuilder 导入示例项目
赞赏(0)
下载 51
赞赏 0
下载 12651664
赞赏 1953
赞赏
京公网安备:11010802035340号