Skip to content

通知系统

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()

最佳实践

  1. 请求权限:发布通知前先检查并请求通知权限
  2. 合理分类:使用合适的 SlotType 对通知进行分类
  3. 及时取消:通知对应的事件处理完成后及时取消通知
  4. 角标同步:保持角标数字与实际未读数量一致
  5. 避免骚扰:控制通知频率,避免过度打扰用户
  6. 提供操作:为通知添加有用的操作按钮,减少用户操作步骤
  7. 进度更新:进度条通知更新频率不宜过高,避免性能问题

参考链接