uni.getpushpermission在ios和android上不可互换:ios直接返回state==="authorized"才有效;android 12及以下始终返回"granted"(假阳性),android 13+需用uni.authorize({scope:'scope.notification'})动态申请并捕获fail判断。

uni.getPushPermission 在 iOS 和 Android 上返回值完全不可互换
iOS 调用 uni.getPushPermission 可直接拿到完整状态对象,state 字段为 "authorized" 才算真正可用;Android 12 及以下版本该 API 始终返回 "granted"(假阳性),根本不能信。Android 13(SDKVersion ≥ "33")起必须改用 uni.authorize({scope: 'scope.notification'}) 动态申请并捕获 fail 回调——不是查,是试。
常见错误现象:
– 在 Android 12 设备上显示“已开启通知”,实际系统设置里关着,发不出推送
– 仅依赖 uni.getPushPermission 返回值控制 UI 开关,导致 Android 用户误以为功能正常
- 先用
uni.getSystemInfoSync().SDKVersion判断是否 ≥"33",再分路径处理 - iOS 直接走
uni.getPushPermission,检查state === "authorized" - Android ≥33 必须触发一次
uni.authorize,fail中判断err.errMsg是否含"auth deny"或"not authorized" - Android
uni.authorize('scope.userLocation') 不能代替设备定位开关检测
uni.authorize('scope.userLocation') 只管 App 层权限,不管系统级定位总开关。用户可能已授予权限,但手机「设置 → 定位服务」全局关闭,此时 uni.getLocation 仍会失败。
使用场景:
– 启动页或登录后立即检测,避免用户操作到关键步骤才报错
– 需配合 uni.getSetting + plus.android.checkPermission(Android)或 plus.ios.importClass(iOS)做兜底
- 先调
uni.getSetting查authSetting['scope.userLocation'],为false或undefined说明未授权 - 若已授权,再调
uni.getLocation测试是否真能获取坐标;失败则大概率是系统定位总开关关闭 - Android 可用
plus.android.checkPermission('android.permission.ACCESS_FINE_LOCATION')补充验证 - iOS 无等效原生接口,只能靠
uni.getLocation实际调用试探,失败后弹窗提示“请检查系统定位服务是否开启”
manifest.json 权限声明不全,云打包或真机运行必报错
权限相关功能在 iOS 云打包阶段就会卡住,报错如 "NSLocationWhenInUseUsageDescription is missing" 或 "No permission description for scope.notification",不是代码问题,是配置缺失。
配置差异:
– iOS 需在 manifest.json 的 plus.distribute.apple.plist 中逐条声明描述文案
– Android 需在 plus.modules 下的 Maps 或自定义模块中声明 ACCESS_FINE_LOCATION 等权限 ID
– 微信小程序还需额外在 mp-weixin.requiredPrivateInfos 声明接口
- iOS 通知权限必须配
{"key":"UIBackgroundModes","array":["remote-notification"]}和{"key":"NSUserNotificationAlertStyle","string":"alert"} - 定位权限 iOS 至少要
NSLocationWhenInUseUsageDescription,需要后台持续定位还得加NSLocationAlwaysUsageDescription - Android 定位权限必须同时声明
ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION,否则部分机型(尤其华为、小米)拒绝授予 - 所有描述文案必须是中文,且不能为空字符串或纯空格
uni.openSetting() 在不同平台跳转目标完全不同
uni.openSetting() 在 iOS 和 Android 上打开的不是同一类页面:iOS 打开的是本 App 的权限子页,Android 打开的是系统级应用详情页——这意味着你无法靠它直接跳转到“通知开关”或“定位总开关”。
容易踩的坑:
– Android 用户点开设置页后找不到通知开关,因为入口藏在「通知管理 → 你的App名称」里
– iOS 用户在设置页里看不到「始终允许」选项,是因为首次授权没选“始终允许”,后续再调 uni.authorize 会直接 fail
- iOS 若需引导用户开启后台定位,必须提前在 manifest 中配好
NSLocationAlwaysUsageDescription,并在首次调用uni.authorize时指定scope: 'scope.locationAlways' - Android 没有统一 API 跳转到通知开关页,只能跳转到应用详情页,再由用户手动点进「通知」分类
- 不要假设
uni.openSetting()能解决所有问题,它只是起点;后续必须配合截图指引或文字说明(例如:“请找到「通知」→ 开启‘允许通知’”) - 测试时务必用真机,模拟器无法触发真实权限弹窗和设置页跳转
uni.getLocation 看是否真能返回坐标。











