离线消息无法通过uni-app的plus.push.receive监听,必须在原生层处理:ios需在appdelegate.m实现didreceiveremotenotification回调,android需在自定义receiver或厂商sdk中解析badge并通知js;角标显示依赖正确配置badgeclass(含完整包名的launcher activity)、厂商sdk初始化、权限声明及服务端payload中的badge字段。

离线消息不走 receive,那怎么监听?
uni-app 的 plus.push.addEventListener('receive', ...) 只在 App 前台或后台(未被系统杀掉)时触发。一旦 App 被用户划掉、系统回收,或冷启动前收到推送,receive 事件根本不会执行 —— 这不是 bug,是 iOS/Android 系统级限制。
真正能捕获离线消息的入口,只有原生层的推送回调:
- iOS:必须在
AppDelegate.m中实现application:didReceiveRemoteNotification:fetchCompletionHandler:,并在里面手动调用application.applicationIconBadgeNumber = badgeValue - Android:需在自定义
PushReceiver或厂商 SDK 的回调里解析badge字段(如华为 HMS 的getBadgeNumber()),再通过plus.bridge通知 JS 层 - 不能依赖
plus.push的 JS 事件监听离线态消息 —— 它压根收不到
badgeClass 配置错,角标就永远不显示
Android 厂商角标不是“设个数字就行”,而是要告诉系统:“把数字写到哪个 Activity 的图标上”。badgeClass 就是这个 Activity 的完整类名。填错等于地址写错,系统找不到目标,角标自然空白。
常见错误配置:
- 直接写
"io.dcloud.PandoraEntry"—— 这是 HBuilderX 默认模板路径,但如果你用的是自定义 SplashActivity 或修改过启动页,它就失效 - 写成
"PandoraEntry"(缺包名)或"io.dcloud.MainActivity"(不存在的类) - 华为设备还要求额外配置
com.huawei.hms.push.ENABLE_BADGE元数据,否则即使badgeClass正确也不生效
正确做法:反编译 APK,用 apktool d yourapp.apk 查 AndroidManifest.xml 中 android:name=".xxxActivity" 且带 LAUNCHER 的那个,拼上包名(如 com.yourcompany.app.MainActivity)
华为设备角标数字不更新?检查这三件事
华为是角标兼容性最“讲究”的厂商,光配对 badgeClass 不够:
- manifest.json 中必须开启华为推送:
"huawei": { "push": { "appid": "你的AppID" } },且agconnect-services.json已放在项目根目录 - Android 权限声明里必须含
android.permission.CHANGE_BADGE,且运行时申请(plus.android.requestPermissions) - 调用
plus.push.setBadge前,先确认是否已初始化 HMS Push SDK:if (plus.runtime.getProperty('hmsPush')) { plus.push.setBadge(...) },否则静默失败
角标数字和实际未读数对不上,别只改 JS
很多人在 JS 层反复调用 plus.push.setBadge(n),但发现桌面角标没变,或者变完又归零。问题往往不在 JS:
- iOS:角标由 APNs payload 中的
badge字段决定,服务端发推送时必须带上{"aps":{"badge":5}},前端 setBadge 只影响当前会话,无法覆盖系统级角标 - Android:小米/OPPO 等依赖通知渠道的
setShowBadge(true),如果渠道创建时没开 badge,后续 setBadge 无效 - 更隐蔽的问题:某些厂商(如 vivo)要求角标数字必须随每条通知递增,不能随意设值,否则被忽略
最终角标显示是服务端 payload、原生 SDK 初始化、厂商通道权限、系统通知渠道四者共同作用的结果,单点调试容易漏掉关键链路。











