# m-permission-manager 使用规范 本文档面向集成本插件的 App 开发者,说明 **必须遵守的约束**、**推荐做法** 和 **上架审核注意事项**。 --- ## 1. 基本约束(必须遵守) ### 1.1 用户主动触发 `requestPermission` / `requestPermissions` **必须由真实用户手势触发**,例如按钮 `click` / `tap`。 ```vue ``` 原因:Android / iOS / Harmony 运行时权限弹窗均面向用户明确操作;冷启动批量申请易触发拒绝,且不符合各应用商店审核惯例。 ### 1.2 先声明、后申请 **仅安装插件不够**,必须在各端配置文件中声明所需权限,否则: | 平台 | 未声明后果 | | --- | --- | | Android | `SecurityException`、申请无弹窗或直接失败 | | iOS | 崩溃或无授权弹窗 | | Harmony | 系统设置无对应开关,插件返回 `restricted` 或 9020003 | 详细配置见 [权限配置说明.md](./权限配置说明.md)。 ### 1.3 按需申请 只申请业务实际使用的权限。在功能入口处按需 `requestPermission`,不要一次性申请全部权限。 ```js // ✅ 审核页 async function handleRequestCamera() { const granted = await requestPermission('camera') if (!granted) { uni.showModal({ title: '需要相机权限', content: getPermissionSettingsGuide('camera', '相机'), confirmText: '去设置', success: (res) => { if (res.confirm) openPermissionSettings('camera') }, }) return } // 继续业务逻辑 } ``` ### 1.4 平台差异处理 调用前可通过 `getSupportedPermissions()` 过滤当前平台不支持的 Key,避免向用户展示无效入口。 ```js const supported = getSupportedPermissions() const canUseOverlay = supported.includes('overlay') // 仅 Android 为 true ``` --- ## 2. 推荐集成流程 ``` 进入功能页 ↓ checkPermission(key) ──→ granted → 执行业务 ↓ notDetermined / denied 用户点击「申请权限」 ↓ requestPermission(key) ↓ 系统弹窗 ──→ 拒绝 → getPermissionSettingsGuide + openPermissionSettings ↓ 同意 granted → 执行业务 ``` ### 2.1 Promise 封装(推荐) 项目可复用 `@/utils/permission-manager.js`: ```js import { checkPermission, requestPermission, requestPermissions, openPermissionSettings, getPermissionSettingsGuide, ensurePermission, getSupportedPermissions, } from '@/utils/permission-manager' ``` | 方法 | 用途 | | --- | --- | | `checkPermission(key)` | 检查状态,返回 `{ granted, status }` | | `requestPermission(key)` | 申请权限,返回 `boolean` | | `requestPermissions(keys[])` | 批量申请,返回 `{ allGranted, results }` | | `openPermissionSettings(key)` | 按权限类型跳转系统设置 | | `getPermissionSettingsGuide(key, label)` | 获取跳转前的引导文案 | | `ensurePermission(key, { openSettings })` | 检查 → 申请 → 可选跳转设置 | ### 2.2 直接调用 UTS API(callback 风格) ```js import { requestPermission } from '@/uni_modules/m-permission-manager' requestPermission({ permission: 'camera', success(res) { if (res.granted) { /* ... */ } }, fail(err) { console.error(err.errCode, err.errMsg) }, }) ``` ### 2.3 永久拒绝后的引导 用户选择「不再询问」或多次拒绝后,应引导至系统设置: ```js const granted = await requestPermission('bluetooth') if (!granted) { uni.showModal({ title: '蓝牙权限未授予', content: getPermissionSettingsGuide('bluetooth', '蓝牙'), confirmText: '去设置', success: (res) => { if (res.confirm) openPermissionSettings('bluetooth') }, }) } ``` 各端跳转行为: | 平台 | `openPermissionSettings` 行为 | | --- | --- | | Android 普通权限 | 应用详情 → 权限列表 | | Android `overlay` | 悬浮窗权限设置页 | | Android `writeSettings` | 修改系统设置权限页 | | iOS | 本 App 设置页(需 manifest 声明对应 UsageDescription) | | Harmony | 系统设置 → 应用详情 | --- ## 3. 各端特别注意 ### 3.1 Android - **Android 13+**:相册 / 存储自动映射 `READ_MEDIA_IMAGES` / `READ_MEDIA_VIDEO` - **Android 12+**:蓝牙自动映射 `BLUETOOTH_CONNECT` / `BLUETOOTH_SCAN` - **特殊权限**:`overlay`、`writeSettings` 需跳转系统设置页,申请结果可能为 `notDetermined`,返回后需再次 `checkPermission` ### 3.2 iOS - 必须在 `privacyDescription` 中配置对应 `NS*UsageDescription`,否则无弹窗 - `storage` / `readStorage` 映射到相册权限(`PHPhotoLibrary`) - `coarseLocation` / `location` 均映射到定位授权 - **蓝牙**:需 `NSBluetoothAlwaysUsageDescription`;系统蓝牙开关在「设置 → 蓝牙」,App 授权在 App 设置页或「隐私与安全性 → 蓝牙」 ### 3.3 Harmony - 默认 `module.json5` 含 5 项 normal 权限,调试包可直接安装 - 相册 / 通讯录为 `system_basic`,需 ACL 签名 + `module.full.json5` - 相册选图推荐 `uni.chooseImage`(系统 PhotoViewPicker),无需媒体读写权限 - 未声明的 ACL 权限:检查返回 `restricted`,申请返回 9020003 --- ## 4. 错误码与用户提示 | errCode | 含义 | 建议提示 | | --- | --- | --- | | 9020001 | 当前环境不支持 | 请在 App 端使用 | | 9020002 | 用户拒绝授权 | 您拒绝了授权,可在设置中重新开启 | | 9020003 | 权限不支持当前平台 | 当前平台不支持该权限 | | 9020004 | 打开系统设置失败 | 无法打开系统设置,请手动前往 | | 9020005 | 权限检查失败 | 权限检查失败,请重试 | | 9020006 | 权限申请失败 | 权限申请失败,请重试 | --- ## 5. 上架审核注意事项 | 市场 | 注意点 | | --- | --- | | App Store | 每个 `NS*UsageDescription` 文案需与真实功能一致;不要申请未使用的权限 | | Google Play | 需在 Data safety 中声明权限用途;Android 13+ 媒体权限需按类型声明 | | 华为 / 鸿蒙 | 说明 `ohos.permission.*` 用途;system_basic 权限需 ACL 白名单 | | 国内 Android 市场 | 隐私合规检测会扫描 manifest 权限列表,确保与隐私政策一致 | --- ## 6. 自定义基座与发版 1. 导入或更新插件后,**必须重新制作自定义基座**或云打包 2. 修改 `manifest.json` 权限或鸿蒙 `module.json5` 后,需重新打包 3. iOS 修改 `privacyDescription` 后需重新打包,必要时删除旧 App 重装以重新触发授权弹窗 --- ## 7. 参考文档 - [readme.md](./readme.md) — API 与快速开始 - [权限配置说明.md](./权限配置说明.md) — 三端权限文件配置详解 - [发布指南.md](./发布指南.md) — 插件市场发布填写参考