鸿蒙新特性实战:通知管理 — notificationManager 发布/取消/多类型通知与权限管理
引言
通知是移动应用中连接用户与信息的桥梁。一条好的通知——在恰当的时机、以恰当的形式、携带恰当的信息量——可以显著提升用户活跃度和留存率。反之,通知权限被拒绝、通知内容不当、通知频率过高,则会让用户直接卸载应用。
HarmonyOS NEXT 提供了完整的通知管理 API——@ohos.notificationManager(Notification Kit),支持从权限检测、授权请求、通知发布、通知取消到多种内容类型的基础/长文本/多行/图片通知的统一管理。所有 API 均为异步操作(支持 Promise 和 callback 两种调用方式),完美集成在 ArkTS 开发流程中。
本文构建一个通知管理实验室 Demo,在页面内实现通知权限检测与请求、三种通知内容类型(基础文本/长文本/多行文本)的创建与发布、通知取消管理(按 ID 取消 / 全部取消)、操作日志追踪等功能,全面演示通知管理的完整工作流。
读完本文,你将掌握:
- 权限管理:
isNotificationEnabled()/requestEnableNotification()— 检测与请求通知权限 - 发布通知:
publish(NotificationRequest)— 构造通知请求体并发布 - 取消通知:
cancel(id)/cancelAll()— 按 ID 或全部清除通知 - 三种内容类型:
NOTIFICATION_CONTENT_BASIC_TEXT/LONG_TEXT/MULTILINE— 适配不同信息密度的场景 - NotificationContent 数据结构:每种类型对应的
normal/longText/multiLine字段 - 错误处理:Promise.catch() 模式捕获发布失败、权限拒绝等异常
一、notificationManager 体系总览
1.1 导入与模块结构
import { notificationManager } from '@kit.NotificationKit';
notificationManager 是一个全局单例对象,所有 API 通过它调用。在 API 24 + DevEco Studio 6.1.1 环境中,推荐使用 @kit.NotificationKit 导入路径。
1.2 核心 API 速查表
| API | 说明 | 返回值 | 权限要求 |
|---|---|---|---|
isNotificationEnabled() |
检查当前应用通知是否已启用 | Promise<boolean> |
无 |
requestEnableNotification() |
弹出系统对话框请求通知权限 | Promise<void> |
无 |
publish(request) |
发布一条通知 | Promise<void> |
无(基础通知) |
cancel(id) |
按 ID 取消指定通知 | Promise<void> |
无 |
cancelAll() |
取消当前应用所有通知 | Promise<void> |
无 |
setBadgeNumber(num) |
设置桌面角标数字 | Promise<void> |
无 |
isBadgeDisplayed() |
检查角标是否启用 | Promise<boolean> |
无 |
addSlot(slot) |
添加通知渠道 | Promise<void> |
无 |
getSlot(slotType) |
获取通知渠道配置 | Promise<NotificationSlot> |
无 |
核心发现:基本的发布/取消/权限操作全部无需声明任何权限,开箱即用。这是鸿蒙通知系统设计中非常友好的一个特点——Android 的通知权限管理相对复杂(需要 NotificationChannel + 运行时权限),而 HarmonyOS 将其大幅简化。
1.3 通知内容类型总览
HarmonyOS 支持四种通知内容类型:
| 内容类型 | 枚举值 | 对应字段 | 适用场景 |
|---|---|---|---|
| 基础文本 | NOTIFICATION_CONTENT_BASIC_TEXT |
normal |
即时通讯消息、系统提醒 |
| 长文本 | NOTIFICATION_CONTENT_LONG_TEXT |
longText |
邮件预览、详情摘要 |
| 多行文本 | NOTIFICATION_CONTENT_MULTILINE |
multiLine |
待办事项列表、消息汇总 |
| 图片通知 | NOTIFICATION_CONTENT_PICTURE |
picture |
截图分享、富媒体推送 |
每种类型对应 NotificationContent 中不同的数据字段,下文将逐一展开。
二、NotificationRequest — 通知请求体详解
NotificationRequest 是 publish() 方法的核心参数,它定义了一条通知的全部属性:
interface NotificationRequest {
id: number; // 通知 ID(同一应用内唯一,用于后续取消)
content: NotificationContent; // 通知内容(根据 contentType 选择不同字段)
deliveryTime?: number; // 定时发布时间戳(毫秒)
showDeliveryTime?: boolean; // 是否在通知栏显示发送时间
notificationSlotType?: notificationManager.SlotType; // 通知渠道类型
isFloatingIcon?: boolean; // 是否显示浮动图标
tapDismissed?: boolean; // 点击后是否自动消失
color?: number; // 通知颜色
badgeNumber?: number; // 角标数字(可覆盖全局角标)
}
关键字段说明:
- id:整数类型,同一应用中每条通知必须有唯一 ID。发布同 ID 的通知会覆盖之前的那条。
- content:
NotificationContent类型,是通知内容的核心载体,结构因notificationContentType而异。 - notificationSlotType:通知渠道类型(社交、服务提醒、内容资讯等),影响系统对通知的排序和展示策略。
- tapDismissed:设为
true时,用户点击通知后自动从通知栏消失。
三、NotificationContent — 四种内容类型详解
3.1 NOTIFICATION_CONTENT_BASIC_TEXT — 基础文本
最基本的通知类型,包含标题和正文:
let content: notificationManager.NotificationContent = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '会议提醒',
text: '14:00 在 3 号会议室进行项目评审',
additionalText: '还有 3 人未确认出席' // 可选补充信息
}
};
normal 对应的 NotificationBasicContent 接口:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
string |
是 | 通知标题 |
text |
string |
是 | 通知正文内容 |
additionalText |
string |
否 | 补充文本(显示在标题上方或下方) |
基础文本通知适合绝大多数场景:即时通讯消息、任务提醒、状态变更通知等。
3.2 NOTIFICATION_CONTENT_LONG_TEXT — 长文本
当通知正文很长时,使用长文本类型——系统在通知栏只显示摘要,用户展开后看到完整内容:
let content: notificationManager.NotificationContent = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT,
longText: {
title: '邮件预览',
text: '周报:本周进度正常,完成了核心模块开发', // 收起的摘要
briefText: '周报摘要', // 展开前的简洁描述
longText: '详细内容:本周完成了用户模块、订单模块的接口开发...(此处可放大量文字)'
}
};
longText 对应的 NotificationLongTextContent 接口:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
string |
是 | 通知标题 |
text |
string |
是 | 通知概要(收起状态显示) |
briefText |
string |
是 | 展开前的简短摘要 |
longText |
string |
是 | 完整长文本(展开后显示) |
使用场景:邮件摘要、新闻摘要、系统更新日志(ChangeLog)等需要携带较多信息的通知。
3.3 NOTIFICATION_CONTENT_MULTILINE — 多行文本
以列表形式展示多条信息,每条占一行:
let content: notificationManager.NotificationContent = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE,
multiLine: {
title: '今日待办',
text: '共 4 项待处理任务',
briefText: '点击查看详情',
lines: [
'代码评审:PR #234 — 需要你的 Review',
'Bug 修复:登录页偶发崩溃 — 优先级 P0',
'会议:16:00 周会 — 3 楼会议室',
'文档:更新 API 对接文档 — 本周五前'
]
}
};
multiLine 对应的 NotificationMultiLineContent 接口:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
string |
是 | 通知标题 |
text |
string |
是 | 概要描述 |
briefText |
string |
否 | 展开前的简短描述 |
lines |
Array<string> |
是 | 每行一条文本,在通知栏展开后逐行显示 |
注意:lines 数组的元素数量没有硬性上限,但建议控制在 5-8 条以内以保证可读性。
3.4 NOTIFICATION_CONTENT_PICTURE — 图片通知
附带大图的富媒体通知:
let content: notificationManager.NotificationContent = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_PICTURE,
picture: {
title: '截图已保存',
text: '截屏已保存到相册',
additionalText: '点击查看',
picture: pixelMap // image.PixelMap 对象
}
};
图片通知需要提供一个 image.PixelMap 对象,适用于截图分享、图片消息推送等场景。由于需要获取 PixelMap,这部分实现比文本通知复杂,本文 Demo 以三种文本类型为主,图片通知作为知识扩展。

四、权限管理 — 检测与授权
4.1 isNotificationEnabled() — 检测通知状态
notificationManager.isNotificationEnabled().then((enabled: boolean) => {
if (enabled) {
// 通知已启用,可以直接发布
} else {
// 通知未启用,需要引导用户开启
}
}).catch((err: Error) => {
console.error('检测失败: ' + err.message);
});
这个 API 返回一个 Promise<boolean>,true 表示用户已允许通知,false 表示用户关闭了通知或从未授权。
最佳实践:在应用首次启动或关键操作前调用此方法,根据结果决定 UI 展示(显示"开启通知"引导按钮或正常的通知功能入口)。
4.2 requestEnableNotification() — 请求授权
notificationManager.requestEnableNotification().then(() => {
// 用户同意了通知授权
}).catch((err: Error) => {
// 用户拒绝了授权
// 注意:用户拒绝后不会再次弹出系统对话框
// 需要引导用户前往系统设置手动开启
});
重要行为说明:
- 第一次调用:弹出系统级对话框,显示"允许"和"禁止"两个选项
- 用户拒绝后再次调用:不会弹出对话框(系统层面的防骚扰机制),直接进入 catch
- 用户已经允许后调用:直接进入 then,不弹窗
因此,如果用户拒绝了通知权限,唯一的恢复方式是引导用户前往系统设置手动开启。
五、发布与取消 — 通知的完整生命周期
5.1 publish() — 发布通知
let request: notificationManager.NotificationRequest = {
id: 100,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '新消息',
text: '你有一条来自张三的未读消息'
}
}
};
notificationManager.publish(request).then(() => {
console.log('通知发布成功');
}).catch((err: Error) => {
console.error('发布失败: ' + err.message);
});
发布注意事项:
- ID 管理:同一 ID 的通知后发会覆盖先发。应用中应维护一个递增计数器或使用时间戳来生成唯一 ID
- 立即生效:
publish()调用成功后,通知几乎立即出现在通知栏(无deliveryTime的情况下) - 通知栏限流:系统对短时间内大量发布有流控机制,批量通知场景需要控制频率
5.2 cancel() — 按 ID 取消
notificationManager.cancel(100).then(() => {
console.log('通知 #100 已取消');
});
关键点:只能取消当前应用发布的通知,不能取消其他应用的通知(这保证了系统安全)。
5.3 cancelAll() — 取消全部
notificationManager.cancelAll().then(() => {
console.log('所有通知已清除');
});
cancelAll() 会清除当前应用在通知栏的所有通知,无需逐个指定 ID。
典型使用场景:
- 用户退出登录时,清除所有与该账户相关的通知
- 应用启动时,清除旧会话的残留通知
- "一键已读"功能,取消所有通知并更新角标
5.4 错误处理模式
所有 notificationManager API 都返回 Promise,推荐使用统一的错误处理:
notificationManager.publish(request)
.then(() => {
// 成功
})
.catch((err: Error) => {
// 失败 — 常见原因:
// 1. 通知权限被拒绝
// 2. 通知 ID 非法(负数或 0)
// 3. content 必填字段缺失
console.error('通知操作失败: ' + err.message);
});
六、实战 Demo:通知管理实验室
页面结构
通知管理实验室
├── 标题栏 — "通知管理实验室" + "@ohos.notificationManager"
├── 通知状态卡片
│ ├── 通知启用状态指示器(绿色圆点 + "已启用"/红色圆点 + "未启用")
│ └── 请求通知权限按钮(仅在未启用时显示)
├── 发布通知卡片
│ ├── 通知类型选择器(水平滚动标签:基础文本/长文本/多行文本)
│ ├── 标题输入框
│ ├── 正文内容输入框
│ ├── 条件内容区(按类型动态切换)
│ │ ├── 基础文本:无额外字段
│ │ ├── 长文本:长文本正文输入框(多行 TextArea)
│ │ └── 多行文本:动态行列表(每行可编辑/可删除,可添加新行)
│ ├── 发布按钮
│ └── 已发布计数和下一个 ID 显示
├── 通知管理卡片
│ ├── 取消最近一条按钮
│ ├── 取消全部通知按钮
│ └── 重新检测状态链接
├── 操作日志卡片
│ └── 时间 + 操作类型(颜色区分)+ 详情,最多 30 条
├── 通知内容类型参考卡片(4 种类型说明)
└── 核心 API 参考 — 8 个关键 API
4 个交互点
- 通知权限检测与请求 — 页面启动时自动检测通知状态,未启用时显示"请求通知权限"按钮,点击后弹出系统授权对话框
- 三种通知类型切换发布 — 顶部标签栏切换基础文本/长文本/多行文本,每种类型显示对应的内容输入区,填写后点击"发布通知"将通知发送到系统通知栏
- 通知取消管理 — "取消最近一条"按 ID 精确取消,"取消全部通知"一键清除所有通知,发布计数实时更新
- 操作日志追踪 — 每次发布/取消/权限操作都会生成时间戳日志,日志以颜色区分操作类型(蓝色=发布,红色=取消,绿色=权限),最多保留 30 条
核心代码实现
权限检测
aboutToAppear(): void {
notificationManager.isNotificationEnabled().then((enabled: boolean) => {
this.notifyEnabled = enabled ? '已启用' : '未启用';
}).catch(() => {
this.notifyEnabled = '检测失败';
});
}
页面启动时自动检测,结果存入 @State notifyEnabled,UI 根据状态显示绿色/红色指示器和相应按钮。
按类型构造 NotificationContent
publishNotification(): void {
let id = this.nextId;
this.nextId++;
let content: notificationManager.NotificationContent = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: { title: this.notifTitle, text: this.notifText }
};
if (this.activeType === 1) {
content = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT,
longText: {
title: this.notifTitle,
text: this.notifText,
briefText: this.notifText,
longText: this.longText
}
};
} else if (this.activeType === 2) {
let lines = this.multilineLines.split('\n');
content = {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE,
multiLine: {
title: this.notifTitle,
text: this.notifText,
briefText: '共 ' + lines.length + ' 条信息',
lines: lines
}
};
}
let request: notificationManager.NotificationRequest = {
id: id,
content: content
};
notificationManager.publish(request).then(() => {
this.publishCount++;
this.addLog('发布', '#' + id + ' — ' + this.notifTitle);
}).catch((err: Error) => {
this.addLog('失败', '#' + id + ' 发布失败: ' + err.message);
});
}
核心逻辑:根据 activeType(0/1/2)选择对应的 notificationContentType 和内容字段,构造 NotificationContent,嵌入 NotificationRequest,调用 publish()。
动态多行编辑
多行文本的通知需要用户编辑多行内容,Demo 通过 split('\n') 将字符串转换为数组,再通过 ForEach 渲染每一行为独立的 TextInput:
ForEach(this.getLineArray(), (line: string, idx: number) => {
Row() {
TextInput({ text: line })
.fontSize(11)
.layoutWeight(1)
.height(34)
.onChange((v: string) => { this.updateLine(idx, v); })
Text('✕')
.fontColor('#EF4444')
.width(28)
.textAlign(TextAlign.Center)
.onClick(() => { this.deleteLine(idx); })
}
.width('100%')
.margin({ bottom: 4 })
})
addLine() 追加新行,deleteLine(index) 移除指定行(至少保留 1 行),updateLine(index, value) 更新指定行的内容。
操作日志追踪
addLog(action: string, detail: string): void {
let now = new Date();
let time = now.getHours().toString().padStart(2, '0') + ':' +
now.getMinutes().toString().padStart(2, '0') + ':' +
now.getSeconds().toString().padStart(2, '0');
let copy: NotifyLog[] = [];
for (let i = 0; i < this.logs.length; i++) {
copy.push(this.logs[i]);
}
copy.push(new NotifyLog(time, action, detail));
if (copy.length > 30) {
copy = copy.slice(copy.length - 30);
}
this.logs = copy;
}
日志数组的更新遵循 ArkTS 不可变状态更新模式:创建新数组 → 拷贝旧元素 → push 新条目 → slice 限长 → 赋值给 @State。
预览效果预期
- 状态检测:页面加载后通知状态栏显示绿色"已启用"或红色"未启用",未启用时出现蓝色授权按钮
- 基础文本通知:填写标题和内容后点击"发布通知",通知栏立即出现一条标准通知
- 长文本通知:切换到"长文本"标签,填写长文本正文后发布,通知在通知栏展开后显示完整内容
- 多行文本通知:切换到"多行文本"标签,动态添加/编辑/删除行,发布后通知栏显示多行列表
- 取消操作:点击"取消最近一条"移除最新发布的通知,"取消全部通知"清除所有
- 日志追踪:每次操作产生一条彩色日志,发布=蓝、取消=红、授权=绿
七、与 Android NotificationManager 的对比
| 维度 | HarmonyOS notificationManager | Android NotificationManager |
|---|---|---|
| 导入 | @kit.NotificationKit |
android.app.NotificationManager |
| 权限检测 | isNotificationEnabled() 返回 Promise |
areNotificationsEnabled() 同步返回 |
| 权限请求 | requestEnableNotification() 弹系统对话框 |
无直接 API,需跳转到设置页 |
| 通知渠道 | NotificationSlotType 枚举(简化) |
必须创建 NotificationChannel |
| 发布方式 | publish(NotificationRequest) Promise |
notify(id, notification) 同步 |
| 内容类型 | NotificationContent + 四种 contentType |
NotificationCompat.Builder + Style |
| Builder 模式 | 无 Builder,直接构造对象 | NotificationCompat.Builder 流式 API |
| 多行文本 | multiLine.lines: string[] |
NotificationCompat.InboxStyle |
HarmonyOS 的优势:
- 无需 Builder:直接构造对象,代码更简洁
- 权限请求内置:
requestEnableNotification()一键弹窗,Android 需要手动跳转设置 - 通知渠道简化:枚举值选择而非强制性创建,降低初学者的心智负担
Android 的优势:
- 通知渠道的精细控制(重要性等级、振动模式、LED 颜色等可逐渠道独立配置)
- 通知组的折叠展开控制更灵活
八、实战技巧与常见问题
8.1 通知 ID 管理策略
推荐的 ID 生成方式:
// 方式一:递增计数器
private nextId: number = Date.now(); // 用时间戳初始化避免与旧通知冲突
nextId++;
// 方式二:业务 ID 映射(如消息 ID)
let notificationId = message.messageId;
注意:使用较小的固定数字作为 ID 容易导致覆盖。建议使用 4 位以上的递增整数或业务相关 ID。
8.2 被拒绝后的用户引导
requestEnableNotification() 被拒绝后不会再次弹窗。此时应:
- 检测
isNotificationEnabled()返回false - 显示引导文字:“通知权限已被关闭,请前往系统设置 > 应用 > 通知管理中开启”
- 提供"去设置"按钮,通过
bundleManager.canOpenLink或openLink跳转到应用设置页
8.3 通知发布失败的常见原因
- 通知权限未开启 —
isNotificationEnabled()返回 false - 必填字段缺失 —
title或text为空字符串 - contentType 与内容字段不匹配 — 声明了 BASIC_TEXT 但赋值了
longText字段 - 通知 ID 非法 — 使用负数或 0 作为 ID
九、总结
@ohos.notificationManager 是 HarmonyOS 通知系统的统一入口,提供了一套简洁、Promise-first 的异步 API,覆盖了从权限管理到通知发布/取消的完整生命周期:
- 零权限起步:基础的通知发布/取消/检测无需任何权限声明,降低了接入门槛
- 四种内容类型:BASIC_TEXT / LONG_TEXT / MULTILINE / PICTURE 覆盖了从简单文本到富媒体的全场景
- Promise 驱动:所有 API 返回 Promise,天然适配 async/await 和链式处理
- 权限管理简单:
isNotificationEnabled()+requestEnableNotification()两步完成检测与授权 - 取消灵活:支持按 ID 精确取消和全部清除,满足消息撤回、已读管理等需求
- 数据结构清晰:
NotificationRequest→NotificationContent→ 类型对应的内容字段,层次分明
对于 HarmonyOS 开发者而言,Notification Kit 是应用与用户保持连接的基础设施。无论是即时通讯的消息推送、协作工具的任务提醒、还是电商应用的活动通知,这套 API 都提供了足够灵活和强大的支持。
结合实战 Demo 中的三种通知类型切换、多行动态编辑、操作日志追踪等功能,开发者可以快速上手并集成到实际项目中。
更多推荐



所有评论(0)