相机、定位、存储权限在HBuilderX打包时易失效,核心在于混淆“声明”与“申请”:manifest.json勾选仅为声明,必须调用uni.authorize等API运行时申请;Android定位需同时勾选粗略与精确定位权限,iOS需填写具业务语义的描述文案;相机和存储权限须分平台配置完整,且云打包前须手动核对双端配置。

相机、定位、存储这三类权限在HBuilderX打包Android/iOS App时,最容易出现“勾了没用”“真机失效”“审核被拒”问题。核心原因不是配置漏了,而是没分清“声明”和“申请”——manifest.json里勾选只是告诉系统“我可能要用”,而真正拿到权限,必须在代码里调用对应API向用户要一次同意。
uni.getLocation() 无回调?先查 manifest.json 里有没有这两个权限
很多开发者只勾了 ACCESS_FINE_LOCATION,结果在部分Android设备(尤其是国产定制系统)上完全拿不到位置。这是因为从Android 12(API 31)起,系统强制要求:哪怕你只要精确定位,也必须同时声明粗略定位。
- 必须同时勾选:
android.permission.ACCESS_COARSE_LOCATION和android.permission.ACCESS_FINE_LOCATION - 顺序建议按粗略→精确排列,避免后期维护混淆
- 如果需要后台持续定位(比如运动轨迹记录),还得额外勾选
android.permission.ACCESS_BACKGROUND_LOCATION,且需在运行时二次申请 - iOS端不能只写空文案,
NSLocationWhenInUseUsageDescription的值必须具业务语义,例如“用于匹配附近可预约的维修师傅”
uni.chooseImage() 或扫码黑屏?检查 Camera 权限是否分平台配全
Android和iOS对相机权限的处理逻辑完全不同:Android靠运行时弹窗+Manifest声明,iOS则依赖Info.plist描述+原生API触发。只在HBuilderX里勾一个CAMERA远远不够。
- Android侧:勾选
android.permission.CAMERA+android.permission.READ_EXTERNAL_STORAGE(Android 10以下)或android.permission.READ_MEDIA_IMAGES(Android 11+) - iOS侧:除了勾选
CAMERA,还必须在manifest.json → iOS设置 → 使用权限描述里填满NSCameraUsageDescription,文案不能是“用于拍照”这种模糊表述 - 真机调试时首次调用前,务必先执行
uni.authorize({scope: 'scope.camera'}),否则iOS会静默拒绝 - 注意:HBuilderX 3.6.11+版本把相机和相册拆成独立模块,如果用了
uni.chooseImage,还要额外勾选Album模块
uni.saveFileToDisk() 失败?存储权限不是勾一个就够了
Android存储权限从10开始彻底重构,WRITE_EXTERNAL_STORAGE 在targetSdkVersion ≥ 29后基本失效。直接勾这个权限,真机上大概率写入失败,且App Store审核会拒。
- Android 10+(targetSdkVersion ≥ 29):优先用
android.permission.READ_MEDIA_IMAGES+android.permission.READ_MEDIA_VIDEO替代旧存储权限 - 若必须访问公共目录(如DCIM),需启用
requestLegacyExternalStorage(仅临时兼容,不推荐长期使用) - iOS没有“存储权限”概念,但
NSPhotoLibraryUsageDescription必须填写,否则uni.saveImageToPhotosAlbum直接报错 - uni-app中保存文件到相册,实际走的是原生相册API,所以即使你只存图片,也要确保
Album模块已勾选
最常被忽略的一点:HBuilderX的“App模块权限配置”界面只是生成配置的入口,它不会自动帮你补全iOS的Info.plist字段或注入Android的targetSdkVersion适配逻辑。每次云打包前,务必手动核对manifest.json里Android和iOS两栏的配置是否都填满、文案是否合规、模块是否勾全——少一个字段,真机就少一个功能。


















