通知系统
HarmonyOS 提供完善的通知系统,支持基础文本通知、长文本通知、多行文本通知、图片通知、进度条通知等多种类型,满足应用消息推送需求。
前置配置
module.json5 权限声明
发布通知需要声明 ohos.permission.NOTIFICATION 权限:
json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.NOTIFICATION",
"reason": "$string:reason_notification",
"usedScene": {}
}
]
}
}注意
除声明权限外,还需引导用户在系统设置中开启通知开关,否则通知无法正常显示。
API 列表
| API | 说明 | 起始版本 |
|---|---|---|
notificationManager.requestEnableNotification() | 请求用户开启通知权限 | API 9 |
notificationManager.isNotificationEnabled() | 查询通知是否已启用 | API 9 |
notificationManager.publish() | 发布通知 | API 9 |
notificationManager.cancel() | 取消指定通知 | API 9 |
notificationManager.cancelAll() | 取消所有通知 | API 9 |
notificationManager.setBadgeNumber() | 设置角标数字 | API 9 |
请求通知权限
在发布通知前,应先检查并请求通知权限:
typescript
import { notificationManager } from '@kit.NotificationKit'
import { common } from '@kit.AbilityKit'
async function checkAndRequestNotification(): Promise<boolean> {
try {
// 检查通知是否已启用
const isEnabled = await notificationManager.isNotificationEnabled()
if (isEnabled) {
return true
}
// 请求用户开启通知
const context = getContext() as common.UIAbilityContext
await notificationManager.requestEnableNotification(context)
return true
} catch (error) {
console.error('通知权限请求失败:', JSON.stringify(error))
return false
}
}通知内容类型
ContentType 枚举
| 枚举值 | 说明 |
|---|---|
NOTIFICATION_CONTENT_BASIC_TEXT | 基础文本通知 |
NOTIFICATION_CONTENT_LONG_TEXT | 长文本通知 |
NOTIFICATION_CONTENT_MULTILINE | 多行文本通知 |
NOTIFICATION_CONTENT_PICTURE | 图片通知 |
NOTIFICATION_CONTENT_CONVERSATION | 对话通知 |
NOTIFICATION_CONTENT_LOCAL_LIVE_VIEW | 本地实况窗通知 |
基础文本通知
最简单的通知类型,包含标题、内容和附加文本:
typescript
import { notificationManager } from '@kit.NotificationKit'
async function publishBasicNotification(): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '新消息',
text: '您有一条新消息待查看',
additionalText: '来自张三'
}
}
}
try {
await notificationManager.publish(notification)
console.info('通知发布成功')
} catch (error) {
console.error('通知发布失败:', JSON.stringify(error))
}
}长文本通知
适用于内容较长的通知,展开后显示完整文本:
typescript
import { notificationManager } from '@kit.NotificationKit'
async function publishLongTextNotification(): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: 2,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT,
longText: {
title: '新闻推送',
text: '华为发布 HarmonyOS NEXT 最新版本',
additionalText: '科技资讯',
longText: '华为在开发者大会上正式发布了 HarmonyOS NEXT 最新版本,带来了全新的 ArkUI 3.0 框架、更强大的分布式能力以及性能提升。新版本支持更多设备类型,包括手机、平板、智能手表、智慧屏等,实现真正的万物互联。',
briefText: '华为发布 HarmonyOS NEXT'
}
}
}
try {
await notificationManager.publish(notification)
console.info('长文本通知发布成功')
} catch (error) {
console.error('通知发布失败:', JSON.stringify(error))
}
}多行文本通知
适用于列表形式的内容展示:
typescript
import { notificationManager } from '@kit.NotificationKit'
async function publishMultilineNotification(): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: 3,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE,
multiLine: {
title: '待办事项',
text: '您有 3 项待办事项',
additionalText: '工作',
briefText: '3 项待办',
longTitle: '今日待办事项',
lines: [
'1. 完成项目需求文档',
'2. 参加下午 3 点会议',
'3. 提交代码审查'
]
}
}
}
try {
await notificationManager.publish(notification)
console.info('多行文本通知发布成功')
} catch (error) {
console.error('通知发布失败:', JSON.stringify(error))
}
}图片通知
包含大图展示的通知类型:
typescript
import { notificationManager } from '@kit.NotificationKit'
async function publishPictureNotification(imagePixelMap: image.PixelMap): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: 4,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_PICTURE,
picture: {
title: '图片分享',
text: '张三分享了一张照片',
additionalText: '相册',
briefText: '新照片',
expandedTitle: '张三分享的照片',
picture: imagePixelMap
}
}
}
try {
await notificationManager.publish(notification)
console.info('图片通知发布成功')
} catch (error) {
console.error('通知发布失败:', JSON.stringify(error))
}
}进度条通知
适用于文件下载、上传等需要显示进度的场景:
typescript
import { notificationManager } from '@kit.NotificationKit'
class ProgressNotification {
private notificationId: number = 100
private isRunning: boolean = false
async startProgress(title: string, total: number): Promise<void> {
this.isRunning = true
await this.updateProgress(title, 0, total)
}
async updateProgress(title: string, current: number, total: number): Promise<void> {
if (!this.isRunning) return
const progress = Math.floor((current / total) * 100)
const notification: notificationManager.NotificationRequest = {
id: this.notificationId,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: `下载中... ${progress}%`,
additionalText: `${current}/${total}`
}
},
notificationSlotType: notificationManager.SlotType.CONTENT_INFORMATION,
progress: {
currentValue: current,
maxValue: total,
isPercentage: false
}
}
try {
await notificationManager.publish(notification)
} catch (error) {
console.error('进度通知更新失败:', JSON.stringify(error))
}
}
async completeProgress(title: string): Promise<void> {
this.isRunning = false
const notification: notificationManager.NotificationRequest = {
id: this.notificationId,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: title,
text: '下载完成',
additionalText: '点击打开'
}
}
}
try {
await notificationManager.publish(notification)
} catch (error) {
console.error('完成通知发布失败:', JSON.stringify(error))
}
}
async cancel(): Promise<void> {
this.isRunning = false
try {
await notificationManager.cancel(this.notificationId)
} catch (error) {
console.error('取消通知失败:', JSON.stringify(error))
}
}
}
// 使用示例
const progressNotifier = new ProgressNotification()
async function downloadFile() {
await progressNotifier.startProgress('文件下载', 100)
// 模拟下载进度
for (let i = 0; i <= 100; i += 10) {
await new Promise(resolve => setTimeout(resolve, 500))
await progressNotifier.updateProgress('文件下载', i, 100)
}
await progressNotifier.completeProgress('文件下载')
}通知渠道(SlotType)
HarmonyOS 使用通知渠道对通知进行分类管理:
| 枚举值 | 说明 | 适用场景 |
|---|---|---|
UNKNOWN_TYPE | 未知类型 | 默认 |
SOCIAL_COMMUNICATION | 社交通信 | 消息、聊天 |
SERVICE_INFORMATION | 服务提醒 | 订单状态、物流 |
CONTENT_INFORMATION | 内容资讯 | 新闻、资讯 |
LIVE_VIEW | 实况窗 | 实时活动 |
CUSTOMER_SERVICE | 客户服务 | 客服消息 |
typescript
import { notificationManager } from '@kit.NotificationKit'
async function publishWithSlot(): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: 5,
notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '新消息',
text: '张三:晚上一起吃饭吗?',
additionalText: '微信'
}
}
}
await notificationManager.publish(notification)
}通知动作按钮
为通知添加可交互按钮:
typescript
import { notificationManager } from '@kit.NotificationKit'
import { Want } from '@kit.AbilityKit'
async function publishNotificationWithActions(): Promise<void> {
// 定义点击通知时的 Want
const want: Want = {
bundleName: 'com.example.myapp',
abilityName: 'EntryAbility',
parameters: {
page: 'messageDetail',
messageId: '12345'
}
}
const notification: notificationManager.NotificationRequest = {
id: 6,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '会议提醒',
text: '下午 3 点项目评审会议',
additionalText: '日历'
}
},
want: want,
actionButtons: [
{
title: '确认参加',
want: {
bundleName: 'com.example.myapp',
abilityName: 'EntryAbility',
parameters: {
action: 'accept',
meetingId: '12345'
}
}
},
{
title: '拒绝',
want: {
bundleName: 'com.example.myapp',
abilityName: 'EntryAbility',
parameters: {
action: 'decline',
meetingId: '12345'
}
}
}
]
}
await notificationManager.publish(notification)
}角标管理
设置应用图标角标数字:
typescript
import { notificationManager } from '@kit.NotificationKit'
// 设置角标数字
async function setBadge(count: number): Promise<void> {
try {
await notificationManager.setBadgeNumber(count)
console.info('角标设置成功:', count)
} catch (error) {
console.error('角标设置失败:', JSON.stringify(error))
}
}
// 清除角标
async function clearBadge(): Promise<void> {
await setBadge(0)
}
// 使用示例:新消息到达时增加角标
let unreadCount = 0
async function onNewMessage(): Promise<void> {
unreadCount++
await setBadge(unreadCount)
// 发布通知
await notificationManager.publish({
id: unreadCount,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: '新消息',
text: '您有一条新消息',
additionalText: `${unreadCount} 条未读`
}
}
})
}
// 消息已读后清除角标
async function onMessagesRead(): Promise<void> {
unreadCount = 0
await clearBadge()
await notificationManager.cancelAll()
}取消通知
typescript
import { notificationManager } from '@kit.NotificationKit'
// 取消指定 ID 的通知
async function cancelNotification(id: number): Promise<void> {
try {
await notificationManager.cancel(id)
console.info(`通知 ${id} 已取消`)
} catch (error) {
console.error('取消通知失败:', JSON.stringify(error))
}
}
// 取消所有通知
async function cancelAllNotifications(): Promise<void> {
try {
await notificationManager.cancelAll()
console.info('所有通知已取消')
} catch (error) {
console.error('取消所有通知失败:', JSON.stringify(error))
}
}完整封装示例
typescript
import { notificationManager } from '@kit.NotificationKit'
import { Want } from '@kit.AbilityKit'
interface NotificationOptions {
id: number
title: string
text: string
additionalText?: string
slotType?: notificationManager.SlotType
want?: Want
actionButtons?: notificationManager.NotificationActionButton[]
}
class NotificationHelper {
private static instance: NotificationHelper
static getInstance(): NotificationHelper {
if (!NotificationHelper.instance) {
NotificationHelper.instance = new NotificationHelper()
}
return NotificationHelper.instance
}
async checkPermission(): Promise<boolean> {
try {
return await notificationManager.isNotificationEnabled()
} catch {
return false
}
}
async publish(options: NotificationOptions): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id: options.id,
notificationSlotType: options.slotType || notificationManager.SlotType.CONTENT_INFORMATION,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: options.title,
text: options.text,
additionalText: options.additionalText || ''
}
},
want: options.want,
actionButtons: options.actionButtons
}
await notificationManager.publish(notification)
}
async publishLongText(id: number, title: string, text: string, longText: string): Promise<void> {
const notification: notificationManager.NotificationRequest = {
id,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT,
longText: {
title,
text,
longText,
briefText: text
}
}
}
await notificationManager.publish(notification)
}
async publishProgress(id: number, title: string, current: number, total: number): Promise<void> {
const progress = Math.floor((current / total) * 100)
const notification: notificationManager.NotificationRequest = {
id,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title,
text: `进度: ${progress}%`,
additionalText: `${current}/${total}`
}
},
progress: {
currentValue: current,
maxValue: total,
isPercentage: false
}
}
await notificationManager.publish(notification)
}
async cancel(id: number): Promise<void> {
await notificationManager.cancel(id)
}
async cancelAll(): Promise<void> {
await notificationManager.cancelAll()
}
async setBadge(count: number): Promise<void> {
await notificationManager.setBadgeNumber(count)
}
}
export const notificationHelper = NotificationHelper.getInstance()最佳实践
- 请求权限:发布通知前先检查并请求通知权限
- 合理分类:使用合适的 SlotType 对通知进行分类
- 及时取消:通知对应的事件处理完成后及时取消通知
- 角标同步:保持角标数字与实际未读数量一致
- 避免骚扰:控制通知频率,避免过度打扰用户
- 提供操作:为通知添加有用的操作按钮,减少用户操作步骤
- 进度更新:进度条通知更新频率不宜过高,避免性能问题