uni.getsetting需在用户交互后调用并区分平台:小程序在按钮点击时触发,app在onshow延时100ms;权限拒绝后authorize失效,须引导手动开启;原生配置(manifest.json、ios/android权限声明)必须完整打包才生效。

uni.getSetting 检查权限状态前必须确认平台和时机
直接调 uni.getSetting 却返回空对象或 authSetting 里全是 undefined,大概率是调用时机不对或平台误判。iOS 真机上这个 API 才返回真实状态,模拟器永远不可靠;Android 部分机型(尤其华为/小米)在 onLaunch 阶段调用会拿不到初始化后的权限表。
正确做法是:把检查逻辑放在用户可感知的交互点之后,比如按钮点击、onShow 生命周期,且必须加平台判断:
- 小程序端(微信/支付宝)可放心在按钮里调,但必须是用户主动触发(不能 onload 自动弹)
- App 端建议在
onShow后延时 100ms 再查,避免权限系统未就绪 - WebView 场景下(如内嵌 H5),
uni.getSetting对 WebView 自身权限无感知,它只管 uni-app 容器层,这类场景需单独处理
检测到 scope.camera === false 后别再调 authorize
用户点过“拒绝”甚至勾选“不再询问”,uni.authorize({ scope: 'scope.camera' }) 就彻底失效——它不会弹窗,直接进 fail 回调,返回 errMsg: "authorize:fail auth deny"。这在 App 端尤其明显,uni.authorize 基本形同虚设。
此时唯一有效动作是引导用户手动开启:
- 小程序端(微信)用
wx.openSetting(),不是uni.openSetting()(后者不支持) - App 端用
uni.openSetting(),但必须先uni.showModal说明用途,不能无提示跳转(否则华为/苹果审核可能拒) - iOS 上如果用户已永久拒绝,跳转后看到的是灰色不可操作项,需提示“请前往「设置 → 隐私与安全性 → 相机」中开启”
manifest.json 和原生配置没配全,授权请求必失败
很多开发者卡在“明明写了 uni.authorize,却连弹窗都不出现”,根本原因是没走通原生层准入流程。uni-app 不是纯 JS 框架,权限申请依赖底层声明。
缺一不可的三步配置:
- HBuilderX 中打开
manifest.json→ “App模块配置” → 勾选 Camera & Gallery 模块(仅勾 permissions 不生效) - iOS 需补全
"app-plus".distribute.apple.permissions下的camera描述,且"app-plus".ios.info中必须含NSCameraUsageDescription字段,文案要具体(如“用于拍摄证件照”) - Android 要确保
manifest.json的android.permission.CAMERA已声明,云端打包时勾选对应权限
改完必须「完整打包」,热更新、调试基座、自定义基座均不生效。
WebView 场景下相机权限拒绝后重启才生效
如果你的应用是通过 web-view 加载 H5 页面,且页面里调用了 input[type="file"] 触发相机,那整个权限链路就脱离了 uni-app 控制——它走的是 WebView 内核自己的权限缓存机制。
连续拒绝两次后,即使你在系统设置里手动打开了相机权限,WebView 仍会沿用旧缓存状态,表现为点击无反应。这不是代码 bug,是 Android WebView 的已知行为(尤其 Android 14+)。
目前唯一稳定解法:
- 提示用户“请退出应用后重新打开”
- 不要试图用
location.reload()或重载 web-view,无效 - 若必须免重启,可考虑将相机功能从 H5 迁出,改用 uni-app 原生
uni.chooseImage+sourceType: ['camera']实现
最常被忽略的点:iOS 的 scope.writePhotosAlbum 和 scope.camera 是两个独立权限,保存照片失败不一定是相机问题,可能是相册写入被拒;而 Android 13+ 已废弃 writePhotosAlbum,但 uni-app 当前版本尚未适配新权限模型,所以跨端兼容逻辑必须分开写。











