OpenHarmony 通知消息 Notification 完整开发(API Version23 + 适配版) 摘要Notification 通知模块用于在系统状态栏弹出消息提醒包含普通文本通知、多行详情通知、大图片横幅通知、常驻后台通知适用于消息推送、定时提醒、任务进度、离线消息等场景。API Version23 重构通知渠道管理、权限校验、通知生命周期、点击跳转 Want 逻辑修复低版本通知无法弹出、点击无响应、重复推送、后台进程通知消失、渠道删除残留等兼容缺陷。旧项目升级 API23 后常出现发送通知无任何状态栏提示、点击通知无法跳转页面、退出应用通知自动清除、多次推送产生大量重复通知、无通知权限直接报错闪退等问题。本文基于 DevEco Studio 适配 OpenHarmony API23 及以上版本封装全局通知工具类实现普通文本通知、大图通知、常驻通知、通知点击路由跳转四大核心能力搭配消息提醒、后台定时任务两套实战页面提供完整可运行代码输出通知权限、渠道创建、资源销毁规范汇总版本升级兼容故障解决方案为鸿蒙消息提醒功能开发提供标准化实操模板。关键词OpenHarmonyArkUIAPI Version23Notification系统通知消息推送通知渠道通知点击跳转一、引言1.1 通知开发背景聊天消息、日程提醒、下载进度、离线推送都依赖系统通知能力通知独立于应用页面锁屏、应用切后台状态下仍可展示在状态栏。系统对通知实行渠道分组管理同类型消息共用一个渠道用户可在系统设置单独关闭某一类通知。 OpenHarmony API Version23 针对 Notification 底层调度引擎完成全面升级核心变更点强制所有通知必须先创建 NotificationChannel 渠道无渠道发送直接失败重构通知动态权限校验逻辑未授予通知权限拦截推送并友好提示标准化点击通知 Want 跳转规则区分打开页面、跳转 Ability优化通知缓存队列限制同一渠道短时间重复推送频率避免刷屏新增常驻通知ONGOING生命周期管控退出应用不会自动移除修复通知 ID 复用覆盖原有通知、渠道删除后无法重建的 bug。大量 API9~11 旧项目升级后调用推送接口状态栏无消息根源是缺少渠道创建逻辑、未申请通知动态权限因此掌握 API23 标准通知封装规范是消息提醒类功能必备技能。1.2 开发环境与测试场景开发工具DevEco Studio 5.0 及以上 适配系统OpenHarmony API Version23、HarmonyOS NEXT 导入模块ohos.notification、ohos.notificationManager 前置权限动态通知权限 ohos.permission.NOTIFICATION_AGENT 测试场景普通文字消息通知、大图预览通知、常驻后台提醒、点击通知跳转指定页面、清除全部通知、删除单条通知二、API23 Notification 通知核心 API 与版本变更说明2.1 核心模块导入etsimport notificationManager from ohos.notificationManager import notification from ohos.notification2.2 通知渠道创建API23 强制前置ets// 创建渠道配置 const channel: notification.NotificationChannel { id: msg_channel, name: 消息通知, description: 应用普通消息提醒, importance: notification.NotificationImportance.LEVEL_3 } await notificationManager.createChannel(channel)importance 优先级等级LEVEL_0无提醒静默存储LEVEL_3状态栏展示 提示音常规消息推荐LEVEL_4横幅弹窗强提醒2.3 通知基础推送结构NotificationRequest通知载体包含 id、渠道 ID、内容、点击跳转 wantNotificationContent通知内容支持普通文本、大图、多行文本Want点击通知后跳转页面路由参数2.4 常用控制 APInotificationManager.publish (request)推送通知notificationManager.cancel (id)根据 ID 删除单条通知notificationManager.cancelAll ()清空本应用全部通知notificationManager.getChannels ()获取已创建渠道列表2.5 API23 废弃与强制约束废弃无渠道直接推送通知必须提前创建对应 channel通知属于动态敏感权限页面调用前必须申请 NOTIFICATION_AGENT相同 channel 相同 id 会覆盖旧通知不同 id 生成多条独立消息常驻 ONGOING 通知无法被用户手动清除仅代码可 cancel后台无进程状态下部分设备限制普通通知推送常驻通知不受限。三、API23 标准基础示例代码3.1 创建通知渠道 普通文本通知推送etsimport notificationManager from ohos.notificationManager import notification from ohos.notification import Want from ohos.app.ability.Want import router from ohos.router async function createMsgChannel() { const channel: notification.NotificationChannel { id: msg_default, name: 通用消息, description: 应用各类消息推送提醒, importance: notification.NotificationImportance.LEVEL_3 } await notificationManager.createChannel(channel) } async function sendSimpleNotify(id: number, title: string, content: string) { await createMsgChannel() // 点击跳转首页Want let want: Want { bundleName: getContext(this).bundleName, abilityName: EntryAbility, uri: pages/index/index } const notifyRequest: notification.NotificationRequest { id: id, channelId: msg_default, content: { contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title: title, text: content } }, want: want } await notificationManager.publish(notifyRequest) }3.2 清除指定 ID 通知etsasync function cancelSingleNotify(notifyId: number) { await notificationManager.cancel(notifyId) } async function clearAllNotify() { await notificationManager.cancelAll() }四、两大业务完整实战案例全兼容 API234.1 实战一全局通知工具类封装utils/notify_util.etsetsimport notificationManager from ohos.notificationManager import notification from ohos.notification import Want from ohos.app.ability.Want import common from ohos.app.ability.common import promptAction from ohos.promptAction import PermissionUtil, { PERMISSION } from ./permission_util // 通知渠道常量统一管理 export const NOTIFY_CHANNEL { MSG: channel_msg, TASK: channel_task } class NotifyUtil { private static instance: NotifyUtil private ctx: common.UIAbilityContext | null null static getInstance(): NotifyUtil { if (!NotifyUtil.instance) { NotifyUtil.instance new NotifyUtil() } return NotifyUtil.instance } setContext(context: common.UIAbilityContext) { this.ctx context } // 初始化消息通知渠道 private async createMsgChannel() { const channel: notification.NotificationChannel { id: NOTIFY_CHANNEL.MSG, name: 消息通知, description: 聊天、资讯类消息提醒, importance: notification.NotificationImportance.LEVEL_3 } await notificationManager.createChannel(channel) } // 初始化后台任务常驻渠道 private async createTaskChannel() { const channel: notification.NotificationChannel { id: NOTIFY_CHANNEL.TASK, name: 后台任务, description: 下载、同步常驻提醒, importance: notification.NotificationImportance.LEVEL_2 } await notificationManager.createChannel(channel) } // 推送普通文本通知 async sendBasicNotify(notifyId: number, title: string, text: string, pageUrl: string) { if (!this.ctx) return // 前置校验通知权限 const hasPerm PermissionUtil.checkSingle(ohos.permission.NOTIFICATION_AGENT) if (!hasPerm) { promptAction.showToast({ message: 未开启通知权限无法推送消息 }) return } await this.createMsgChannel() // 构建跳转Want const want: Want { bundleName: this.ctx.bundleName, abilityName: EntryAbility, uri: pageUrl } const request: notification.NotificationRequest { id: notifyId, channelId: NOTIFY_CHANNEL.MSG, content: { contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title, text } }, want: want } try { await notificationManager.publish(request) promptAction.showToast({ message: 通知已发送至状态栏 }) } catch (err) { promptAction.showToast({ message: 通知推送失败 }) console.error(推送通知异常, err) } } // 推送常驻后台通知无法手动清除 async sendOngoingTaskNotify(notifyId: number, title: string, text: string) { if (!this.ctx) return const hasPerm PermissionUtil.checkSingle(ohos.permission.NOTIFICATION_AGENT) if (!hasPerm) return await this.createTaskChannel() const request: notification.NotificationRequest { id: notifyId, channelId: NOTIFY_CHANNEL.TASK, content: { contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title, text } }, ongoing: true // 标记为常驻通知 } await notificationManager.publish(request) } // 删除单条通知 async cancelNotify(notifyId: number) { await notificationManager.cancel(notifyId) promptAction.showToast({ message: 已移除该条通知 }) } // 清空全部通知 async clearAll() { await notificationManager.cancelAll() promptAction.showToast({ message: 已清空所有通知 }) } } export default NotifyUtil.getInstance()4.2 实战二通知推送演示页面普通通知 常驻任务通知etsimport NotifyUtil from ../utils/notify_util import PermissionUtil from ../utils/permission_util Entry Component struct NotificationPage { notifyId: number 1001 taskNotifyId: number 9001 aboutToAppear() { // 绑定页面上下文 const ctx getContext(this) NotifyUtil.setContext(ctx) PermissionUtil.setContext(ctx) } // 发送普通资讯通知点击跳转首页 async sendMsgNotify() { await NotifyUtil.sendBasicNotify( this.notifyId, 新资讯推送, 今日鸿蒙技术更新点击查看详情, pages/index/index ) } // 发送常驻后台同步通知 async sendSyncTaskNotify() { await NotifyUtil.sendOngoingTaskNotify( this.taskNotifyId, 文件同步中, 后台正在同步本地笔记数据 ) } // 清除常驻任务通知 async removeTaskNotify() { await NotifyUtil.cancelNotify(this.taskNotifyId) } // 清空全部通知 async clearAllNotify() { await NotifyUtil.clearAll() } build() { Column({ space: 20 }) { Text(系统通知Notification演示) .fontSize(22) .fontWeight(FontWeight.Bold) .margin({ bottom: 10 }) Button(推送普通资讯通知) .width(300) .height(46) .backgroundColor(#007DFF) .onClick(async () await this.sendMsgNotify()) Button(推送常驻后台同步通知) .width(300) .height(46) .backgroundColor(#009966) .onClick(async () await this.sendSyncTaskNotify()) Button(移除常驻同步通知) .width(300) .height(46) .backgroundColor(#ff9500) .onClick(async () await this.removeTaskNotify()) Button(清空全部应用通知) .width(300) .height(46) .backgroundColor(#f56c6c) .onClick(async () await this.clearAllNotify()) } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) .padding(20) .backgroundColor(#F5F5F5) } }五、API23 通知适配与性能优化规范5.1 渠道管理规范按业务类型拆分渠道消息、后台任务、活动推送分开创建页面推送前自动检测并创建渠道无需手动提前执行同一渠道相同 ID 通知会覆盖不同 ID 独立多条展示。5.2 权限交互规范推送通知前校验 NOTIFICATION_AGENT 动态权限无权限阻断推送并提示应用首次使用通知功能主动申请权限不静默失败用户永久拒绝权限时提示前往系统设置开启通知。5.3 常驻通知业务规范下载、同步、录音等后台服务使用 ongoing 常驻通知常驻通知用户无法手动清除业务完成必须代码调用 cancel 删除普通聊天、资讯消息不使用常驻类型允许用户上滑清除。5.4 跳转 Want 规范Want 必须填写当前应用 bundleName 与 EntryAbilityuri 填写目标页面路由地址点击通知自动跳转对应业务页面需要携带参数可在 want.parameters 中追加自定义键值。六、API23 升级高频兼容问题与解决方案问题 1调用推送接口状态栏完全不显示通知 解决1. 创建对应 NotificationChannel 渠道2. 授予 NOTIFICATION_AGENT 通知权限3. 渠道 importance 等级≥LEVEL_2。问题 2多次推送通知只会显示一条新消息覆盖旧消息 解决每次推送使用不同 notifyId相同 ID 会覆盖同渠道旧通知。问题 3点击通知无任何页面跳转 解决完整配置 want 的 bundleName、abilityName、uri 页面路由。问题 4退出应用后常驻通知自动消失 解决推送时设置 ongoing:true 标记为后台常驻通知。问题 5升级 API23 旧代码直接推送报错 解决全部补充渠道创建逻辑API9 及以下无强制渠道要求API23 必须创建。问题 6短时间连续推送多条通知系统拦截不展示 解决拆分不同 channel 或增加推送间隔避免高频刷屏触发系统限流。七、总结Notification 系统通知是鸿蒙应用消息提醒标准实现方案API Version23 强制引入通知渠道前置创建、动态权限校验机制统一通知内容、点击跳转、常驻任务的标准化配置彻底解决旧版无消息、点击失效、通知丢失等核心兼容问题。项目封装全局通知工具类拆分消息、任务双渠道提供普通通知、常驻后台通知、清除通知全套方法搭配权限前置校验适配资讯推送、后台同步、日程提醒等主流业务场景。