uni.getSetting 必须在 uni.getLocation 前调用,否则 Android 端权限静默失败;App 中 uni.authorize 无效,仅小程序可用;检测到拒绝后需用 uni.showModal 引导用户跳转 uni.openSetting;manifest.json 中 storage 权限须设为 "once" 并配具体 prompt。

uni.getSetting 必须在 uni.getLocation 前调用
直接调用 uni.getLocation 而不检查状态,是 Android 端权限静默失败的最常见原因。用户点过一次“拒绝”后,uni.getLocation 会直接进 fail 回调,不弹窗、无提示、也不报具体错误码——这不是 Bug,是系统行为。
正确做法是:每次需要定位前,先查状态:
-
res.authSetting['scope.userLocation'] === undefined:首次未询问,可安全调用uni.getLocation或uni.authorize -
=== true:已授权,直接用 -
=== false:已拒绝,此时再调uni.authorize无效,必须走引导逻辑
注意:华为/小米部分机型在 false 时就代表“永久拒绝”,不要幻想还能再弹一次窗。
uni.authorize 在 App 端基本没用
App(Android/iOS)环境下,uni.authorize 不触发系统弹窗,只返回 fail: { errMsg: "authorize:fail auth deny" }。它只在小程序平台有效,这点官方文档没写清楚,但实测如此。
所以别在 App 里写这种代码:
uni.getLocation({ fail: () => uni.authorize({ scope: 'scope.userLocation' }) })
它只会白忙活。App 端权限申请完全依赖 uni.getSetting + 用户主动操作,没有“重试授权”的中间态。
真正能用的只有两个动作:
- 检测到
undefined→ 调uni.getLocation(系统自动弹窗) - 检测到
false→ 弹uni.showModal说明用途,确认后调uni.openSetting
uni.openSetting 调用前必须做二次确认
uni.openSetting 会跳转到系统设置页,但华为应用市场明确禁止“因拒绝强制跳转”。审核被拒的高频原因就是:用户一拒,立刻无提示跳设置页。
必须加一层轻量交互:
- 用
uni.showModal明确告知用途,例如:“开启定位才能查看附近活动,要去设置页打开吗?” -
confirmText写“去设置”,cancelText写“稍后再说” - 仅在用户点击“去设置”后才调
uni.openSetting
另外,uni.openSetting 在 App 端返回的是完整设置页,无法监听用户是否真的开启了权限。所以跳转后,建议清空当前页面缓存或提示“返回后重试”。
manifest.json 的 storage 权限别设成 always
安卓存储权限(permissionExternalStorage)在 manifest.json 中配置为 "always" 是上架雷区。华为、vivo、小米等应用商店会直接拒审,理由是“过度索取权限”。
唯一合规写法是:
"permissionExternalStorage": { "request": "once", "prompt": "用于保存您拍摄的照片和下载的地图离线包" }
关键点:
-
"once"表示仅在首次启动时由系统统一申请,且不可重复触发 -
prompt字段必须具体、真实,不能写“用于APP功能”这类模糊文案 - 即使配了
"once",业务层仍要运行时检测:用户可能跳过弹窗,或厂商系统拦截,导致实际没拿到权限
最易忽略的一点:iOS 不走这个配置,App 端 iOS 的相册/相机权限仍需在 Info.plist 里单独声明,否则 uni.chooseImage 直接 crash。


















