使用规范.md 6.9 KB

m-permission-manager 使用规范

本文档面向集成本插件的 App 开发者,说明 必须遵守的约束推荐做法上架审核注意事项


1. 基本约束(必须遵守)

1.1 用户主动触发

requestPermission / requestPermissions 必须由真实用户手势触发,例如按钮 click / tap

<!-- ✅ 正确 -->
<button @click="handleRequestCamera">申请相机权限</button>

<!-- ❌ 错误:页面 onLoad / onShow 自动批量申请 -->
<script setup>
onMounted(async () => {
  await requestPermissions(['camera', 'microphone', 'location']) // 体验差,可能被系统限制
})
</script>

原因:Android / iOS / Harmony 运行时权限弹窗均面向用户明确操作;冷启动批量申请易触发拒绝,且不符合各应用商店审核惯例。

1.2 先声明、后申请

仅安装插件不够,必须在各端配置文件中声明所需权限,否则:

平台 未声明后果
Android SecurityException、申请无弹窗或直接失败
iOS 崩溃或无授权弹窗
Harmony 系统设置无对应开关,插件返回 restricted 或 9020003

详细配置见 权限配置说明.md

1.3 按需申请

只申请业务实际使用的权限。在功能入口处按需 requestPermission,不要一次性申请全部权限。

// ✅ 审核页
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,避免向用户展示无效入口。

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

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 风格)

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 永久拒绝后的引导

用户选择「不再询问」或多次拒绝后,应引导至系统设置:

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
  • 特殊权限overlaywriteSettings 需跳转系统设置页,申请结果可能为 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. 参考文档