更新记录

1.0.0(2026-04-11) 下载此版本

初次发布


平台兼容性

uni-app(5.06)

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

laoqianjunzi-permiss

laoqianjunzi-permiss 是一个基于 UTS 实现的跨端权限插件,统一封装了 Android、iOS、鸿蒙三个 App 平台上的权限检查、权限申请以及跳转系统设置页能力,可同时用于 uni-appuni-app x

它实际提供的核心能力只有 3 个:

  • checkPermissions:检查权限当前状态
  • requestPermissions:申请权限
  • openSystemPermissionPage:跳转到当前应用的系统设置页

插件内部已经针对三个平台做了原生适配:

  • Android:基于原生运行时权限与应用设置页
  • iOS:基于系统权限 API 与 App Settings
  • 鸿蒙:基于 @kit.AbilityKit 权限申请与设置页能力

适用范围

适用平台

根据插件源码和 package.json,当前真实支持情况如下:

平台 支持情况 说明
Android App 支持 最低 minVersion: 28
iOS App 支持 最低 minVersion: 12
鸿蒙 App 支持 app-harmony
H5 不用于真实权限控制 当前为占位实现,直接返回全部授权
微信小程序 不用于真实权限控制 当前为占位实现,直接返回全部授权

适用框架

  • uni-app:支持 Vue2 / Vue3 项目中直接调用
  • uni-app x:支持 uvue 页面与 uts 代码中直接调用

插件能力与行为说明

统一输入结构

每个权限都使用同一种数据结构:

type PermissionItem = {
  name: string
  title: string
  content: string
}

字段说明:

  • name:权限名称,必须传原生权限常量
  • title:权限申请标题说明
  • content:权限申请详细说明

统一返回结构

type PermissionResultItem = {
  name: string
  status: number
  title: string
  content: string
  cannotCheckByAPI: boolean
}

type PermissionResult = {
  allGranted: boolean
  doNotAskAgain: boolean
  permissions: Array<PermissionResultItem>
}

status 状态值

状态值 含义 说明
0 未授权 仍可以继续申请
1 已授权 可直接使用功能
2 已拒绝且需要去设置页 应引导用户手动开启
3 无效权限 权限名错误、未声明或当前平台不支持

cannotCheckByAPI 的含义

该字段主要是给 iOS 使用。

  • false:可以通过系统 API 直接判断状态
  • true:无法稳定通过 API 直接判断,需结合实际功能使用判断

例如 iOS 上的部分权限:

  • NSMotionUsageDescription
  • NSHealthShareUsageDescription
  • NSHealthUpdateUsageDescription
  • NSHomeKitUsageDescription
  • NSSiriUsageDescription
  • NSVideoSubscriberAccountUsageDescription
  • NSTVProviderUsageDescription
  • NSLocalNetworkUsageDescription

安装与引入

把插件安装到项目的 uni_modules/laoqianjunzi-permiss 后,在页面或业务模块中引入:

import {
  checkPermissions,
  requestPermissions,
  openSystemPermissionPage
} from '@/uni_modules/laoqianjunzi-permiss'

如果你在 uni-app x 中需要为权限数组补充类型,也可以同时引入类型:

import {
  checkPermissions,
  requestPermissions,
  openSystemPermissionPage
} from '@/uni_modules/laoqianjunzi-permiss'
import type { PermissionItem } from '@/uni_modules/laoqianjunzi-permiss/utssdk/interface.uts'

使用前必须先做的配置

插件只负责运行时权限处理,不会替你自动补齐业务工程中的权限声明。

根据 uni-app x 官方插件规范,插件目录不能直接替使用者修改业务项目根目录里的 manifest.jsonInfo.plist 等文件,因此这些配置必须由接入者在自己的项目里完成。

Android

请先在项目中声明对应 Android 权限。

  • uni-app:在 manifest.jsonapp-plus -> distribute -> android -> permissions 中声明,或在原生 AndroidManifest.xml 中声明
  • uni-app x:在项目 manifest.json / 原生 AndroidManifest.xml 中声明对应权限

常见权限示例:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

说明:

  • Android 13 及以上,相册/媒体建议使用 READ_MEDIA_IMAGESREAD_MEDIA_VIDEOREAD_MEDIA_AUDIO
  • Android 12 及以下,插件内部会把 READ_MEDIA_* 自动兼容映射到 READ_EXTERNAL_STORAGE
  • POST_NOTIFICATIONS 仅 Android 13+ 有意义;低版本会被视为无效权限

iOS

请先在业务项目的 Info.plist 中写入对应说明文案;如果是可视化配置项目,也可以在 manifest.json 的 iOS 隐私描述节点中配置。

常见示例:

<key>NSCameraUsageDescription</key>
<string>用于扫码、拍照或上传头像</string>
<key>NSMicrophoneUsageDescription</key>
<string>用于语音输入或录音</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>用于选择图片</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>用于定位附近服务</string>

注意:

  • 传给插件的 name 就是 Info.plist 的 key
  • 如果未在 Info.plist 中声明,即使运行时调用,也会被视为无效权限或无法正常弹框

鸿蒙

请先在鸿蒙工程对应的 module.json5 中声明权限,一般是 requestPermissions 数组。

示例:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA"
      },
      {
        "name": "ohos.permission.MICROPHONE"
      },
      {
        "name": "ohos.permission.LOCATION"
      }
    ]
  }
}

注意:

  • 传给插件的权限名必须以 ohos.permission. 开头
  • 未声明到 module.json5 的权限会返回 status = 3

三个 API 的使用方式

1. checkPermissions(permissions)

检查权限状态,返回 Promise<PermissionResult>

典型用法:

const result = await checkPermissions(permissionList)
if (result.allGranted) {
  // 已全部授权
} else {
  // 存在未授权权限
}

2. requestPermissions(permissions)

发起权限申请,返回 Promise<PermissionResult>

典型用法:

const result = await requestPermissions(permissionList)
if (!result.allGranted && result.doNotAskAgain) {
  await openSystemPermissionPage(permissionList)
}

3. openSystemPermissionPage(permissions)

打开当前应用的系统设置页。

说明:

  • Android:跳到当前 App 详情设置页
  • iOS:跳到当前 App Settings
  • 鸿蒙:跳到当前应用对应设置页
  • 参数必须传,若没有特定权限可传空数组 []
await openSystemPermissionPage([])

平台权限名写法

Android 权限名写法

推荐直接传完整原生常量:

  • android.permission.CAMERA
  • android.permission.RECORD_AUDIO
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.READ_MEDIA_IMAGES
  • android.permission.READ_MEDIA_VIDEO
  • android.permission.READ_MEDIA_AUDIO
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.POST_NOTIFICATIONS

补充说明:

  • 插件内部支持你只传 CAMERA 这类短名,并自动补成 android.permission.CAMERA
  • 但为了避免项目里出现歧义,仍然建议始终写完整权限名

iOS 权限名写法

直接传 Info.plist key,例如:

  • NSCameraUsageDescription
  • NSMicrophoneUsageDescription
  • NSPhotoLibraryUsageDescription
  • NSPhotoLibraryAddUsageDescription
  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription
  • NSContactsUsageDescription
  • NSCalendarsUsageDescription
  • NSCalendarsFullAccessUsageDescription
  • NSRemindersUsageDescription
  • NSUserTrackingUsageDescription
  • NSUserNotificationsUsageDescription

鸿蒙权限名写法

必须传鸿蒙原生权限常量,例如:

  • ohos.permission.CAMERA
  • ohos.permission.MICROPHONE
  • ohos.permission.LOCATION
  • ohos.permission.READ_CALENDAR
  • ohos.permission.WRITE_CALENDAR

uni-app 用法

uni-app 中建议在 APP-PLUS 环境下使用,并在运行时根据系统信息构造权限数组。

uni-app 通用调用流程

import {
  checkPermissions,
  requestPermissions,
  openSystemPermissionPage
} from '@/uni_modules/laoqianjunzi-permiss'

function getPermissionList() {
  const systemInfo = uni.getSystemInfoSync()
  const osName = systemInfo.osName || ''
  const platform = systemInfo.platform || ''

  if (osName === 'android' || platform === 'android') {
    return [
      {
        name: 'android.permission.CAMERA',
        title: '相机权限申请说明',
        content: '用于扫码、拍照或上传图片。'
      }
    ]
  }

  if (osName === 'ios' || platform === 'ios') {
    return [
      {
        name: 'NSCameraUsageDescription',
        title: '相机权限申请说明',
        content: '用于扫码、拍照或上传图片。'
      }
    ]
  }

  if (osName === 'harmonyos') {
    return [
      {
        name: 'ohos.permission.CAMERA',
        title: '相机权限申请说明',
        content: '用于扫码、拍照或上传图片。'
      }
    ]
  }

  return []
}

export async function ensurePermissions() {
  const permissionList = getPermissionList()
  if (!permissionList.length) {
    return true
  }

  const checkResult = await checkPermissions(permissionList)
  if (checkResult.allGranted) {
    return true
  }

  const requestResult = await requestPermissions(permissionList)
  if (requestResult.allGranted) {
    return true
  }

  if (requestResult.doNotAskAgain) {
    const modalRes = await uni.showModal({
      title: '权限提示',
      content: '相关权限已被拒绝,请前往系统设置手动开启。'
    })
    if (modalRes.confirm) {
      await openSystemPermissionPage(permissionList)
    }
  }

  return false
}

uni-app / Android

1. 权限数组写法

const permissionList = [
  {
    name: 'android.permission.CAMERA',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'android.permission.ACCESS_FINE_LOCATION',
    title: '定位权限申请说明',
    content: '用于获取附近服务或门店信息。'
  }
]

2. 典型调用

const checkResult = await checkPermissions(permissionList)
if (!checkResult.allGranted) {
  const requestResult = await requestPermissions(permissionList)
  if (!requestResult.allGranted && requestResult.doNotAskAgain) {
    await openSystemPermissionPage(permissionList)
  }
}

3. Android 平台说明

  • 插件会先检查权限是否已在 Manifest 中声明
  • 如果未声明,会直接返回 status = 3
  • Android 6.0+ 会按运行时权限处理
  • 如果用户点了“不再询问”,会返回 status = 2
  • POST_NOTIFICATIONS 在 Android 13+ 才有效

uni-app / iOS

1. 权限数组写法

const permissionList = [
  {
    name: 'NSCameraUsageDescription',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'NSPhotoLibraryUsageDescription',
    title: '相册权限申请说明',
    content: '用于从相册中选择图片。'
  }
]

2. 典型调用

const requestResult = await requestPermissions(permissionList)
if (!requestResult.allGranted && requestResult.doNotAskAgain) {
  await openSystemPermissionPage(permissionList)
}

3. iOS 平台说明

  • 传入的权限名就是 Info.plist 的 key
  • 被用户拒绝后,会返回 status = 2
  • openSystemPermissionPage 会直接跳转到当前应用设置页
  • 某些权限无法通过 API 完整判断,返回项中会标记 cannotCheckByAPI = true

uni-app / 鸿蒙

1. 权限数组写法

const permissionList = [
  {
    name: 'ohos.permission.CAMERA',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'ohos.permission.LOCATION',
    title: '定位权限申请说明',
    content: '用于获取附近服务或门店信息。'
  }
]

2. 典型调用

const checkResult = await checkPermissions(permissionList)
if (!checkResult.allGranted) {
  const requestResult = await requestPermissions(permissionList)
  if (!requestResult.allGranted && requestResult.doNotAskAgain) {
    await openSystemPermissionPage(permissionList)
  }
}

3. 鸿蒙平台说明

  • 权限名必须严格以 ohos.permission. 开头
  • 如果权限未配置到 module.json5,通常会返回 status = 3
  • 鸿蒙检查权限时通常无法区分“从未申请过”和“已拒绝”,检查阶段统一更偏向返回未授权
  • 真正申请时,如果用户已拒绝并且不能再拉起弹窗,插件会把结果整理为 status = 2

uni-app x 用法

uni-app x 推荐直接使用条件编译分别维护 Android、iOS、鸿蒙三份权限数组,并在 uts 中给数组加类型声明。

uni-app x 通用页面示例

<template>
  <view class="page">
    <button class="btn" type="primary" @click="ensurePermissions">申请权限</button>
  </view>
</template>

<script setup lang="uts">
import {
  checkPermissions,
  requestPermissions,
  openSystemPermissionPage
} from '@/uni_modules/laoqianjunzi-permiss'
import type { PermissionItem } from '@/uni_modules/laoqianjunzi-permiss/utssdk/interface.uts'

function getPermissionList(): Array<PermissionItem> {
  // #ifdef APP-ANDROID
  return [
    {
      name: 'android.permission.CAMERA',
      title: '相机权限申请说明',
      content: '用于扫码、拍照或上传图片。'
    }
  ]
  // #endif

  // #ifdef APP-IOS
  return [
    {
      name: 'NSCameraUsageDescription',
      title: '相机权限申请说明',
      content: '用于扫码、拍照或上传图片。'
    }
  ]
  // #endif

  // #ifdef APP-HARMONY
  return [
    {
      name: 'ohos.permission.CAMERA',
      title: '相机权限申请说明',
      content: '用于扫码、拍照或上传图片。'
    }
  ]
  // #endif

  return [] as Array<PermissionItem>
}

async function ensurePermissions() {
  const permissionList = getPermissionList()
  if (permissionList.length == 0) {
    return
  }

  const checkResult = await checkPermissions(permissionList)
  if (checkResult.allGranted) {
    uni.showToast({
      title: '权限已就绪',
      icon: 'none'
    })
    return
  }

  const requestResult = await requestPermissions(permissionList)
  if (requestResult.allGranted) {
    uni.showToast({
      title: '授权成功',
      icon: 'none'
    })
    return
  }

  if (requestResult.doNotAskAgain) {
    const modalRes = await uni.showModal({
      title: '权限提示',
      content: '相关权限已被拒绝,请前往系统设置手动开启。'
    })
    if (modalRes.confirm) {
      await openSystemPermissionPage(permissionList)
    }
  }
}
</script>

<style>
.page {
  display: flex;
  flex-direction: column;
  padding: 24px;
}

.btn {
  margin-top: 12px;
}
</style>

uni-app x / Android

1. 推荐权限数组

import type { PermissionItem } from '@/uni_modules/laoqianjunzi-permiss/utssdk/interface.uts'

const permissionList: Array<PermissionItem> = [
  {
    name: 'android.permission.CAMERA',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'android.permission.RECORD_AUDIO',
    title: '麦克风权限申请说明',
    content: '用于语音输入或录音。'
  }
]

2. 推荐调用方式

const checkResult = await checkPermissions(permissionList)
if (!checkResult.allGranted) {
  const requestResult = await requestPermissions(permissionList)
  if (!requestResult.allGranted && requestResult.doNotAskAgain) {
    await openSystemPermissionPage(permissionList)
  }
}

3. Android 平台补充说明

  • 插件内部会先确认权限是否已在 Manifest 中声明
  • 再检查是否已授权
  • 对于已拒绝权限,会结合是否申请过、是否还能再次弹框,区分返回 02
  • 对媒体权限做了 Android 13 以下兼容映射

uni-app x / iOS

1. 推荐权限数组

import type { PermissionItem } from '@/uni_modules/laoqianjunzi-permiss/utssdk/interface.uts'

const permissionList: Array<PermissionItem> = [
  {
    name: 'NSCameraUsageDescription',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'NSMicrophoneUsageDescription',
    title: '麦克风权限申请说明',
    content: '用于语音输入或录音。'
  }
]

2. 推荐调用方式

const requestResult = await requestPermissions(permissionList)
if (!requestResult.allGranted && requestResult.doNotAskAgain) {
  await openSystemPermissionPage(permissionList)
}

3. iOS 平台补充说明

  • 相册、相机、麦克风、定位、通知、通讯录、日历、提醒事项、蓝牙、追踪等均已做原生适配
  • NSPhotoLibraryUsageDescription 在部分授权场景下也会被视为已授权
  • 部分权限虽然可以发起申请,但无法在检查阶段精确判断,此时会标记 cannotCheckByAPI = true
  • openSystemPermissionPage 会通过 UIApplication.openSettingsURLString 跳转设置页

uni-app x / 鸿蒙

1. 推荐权限数组

import type { PermissionItem } from '@/uni_modules/laoqianjunzi-permiss/utssdk/interface.uts'

const permissionList: Array<PermissionItem> = [
  {
    name: 'ohos.permission.CAMERA',
    title: '相机权限申请说明',
    content: '用于扫码、拍照或上传图片。'
  },
  {
    name: 'ohos.permission.MICROPHONE',
    title: '麦克风权限申请说明',
    content: '用于语音输入或录音。'
  }
]

2. 推荐调用方式

const checkResult = await checkPermissions(permissionList)
if (!checkResult.allGranted) {
  const requestResult = await requestPermissions(permissionList)
  if (!requestResult.allGranted && requestResult.doNotAskAgain) {
    await openSystemPermissionPage(permissionList)
  }
}

3. 鸿蒙平台补充说明

  • 插件内部使用 requestPermissionsFromUser
  • 若用户拒绝后系统不再弹框,插件会进一步引导走设置页相关能力,并整理为 status = 2
  • openSystemPermissionPage 会拉起鸿蒙设置应用中的当前应用设置页

推荐接入流程

无论是 uni-app 还是 uni-app x,都建议按下面顺序接入:

  1. 先在业务项目中声明平台权限
  2. 页面进入后先 checkPermissions
  3. 未授权时再 requestPermissions
  4. 若结果里 doNotAskAgain = true,弹窗说明后调用 openSystemPermissionPage
  5. 用户回到页面后,再次调用 checkPermissions

常见场景示例

相机权限

平台 权限名
Android android.permission.CAMERA
iOS NSCameraUsageDescription
鸿蒙 ohos.permission.CAMERA

麦克风权限

平台 权限名
Android android.permission.RECORD_AUDIO
iOS NSMicrophoneUsageDescription
鸿蒙 ohos.permission.MICROPHONE

定位权限

平台 权限名
Android android.permission.ACCESS_FINE_LOCATION
iOS NSLocationWhenInUseUsageDescription
鸿蒙 ohos.permission.LOCATION

注意事项

1. 不要传空数组给检查和申请方法

插件源码中:

  • checkPermissions([]) 会报参数错误
  • requestPermissions([]) 会报参数错误
  • openSystemPermissionPage([]) 可以正常调用

2. 返回结果顺序与传入顺序一致

permissions 返回数组始终与传入顺序一致,适合按原始顺序展示说明文案。

3. Android 会校验权限是否已在 Manifest 中声明

如果没有声明,即使权限名本身正确,也会返回 status = 3

4. iOS 某些权限不适合只看检查结果

cannotCheckByAPI = true 时,应以实际功能调用效果为准,不建议只依据 status 做最终业务判断。

5. 鸿蒙权限检查与权限申请不是同一语义

鸿蒙在检查阶段通常只能判断“当前是否已授权”,不能完整区分“首次未申请”和“曾被拒绝”,所以应以申请结果为最终判断依据。

6. 插件更适合 App 端统一权限治理

如果你的项目还包含 H5、小程序等端,建议把该插件仅用于 App 侧权限治理;H5 和小程序当前目录下的实现为占位逻辑,不适合作为真实权限判断依据。

最佳实践建议

  • 把权限申请收口到统一工具模块,避免各页面重复写权限逻辑
  • 在真正使用敏感能力前再申请,不要在应用启动时一次性申请所有权限
  • titlecontent 写成真实业务用途,便于审核与用户理解
  • status = 2 的情况统一做“去设置页”引导
  • Android、iOS、鸿蒙的权限名不要混用,必须按平台分别构造数组

版本信息

  • 插件版本:1.0.0
  • 插件类型:UTS 插件
  • 适配工程:uni-app / uni-app x

如果你希望在项目里进一步封装一个 ensureCameraPermissionensureLocationPermissionensureRecordPermission 之类的业务方法,建议直接基于本插件的三个 API 二次封装即可。

隐私、权限声明

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

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

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

许可协议

MIT协议