iOS用uni.getPushPermission查state是否为"authorized",Android 13+需uni.authorize('scope.notification')动态申请,均须真机验证并按平台跳转设置页。

uni-app 中如何检测 App 端通知权限状态
iOS 和 Android 对通知权限的判断逻辑完全不同,uni.getSystemInfoSync().platform 返回 "ios" 或 "android" 后必须分路径处理。iOS 可直接用 uni.getPushPermission 获取完整状态;Android 从 Android 13(API 33)起需单独申请 POST_NOTIFICATIONS 权限,且 uni.getPushPermission 在旧版 Android 上始终返回 granted(假阳性),不可信。
实操建议:
- iOS:直接调用
uni.getPushPermission,检查返回对象中state字段是否为"authorized"(注意不是"granted") - Android:优先用
uni.getSystemInfoSync().SDKVersion判断是否 ≥ "33",是则调用uni.authorize({scope: 'scope.notification'})并捕获fail;否则默认视为已授权(但实际可能被系统关闭,需结合后续发送测试) - 避免只依赖
uni.getPushPermission的返回值做 UI 判断,尤其在 Android 12 及以下
跳转到系统设置页引导用户开启通知
uni-app 没有统一 API 跳转通知设置页,必须按平台写条件分支。iOS 使用 plus.ios.invoke(plus.ios.mainApplication(), 'openURL:', 'app-settings:') ;Android 需拼接包名跳转到应用详情页,再由用户手动点进通知设置——不能直接跳转到「通知开关」二级页。
关键细节:
- iOS:必须用
plus.ios原生桥接,uni.openSetting在 iOS App 端无效 - Android:
uni.openSetting在 App 端也无效,必须用plus.android.invokeXXX调用原生方法,目标 Intent Action 为"android.settings.APPLICATION_DETAILS_SETTINGS",data Uri 格式为"package:你的appid" - AppID 必须与
manifest.json中的packagename严格一致(Android)或id(iOS),大小写敏感 - 跳转前建议先
plus.runtime.restart()确保环境就绪(尤其热更新后)
Android 13+ POST_NOTIFICATIONS 权限的实际处理逻辑
即使用户已在设置中打开通知,若 App 未动态申请 POST_NOTIFICATIONS,uni.showNotification 仍会静默失败,且无错误提示。这个权限必须在首次需要发通知前主动申请,不能等 getPushPermission 返回 denied 再申请。
正确做法:
- App 启动后、用户登录完成时,立即调用
uni.authorize({scope: 'scope.notification'}) -
fail回调中判断err.errMsg是否含"auth deny"或"not authorized",是则弹窗引导跳转设置页 - 成功回调中仍需调用一次
uni.getPushPermission确认最终状态,因部分厂商 ROM 会在授权后延迟同步状态 - 不要在
onLaunch中阻塞等待该授权,避免白屏;用setTimeout延迟 300ms 再触发更稳妥
真机调试时最容易忽略的三个坑
模拟器无法测试通知权限,所有验证必须在真机上进行。常见掉坑点:
- iOS 打包时未勾选
PushCapability(Xcode 中),导致getPushPermission直接报错或返回空对象 - Android 调试用的 debug 包签名与正式包不一致,跳转设置页时系统找不到对应应用(表现为页面闪退或停留在桌面)
- 用户拒绝权限后,再次调用
uni.authorize不会弹窗,必须先跳转设置页手动开启——这点和微信小程序不同,容易误以为 API 失效
权限状态不是一劳永逸的,系统设置、厂商限制、App 更新都可能重置它。每次发重要通知前,最好重新校验一次,而不是仅依赖启动时的缓存结果。


















