查看: 99|回复: 0

鸿蒙uni-app x uni-push推送开发与避坑指南

[复制链接]
发表于 半小时前 | 显示全部楼层 |阅读模式
推送通知是 App 标配。uni-push 是 DCloud 与个推合作的统一推送服务,聚合华为、小米、OPPO、VIVO、魅族、荣耀、Google 等厂商的推送通道。鸿蒙平台从 uni-push 4.61 开始支持。鸿蒙推送走华为 HMS Push 通道,在 UniPush 2.0 后台配置时需要开通华为厂商通道。需要注意,鸿蒙推送机制与 Android 不完全相同,Android 的通知渠道管理 getPushChannelManager 在鸿蒙不支持。

一、鸿蒙平台核心 API 支持情况
在鸿蒙平台,uni-push 4.61 起支持:
1. getPushClientId:获取客户端唯一推送标识 cid,上报服务端用于指定目标设备。
2. onPushMessage:监听推送消息,type 为 receive 表示收到推送,click 表示用户点击系统通知栏消息启动应用。
3. offPushMessage:移除推送监听。
4. createPushMessage:创建本地通知,不依赖服务端。
5. setAppBadgeNumber:设置或清除应用角标。
6. getPushChannelManager:不支持,这是 Android 专属 API;鸿蒙有自己的通知管理机制,不需要手动创建通知渠道。

二、基础调用
获取 cid:
  1. uni.getPushClientId({
  2.   success: (res) => {
  3.     console.log('推送标识:', res.cid)
  4.   },
  5.   fail: (err) => {
  6.     console.log('获取推送标识失败:', err)
  7.   }
  8. })
复制代码

监听与移除:
  1. uni.onPushMessage((res) => {
  2.   if (res.type == 'receive') {
  3.     console.log('收到推送消息:', res.data)
  4.   } else if (res.type == 'click') {
  5.     console.log('用户点击了推送消息:', res.data)
  6.   }
  7. })
  8. uni.offPushMessage(callback)
复制代码
如果多次监听 onPushMessage,事件会多次触发,不需要时要用 offPushMessage 移除。

创建本地通知:
  1. uni.createPushMessage({
  2.   title: '新消息',
  3.   content: '你有一条新的订单消息',
  4.   payload: { orderId: '12345' },
  5.   sound: 'system',
  6.   cover: false,
  7.   delay: 0
  8. })
复制代码

设置角标:
  1. uni.setAppBadgeNumber(5)
复制代码
传 0 表示清除角标。

三、鸿蒙平台重点避坑
1. content 必填。Android 和 iOS 上 title、content 都可以不填或有默认值,但鸿蒙平台 createPushMessage 的 content 是必填。错误写法:
  1. uni.createPushMessage({
  2.   title: '通知'
  3.   // 缺少 content,鸿蒙会报错
  4. })
复制代码
正确写法:
  1. uni.createPushMessage({
  2.   title: '通知',
  3.   content: '通知内容'
  4. })
复制代码

2. getPushChannelManager 不可用。它是 Android 专属 API,鸿蒙平台不支持,调用会返回 null 或不支持。鸿蒙不需要手动创建通知渠道。

3. 角标显示受设备规则影响。setAppBadgeNumber 在鸿蒙支持,但不同设备角标显示规则可能不同,有些设备还需要在应用通知管理里开启“桌面角标”配置才会生效。

4. 推送通道配置。鸿蒙推送走华为 HMS Push,UniPush 2.0 后台需要开通华为厂商通道。客户端拿到 cid 后要上报到服务端,服务端推送时用 cid 指定目标设备。如果服务端使用 uniCloud,原文提到可结合 uni-cloud-push 云端配合方案,具体以官方文档为准。

四、实战场景
1. 启动时获取 cid 并上报:
  1. const initPush = () => {
  2.   uni.getPushClientId({
  3.     success: (res) => {
  4.       uni.request({
  5.         url: 'https://your-server.com/api/report-cid',
  6.         method: 'POST',
  7.         data: {
  8.           cid: res.cid,
  9.           platform: 'harmony'
  10.         },
  11.         success: () => {
  12.           console.log('cid 上报成功')
  13.         },
  14.         fail: (err) => {
  15.           console.log('cid 上报失败:', err)
  16.         }
  17.       })
  18.     },
  19.     fail: (err) => {
  20.       console.log('获取推送标识失败:', err)
  21.     }
  22.   })
  23. }
复制代码

2. 监听 receive 和 click,点击后按 payload 跳转:
  1. const setupPushListener = () => {
  2.   uni.onPushMessage((res) => {
  3.     if (res.type == 'receive') {
  4.       console.log('收到推送:', res.data)
  5.       uni.showToast({
  6.         title: '收到新消息',
  7.         icon: 'none'
  8.       })
  9.     } else if (res.type == 'click') {
  10.       const data = res.data as UTSJSONObject
  11.       const page = data['page'] as string
  12.       if (page != null) {
  13.         uni.navigateTo({
  14.           url: page
  15.         })
  16.       }
  17.     }
  18.   })
  19. }
复制代码

3. 本地通知、延迟通知、覆盖旧通知、静默通知:
  1. uni.createPushMessage({
  2.   title: '订单提醒',
  3.   content: '您的订单已发货,请注意查收',
  4.   payload: {
  5.     orderId: '12345',
  6.     type: 'order'
  7.   },
  8.   sound: 'system',
  9.   cover: false
  10. })
  11. uni.createPushMessage({
  12.   title: '活动提醒',
  13.   content: '您关注的商品即将开始限时特惠',
  14.   delay: 60,
  15.   payload: {
  16.     activityId: 'activity_001'
  17.   }
  18. })
  19. const createCoverNotification = (content: string) => {
  20.   uni.createPushMessage({
  21.     title: '新消息',
  22.     content: content,
  23.     cover: true,
  24.     payload: {
  25.       type: 'message'
  26.     }
  27.   })
  28. }
  29. uni.createPushMessage({
  30.   title: '后台同步',
  31.   content: '数据同步完成',
  32.   sound: 'none',
  33.   payload: {
  34.     type: 'sync'
  35.   }
  36. })
复制代码

4. 角标更新与清除:
  1. const updateBadge = (count: number) => {
  2.   uni.setAppBadgeNumber(count, {
  3.     title: '新消息',
  4.     content: '您有' + count + '条未读消息'
  5.   })
  6. }
  7. const clearBadge = () => {
  8.   uni.setAppBadgeNumber(0)
  9. }
复制代码

五、页面级监听管理
实际页面中,建议用变量保存回调,开始监听时 onPushMessage,停止或页面卸载时 offPushMessage,避免重复监听。核心逻辑可参考:
  1. let pushCallback: ((res: OnPushMessageCallbackResult) => void) | null = null
  2. const startListening = () => {
  3.   pushCallback = (res: OnPushMessageCallbackResult) => {
  4.     if (res.type == 'receive') {
  5.       // 处理收到消息
  6.     } else if (res.type == 'click') {
  7.       // 处理点击跳转
  8.     }
  9.   }
  10.   uni.onPushMessage(pushCallback)
  11. }
  12. const stopListening = () => {
  13.   if (pushCallback != null) {
  14.     uni.offPushMessage(pushCallback)
  15.     pushCallback = null
  16.   }
  17. }
  18. onUnload(() => {
  19.   stopListening()
  20. })
复制代码

六、与鸿蒙原生推送的差异
鸿蒙原生开发中,推送对接需要使用 @kit.PushKit,例如通过 pushService.getToken() 获取 token,并处理 Push Kit 回调:
  1. import { pushService } from '@kit.PushKit'
  2. pushService.getToken().then((token) => {
  3.   console.log('推送 token:', token)
  4. })
复制代码
相比之下,uni-app x 的 uni-push 把 cid 获取、消息监听和厂商通道聚合封装起来,鸿蒙走 HMS Push,少处理不少原生 SDK 差异。对于已经使用 uni-app x 的项目,可以优先用 uni-push 完成推送能力接入;如果要做深度系统集成或特殊通知能力,再评估原生方案。

总结
鸿蒙平台接入 uni-push 的关键点有三个:版本从 uni-push 4.61 起支持;createPushMessage 的 content 必填;getPushChannelManager 不可用。落地时先获取 cid 并上报服务端,再监听 receive/click 处理业务跳转,本地通知、延迟、覆盖、静默和角标按需组合。配置侧记得在 UniPush 2.0 后台开通华为厂商通道,角标不显示时检查设备通知管理中的“桌面角标”开关。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-29 09:52 , Processed in 0.019471 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部