UniApp权限管理太乱?一行代码搞定Android/iOS/微信小程序!
做跨端开发最头疼的就是权限适配——Android要动态申请、iOS要配置描述、小程序又是另一套API。这个插件把三端权限管理统一封装,支持防抖、自动引导用户去设置,只需一行代码就能优雅搞定相机、定位、存储等常见权限。
一、问题背景:三端权限,三套逻辑
最近接手一个UniApp项目,权限管理代码写得我头皮发麻:
// Android 一套
if (platform === 'android') {
plus.android.requestPermissions(
['android.permission.CAMERA'],
(result) => {
if (result.granted.length > 0) {
// 有权限
} else {
// 无权限,引导去设置
}
}
);
}
// iOS 又一套
if (platform === 'ios') {
const AVCaptureDevice = plus.ios.importClass('AVCaptureDevice');
const status = AVCaptureDevice.authorizationStatusForMediaType('vide');
// ...
}
// 小程序还不一样...
wx.authorize({
scope: 'scope.camera',
success: () => {},
fail: () => {
wx.openSetting(); // 引导用户去设置
}
});
同一个功能,三套代码;每次加个权限,三个文件都要改。
实在忍不了,自己封装了个统一的权限管理插件——qj-permission。
二、插件特性
✅ 三端统一:一套API搞定Android、iOS、微信小程序
✅ 自动适配:根据运行平台自动切换权限处理逻辑
✅ 防抖机制:避免用户快速点击导致多次弹窗
✅ 友好引导:权限被拒后自动弹窗引导用户去设置
✅ 开箱即用:内置常见权限的申请文案,也支持自定义
三、安装使用
1. 引入插件
将 qj-permission 文件夹放到项目中:
├── qj-permission/
│ ├── index.js # 主入口
│ ├── android.js # Android权限处理
│ ├── ios.js # iOS权限处理
│ ├── wechat.js # 微信小程序权限处理
│ └── permission.json # 权限配置
2. 基础用法
import { authPermission } from '@/qj-permission/index.js';
// 申请相机权限
authPermission('CAMERA', () => {
// 授权成功,执行业务逻辑
uni.chooseImage({
count: 1,
sourceType: ['camera'],
success: (res) => {
console.log('拍照成功', res.tempFilePaths);
}
});
});
或者
<button @click="authPermission('ACCESS_FINE_LOCATION', callbackLoca)">地理位置权限</button>
就这么简单,一行代码搞定!
3. 支持的权限类型
| 权限ID | 说明 |
|---|---|
CAMERA | 相机/摄像头 |
ACCESS_FINE_LOCATION | 地理位置 |
WRITE_EXTERNAL_STORAGE | 存储空间/相册 |
RECORD_AUDIO | 麦克风 |
CALL_PHONE | 拨打电话 |
READ_CONTACTS | 通讯录 |
四、核心实现解析
1. 统一入口,平台分发
async function authPermission(permissionID, callback) {
// #ifdef APP-PLUS
if (systemInfo.platform === 'android') {
await handleAndroidPermission(permissionID, callback);
} else if (systemInfo.platform === 'ios') {
await handleIosPermission(permissionID);
}
// #endif
// #ifdef MP-WEIXIN
await handleWechatPermission(permissionID);
// #endif
callback?.();
}
利用UniApp的条件编译 #ifdef,在打包时自动选择对应平台的实现。
2. 防抖机制
用户快速点击可能触发多次权限申请,造成体验问题:
let isDebouncing = false;
async function debounceExecute(fn) {
if (isDebouncing) return; // 防止重复触发
isDebouncing = true;
try {
return await fn();
} finally {
setTimeout(() => { isDebouncing = false; }, 500);
}
}
3. 权限被拒后的友好引导
function showPermissionModal(onConfirm) {
uni.showModal({
title: "温馨提示",
content: "还没有该权限,立即去设置开启?",
confirmText: "去设置",
success: (res) => res.confirm && onConfirm?.(),
});
}
用户拒绝授权后,会弹出引导框,点击"去设置"直接跳转系统设置页面。
4. 权限配置文件
permission.json 中预置了各权限的申请说明文案:
{
"CAMERA": {
"title": "相机/摄像头权限申请说明",
"content": "用于开启相机拍摄照片和视频,用于头像设置、内容发布、扫码识别及相关拍摄场景。",
"ios": "AVCaptureDevice",
"wechat": "scope.camera"
}
}
Android会自动展示说明弹窗,符合Google Play的权限政策要求。
五、注意事项
- iOS需配置权限描述:在
manifest.json的app-plus.distribute.iOS.privacyDescription中配置权限使用说明 - Android需声明权限:在
manifest.json的app-plus.distribute.android.permissions中添加所需权限 - 小程序需在manifest.json中声明:如
"permission": { "scope.userLocation": { "desc": "你的位置信息将用于..." }}
六、总结
跨端开发的魅力在于"一次开发,多端运行",但权限管理这种平台差异点往往会打破这个理想。
这个插件的思路很简单:统一入口 + 平台分发 + 体验优化。封装之后,业务代码再也不用关心平台差异,专注于业务逻辑就好。
如果觉得有用,欢迎点赞收藏,也欢迎在评论区交流你的跨端权限管理方案~
插件文件:已附在文章开头,可直接下载使用