manifest.json未配置权限时uni.authorize必失败;需勾选Camera&Gallery模块、补全iOS描述文案及Info.plist字段、重新完整打包;uni.getSetting需在onShow后调用且区分平台检查scope.writePhotosAlbum。

manifest.json 里不配权限,uni.authorize 肯定失败
iOS 和 Android 都不会让你在没声明的前提下动态申请敏感权限——这步是硬性门槛,不是可选项。HBuilderX 3.6.11+ 把相机和相册拆成独立模块,光写 permissions 不够,还得勾选 Camera&Gallery 模块。
- 检查
manifest.json→ “App模块配置” → “可选模块” → 勾选Camera&Gallery(相机和相册) - 同时在
"app-plus".distribute.apple.permissions下补上描述:"camera": { "description": "用于拍照上传头像" }、"photos": { "description": "用于从相册选择图片" } - iOS 还要额外加 Info.plist 字段:在
"app-plus".ios.info里加"NSCameraUsageDescription"和"NSPhotoLibraryUsageDescription",内容必须具体,不能写“用于功能优化”这种模糊话 - 改完必须重新「完整打包」,热更新不生效
uni.getSetting 返回空或 undefined?先确认平台和时机
这个 API 在 iOS 真机上才返回真实授权状态,模拟器永远返回空对象;而且它只在 App 启动后、用户操作前调用才可靠——比如放在按钮点击里就晚了,得提前埋点。
- 别在
onLaunch就调uni.getSetting,此时权限系统可能还没初始化,建议延后到onShow或用户触发动作时再查 - 返回的
res.authSetting是个对象,键名固定:"scope.camera"、"scope.writePhotosAlbum"(注意不是read,iOS 写相册才是关键) - Android 13+ 开始,
writePhotosAlbum已被废弃,要用manageExternalStorage或媒体权限,但 uni-app 目前仍走旧路径,所以 iOS 和 Android 要分开处理逻辑
uni.authorize 只弹一次,拒绝后不能再唤起弹窗
这是最常卡住人的地方:用户点“不允许”,你再点保存按钮,uni.authorize 直接进 fail 回调,不会重试。这时候必须引导用户手动去系统设置里开。
- 在
fail回调里立刻调uni.showModal提示,并带uni.openSetting()跳转按钮 - 不要反复调用
uni.authorize,iOS 会静默失败,Android 可能触发系统“不再询问”标记 - 如果用户点了“不再询问”,
uni.getSetting里对应字段会变成false,且uni.openSetting()才是唯一出路 - 小程序端(如微信)不支持
uni.openSetting,需换用wx.openSetting,uni-app 项目要做平台判断
保存图片前漏掉 scope.writePhotosAlbum 权限,iOS 会静默失败
很多人以为有相册读权限就能写,其实 iOS 分得极细:photos 权限只管读,writePhotosAlbum 才管存。不申请这个,uni.saveImageToPhotosAlbum 会直接报错 errCode: 1002(无权限),连提示都没有。
- 务必在调用
uni.saveImageToPhotosAlbum前,用uni.getSetting检查authSetting['scope.writePhotosAlbum'] - Android 上这个字段已弃用,但 uni-app 为兼容仍保留,所以判断逻辑要包一层平台判断:
if (uni.getSystemInfoSync().platform === 'ios') - 真机测试必须用 iOS 设备,模拟器不触发权限弹窗也不校验描述文案,App Store 审核会因缺失
NSPhotoLibraryAddUsageDescription直接拒
权限不是配完 manifest 就完事,也不是调一次 API 就搞定。iOS 的描述文案、模块勾选、权限粒度、失败后跳转路径,四个环节缺一不可;Android 则要注意 API 版本差异和存储权限演进。最容易忽略的是:iOS 真机未授权时,uni.saveImageToPhotosAlbum 不报错也不提示,只默默失败。

















