HarmonyOS Next 用户通知服务Notification Kit介绍与实战
1、用户通知服务Notification Kit介绍
Notification Kit(用户通知服务)为开发者提供本地通知发布通道,开发者可借助Notification Kit将应用产生的通知直接在客户端本地推送给用户,本地通知根据通知类型及发布场景会产生对应的铃声、震动、横幅、锁屏、息屏、通知栏提醒和显示。类似Android 的通知栏功能:
创建通知后以图标的形式在状态栏中显示:
用户可以在状态栏向下滑动以打开抽屉式通知栏,并在其中查看更多详情及对通知执行操作。
还有提醒式通知样式:
HarmonyOS 也提供了类似的能力Notification Kit。
2、用户通知服务与Call Kit、Push Kit区别
- 用户通知是允许开发者自己调用接口创建定义的
- Push Kit(推送服务)是华为提供的消息推送平台,建立了从云端到终端的消息推送通道。所有HarmonyOS应用可通过集成Push Kit,实现向应用实时推送消息,使消息易见,构筑良好的用户关系,提升用户的感知度和活跃度。Push Kit与云端的链接的是系统守护进程,一直运行在后台,当点击通知服务厂商的通知栏时会拉起对应应用进程。显示场景主要包括通知中心、锁屏、横幅、桌面图标角标与通知图标。
- Call Service Kit(通话服务)是HarmonyOS为开发者提供的应用内通话管理服务。开发者通过集成Call Service Kit,可以实现便捷的来电一键接听、横幅通知、静音与取消静音等功能,提升用户体验。当应用在后台时,如果有来电,需要Push Kit(推送服务)先拉起应用主进程,应用才能给Call Service Kit上报来电。Call Kit与Push Kit关系如下:
可以理解为应用有个独立守护进程一直与华为云端通信,这个是Push Kit,当有通知到达时,这个进程调用Notification Kit创建对应通知栏通知,当对应通知时通话时,点击通知栏拉起进程,应用给Call Kit上报来电。
3、用户通知服务Notification Kit 能力及API
使用Notification Kit的主要业务流程如下:
1.请求通知授权。
2.应用发布通知到通知服务。
3.将通知展示到通知中心。
请求通知授权
首先应用需要获取用户授权才能发送通知。在通知发布前调用requestEnableNotification()方法,弹窗让用户选择是否允许发送通知,后续再次调用requestEnableNotification()方法时,则不再弹窗。
授权通知接口功能如下:
接口名 | 描述 |
---|---|
isNotificationEnabled():Promise | 查询通知是否授权。 |
requestEnableNotification(context: UIAbilityContext): Promise | 请求发送通知的许可,第一次调用会弹窗让用户选择。 |
首先导入NotificationManager模块:
import { notificationManager } from '@kit.NotificationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common } from '@kit.AbilityKit';
const TAG: string = '[PublishOperation]';
const DOMAIN_NUMBER: number = 0xFF00;
可通过requestEnableNotification的错误码判断用户是否授权。若返回的错误码为1600004,即为拒绝授权。
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
notificationManager.isNotificationEnabled().then((data: boolean) => {
hilog.info(DOMAIN_NUMBER, TAG, "isNotificationEnabled success, data: " + JSON.stringify(data));
if(!data){
notificationManager.requestEnableNotification(context).then(() => {
hilog.info(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification success`);
}).catch((err : BusinessError) => {
if(1600004 == err.code){
hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification refused, code is ${err.code}, message is ${err.message}`);
} else {
hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);
}
});
}
}).catch((err : BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `isNotificationEnabled fail, code is ${err.code}, message is ${err.message}`);
});
发布通知
Notification Kit中常用的通知样式如下:
类型 | 通知样式 | 规格描述 |
---|---|---|
文本 | ![]() | 通知文本内容最多显示三行,超长后以“…”截断。 |
多行文本 | ![]() | |
最多可显示三行内容,每行内容超长后以“…”截断。 | ||
通知角标 | ![]() | |
以数字的形式展示在右上角。 | ||
进度条 | ![]() | 进度类通知。 |
发布文本类型通知
文本类型通知主要应用于发送短信息、提示信息等,支持普通文本类型和多行文本类型。
首先导入对应模块:
import { notificationManager } from '@kit.NotificationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const TAG: string = '[PublishOperation]';
const DOMAIN_NUMBER: number = 0xFF00;
接着构造NotificationRequest对象,并发布通知。
//普通文本类型通知由标题、文本内容和附加信息三个字段组成。
let notificationRequest: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: 'test_title',
text: 'test_text',
additionalText: 'test_additionalText',
}
}
};
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
});
//多行文本类型通知继承了普通文本类型的字段,同时新增了多行文本内容、内容概要和通知展开时的标题。
let notificationRequest: notificationManager.NotificationRequest = {
id: 3,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE, // 多行文本类型通知
multiLine: {
title: 'test_title',
text: 'test_text',
briefText: 'test_briefText',
longTitle: 'test_longTitle',
lines: ['line_01', 'line_02', 'line_03'],
}
}
};
// 发布通知
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
});
进度条类型通知
进度条通知也是常见的通知类型,主要应用于文件下载、事务处理进度显示。当前系统提供了进度条模板,发布通知应用设置好进度条模板的属性值,如模板名、模板数据,通过通知子系统发送到通知栏显示。
目前系统模板仅支持进度条模板,通知模板NotificationTemplate中的data参数为用户自定义数据,用于显示与模块相关的数据。
首先需要先查询系统是否支持进度条模板,查询结果为支持downloadTemplate模板类通知。
notificationManager.isSupportTemplate('downloadTemplate').then((data:boolean) => {
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in supporting download template notification.');
let isSupportTpl: boolean = data; // isSupportTpl的值为true表示支持downloadTemplate模板类通知,false表示不支持
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to support download template notification. Code is ${err.code}, message is ${err.message}`);
});
如果支持,则构造进度条模板对象,并发布通知:
let notificationRequest: notificationManager.NotificationRequest = {
id: 5,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: 'test_title',
text: 'test_text',
additionalText: 'test_additionalText'
}
},
// 构造进度条模板,name字段当前需要固定配置为downloadTemplate
template: {
name: 'downloadTemplate',
data: { title: 'File Title', fileName: 'music.mp4', progressValue: 45 }
}
}
// 发布通知
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
});
取消通知
用户收到通知提醒后,点击通知并拉起应用到前台时,应用可以选择取消某条通知或所有通知。
例如,用户收到某个好友的IM消息,点击通知进入应用查看消息后,应用可以取消相关通知提醒。
取消通知代码示例:
// 当拉起应用到前台,查看消息后,调用该接口取消通知。
notificationManager.cancel(1, (err: BusinessError) => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to cancel notification. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in canceling notification.');
});
用户通知服务Notification Kit 适用场景
当应用处于前台运行时,开发者可以使用Notification Kit向用户发布通知。当应用转为后台时,本地通知发布通道关闭,开发者需要接入Push Kit进行云侧离线通知的发布。
开发者可以在多种场景中运用本地通知能力。如同步用户的上传下载进度、发布即时的客服支付通知、更新运动步数等。
Notification Kit支持的能力主要包括:
- 发布文本、进度条等类型通知。
- 携带或更新应用通知数字角标。
- 取消曾经发布的某条或全部通知。
- 查询已发布的通知列表。
- 查询应用自身通知开关状态。
- 应用通知用户的能力默认关闭,开发者可拉起授权框,请求用户授权发布通知。
HarmonyOS 对通知的使用做了下面限制:
- 单个应用已发布的通知在通知中心等系统入口的留存数量有限(当前规格最多24条)。
- 通知的长度不能超过200KB(跨进程序列化大小限制)。
- 通知的发布频次和更新频次需要满足如下要求,否则会导致发布或更新失败,返回相应错误码。
- 单个应用发布新通知的频次累计不能超过每秒10条,更新通知的频次累计不能超过每秒20条。
- 所有三方应用发布新通知的频次累计不能超过每秒15条,更新通知的频次累计不能超过每秒30条。
4、IM场景下通知实战
基础设置
IM场景应用,比如微信、企微等,目前由于鸿蒙不像Android一样可以保活,在应用切换到后台后应用本身无法再做任何事情,目前采用类似于iOS的方式,提供了Push Kit,应用在后台时可以通过Push Kit接收通知。但是目前Push Kit有个问题,iOS的Push Kit可以在通知展示前通过询问应用的方式让APP干预通知是否展示,HarmonyOS 目前应用无法干预,就算应用在前台也无法干预。不过HarmonyOS Push Kit提供了应用在后台时展示通知消息,应用在前台时只接收通知消息自行完成业务处理,而不展示通知消息,只需在调用REST API推送通知消息,消息体中携带foregroundShow字段,并且设置为false(默认为true,表示前后台都展示),则应用在前台时不会展示通知消息:
// Request Body
{
"payload": {
"notification": {
"category": "MARKETING",
"title": "普通通知标题",
"body": "普通通知内容",
"profileId": "111***222",
"clickAction": {
"actionType": 0
},
"foregroundShow": false // 设置为false则应用在前台时不会展示通知消息
}
},
"target": {
"token": ["IQAAAA**********4Tw"]
}
}
通过receiveMessage()方法传入PushType为"DEFAULT"获取通知消息,用于应用在前台时接收通知消息,示例代码如下
import { UIAbility } from '@kit.AbilityKit';
import { pushService } from '@kit.PushKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
/**
* 此处以PushMessageAbility为例,用于应用在前台时接收通知消息
*/
export default class PushMessageAbility extends UIAbility {
onCreate(): void {
try {
// receiveMessage中的参数固定为DEFAULT
pushService.receiveMessage('DEFAULT', this, (data) => {
// process message,并建议对Callback进行try-catch
try {
// get notification passed by REST API
const notification = JSON.parse(data.data)?.notification;
hilog.info(0x0000, 'testTag', 'Succeeded in getting notification,data=%{public}s', JSON.stringify(notification));
} catch (e) {
let errRes: BusinessError = e as BusinessError;
hilog.error(0x0000, 'testTag', 'Failed to process data: %{public}d %{public}s', errRes.code, errRes.message);
}
});
} catch (err) {
let e: BusinessError = err as BusinessError;
hilog.error(0x0000, 'testTag', 'Failed to get message: %{public}d %{public}s', e.code, e.message);
}
}
}
应用在前台实现了类似透传消息的效果。
接下来我们在收到透传消息后根据业务逻辑自定义通知,比如正在跟A聊天停留在A聊天页面,那么此时A来消息则不进行通知栏通知,如果此时是另一个用户B来消息则要正常展示。
这里我们解析Push Kit透传内容,弹出普通文本通知:
const notification = JSON.parse(data.data)?.notification;
let notificationRequest: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: notification.title,
text: 'notification.text',
additionalText: 'notification.additional',
}
}
};
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
});
角标设置
HarmonyOS 针对未读的通知,系统提供了角标设置接口,将未读通知个数显示在桌面图标的右上角角标上。通知增加时,角标上显示的未读通知个数需要增加。通知被查看后,角标上显示的未读通知个数需要减少,没有未读通知时,不显示角标。
增加角标个数:发布通知在NotificationRequest的badgeNumber字段里携带,下面示例为调用setBadgeNumber接口增加角标,在发布完新的通知后,调用该接口。
let setBadgeNumberCallback = (err: BusinessError): void => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to set badge number. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, `Succeeded in setting badge number.`);
}
let badgeNumber = 9;
notificationManager.setBadgeNumber(badgeNumber, setBadgeNumberCallback);
减少角标个数。一条通知被查看后,应用需要调用接口设置剩下未读通知个数,桌面刷新角标。
let setBadgeNumberCallback = (err: BusinessError): void => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to set badge number. Code is ${err.code}, message is ${err.message}`);
return;
}
hilog.info(DOMAIN_NUMBER, TAG, `Succeeded in setting badge number.`);
}
let badgeNumber = 8;
notificationManager.setBadgeNumber(badgeNumber, setBadgeNumberCallback);
注意:由于setBadgeNumber为异步接口,使用setBadgeNumber连续设置角标时,为了确保执行顺序符合预期,需要确保上一次设置完成后才能进行下一次设置。
通知渠道设置
一些特殊的业务场景,不同类型的消息可能会有不同的提示音等配置,比如聊天消息和营销通知,HarmonyOS 系统支持多种通知渠道,不同通知渠道对应的通知提醒方式不同,可以根据应用的实际场景选择适合的通知渠道,并对通知渠道进行管理(支持创建、查询、删除等操作)。
不同类型的通知渠道对应的通知提醒方式不同,详见下表。其中,Y代表支持,N代表不支持。
SlotType | 取值 | 分类 | 通知中心 | 横幅 | 锁屏 | 铃声/振动 | 状态栏图标 | 自动亮屏 |
---|---|---|---|---|---|---|---|---|
UNKNOWN_TYPE | 0 | 未知类型 | Y | N | N | N | N | N |
SOCIAL_COMMUNICATION | 1 | 社交通信 | Y | Y | Y | Y | Y | Y |
SERVICE_INFORMATION | 2 | 服务提醒 | Y | Y | Y | Y | Y | Y |
CONTENT_INFORMATION | 3 | 内容资讯 | Y | N | N | N | N | N |
CUSTOMER_SERVICE | 5 | 客服消息 | Y | N | N | Y | Y | N |
OTHER_TYPES | 0xFFFF | 其他 | Y | N | N | N | N | N |
下面是创建指定类型通知渠道示例: |
// addslot回调
let addSlotCallBack = (err: BusinessError): void => {
if (err) {
hilog.error(DOMAIN_NUMBER, TAG, `addSlot failed, code is ${err.code}, message is ${err.message}`);
} else {
hilog.info(DOMAIN_NUMBER, TAG, `addSlot success`);
}
}
notificationManager.addSlot(notificationManager.SlotType.SOCIAL_COMMUNICATION, addSlotCallBack);
自定义铃声
不同类型消息如果要设置不同铃声,可以通过sound字段,应用通知自定义铃声文件名。该文件必须放在resources/rawfile目录下,支持m4a、aac、mp3、ogg、wav、flac、amr等格式。
仅当应用申请并获得通知自定义铃声权益后,该字段方可生效。
当前该权益仅面向AppGallery Connect中“应用分类”为“应用/社交”且“应用标签”为“通讯”的应用开放。
开发者可以通过登录AppGallery Connect,选择需要查看的应用,在左侧导航栏选择“应用上架 > 应用信息”,查询应用分类和应用标签是否符合条件。
通知点击
当发布通知时,我们一般期望用户可以通过点击通知栏拉起我们应用对应用户的聊天页,可以通过Ability Kit申请WantAgent封装至通知消息中。
处理流程如下:
下面示例是创建拉起UIAbility的WantAgent的WantAgentInfo信息。
let wantAgentObj:WantAgent; // 用于保存创建成功的wantAgent对象,后续使用其完成触发的动作。
// 通过WantAgentInfo的operationType设置动作类型
let wantAgentInfo:wantAgent.WantAgentInfo = {
wants: [
{
deviceId: '',
bundleName: 'com.samples.notification',
abilityName: 'SecondAbility',
action: '',
entities: [],
uri: '',
parameters: {}
}
],
actionType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]
};
5、总结
HarmonyOS的Notification Kit为开发者提供本地通知管理能力,支持创建文本、多行文本、进度条等通知样式,并可实现角标更新、通知取消及自定义铃声等功能。与Push Kit(云端推送)和Call Kit(通话管理)形成互补:Notification Kit处理本地即时通知,Push Kit负责后台云消息推送,Call Kit则专注于通话场景的交互管理。核心流程包括请求授权(isNotificationEnabled查询、requestEnableNotification弹窗)、构建通知模板(含标题、内容及扩展字段),通过publish接口触发展示,并支持按ID取消或批量清理通知。应用需注意系统限制:单应用通知留存上限24条,内容大小不超过200KB,发布频次受限(前台每秒10条新通知)。实战中结合Push Kit可实现IM场景消息同步,通过foregroundShow字段控制前后台通知展示策略,并利用角标接口动态更新未读计数。该服务适用于即时通讯、进度同步等需用户即时感知的场景,但需注意通知渠道分类(如社交通信类支持全通道提醒)及自定义权益申请(如铃声需特定应用标签)。