公共事件与通知功能实现
帝心:全网首发HarmonyOS4.0教程(哔哩哔哩)创作者。致力于推广鸿蒙教程开发。
developer.huawei.com/consumer/cn…
打开 APP 时,推送一个通知
使用Noification Kit的主要业务流程如下:
- 请求通知授权。
- 应用发布通知到通知服务。
- 将通知展示到通知中心。
通知工具类
本工具类具备如下基础功能
-
- 启动APP即发送通知
- 添加通知类型
- 请求授权并发布普通文本类型通知
待扩展功能:
-
- 发布多行文本类型通知
- 发布进度条通知
- 为通知添加行为意图
// 发布通知的工具类
import { common } from '@kit.AbilityKit'
import { notificationManager } from '@kit.NotificationKit'
import { BusinessError } from '@kit.BasicServicesKit'
class NotificationUtils {
// 添加通知类型 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-notificationmanager-V5#slottype
addNotificationType() {
// 添加通知类型 : addslot回调
// 社交通信类通知 : SlotType.SOCIAL_COMMUNICATION
// 内容咨询类通知 : SlotType.CONTENT_INFORMATION
// 服务提醒 : SlotType.SERVICE_INFORMATION
notificationManager.addSlot(notificationManager.SlotType.SERVICE_INFORMATION, (err: BusinessError): void => {
if (err) {
console.log(`dxin => 添加通知失败 ${err.code}, message is ${err.message}`);
} else {
console.log(`dxin => 添加通知成功`);
}
});
}
publishNotification() {
// 添加通知类型 可以调用也可以不调用
// this.addNotificationType()
let context = getContext(this) as common.UIAbilityContext
// 1. 请求通知授权 同步 响应值为 boolean 类型
let authorizationFlag = notificationManager.isNotificationEnabledSync()
if (authorizationFlag) {
// 2.能进来就不是第一次
console.log('dxin => 用户曾经在弹窗授权过')
// 再次发送通知 就是以后打开app页发通知。 如果只有首次打开发送通知。可注释下面这行
this.publishNotificationAction() // 真正发通知的动作
} else {
// 3.第一次启动app 未授权 拉起弹窗 让用户授权
// 可通过requestEnableNotification的错误码判断用户是否授权。若返回的错误码为1600004,即为拒绝授权。
// 应用请求通知使能模态弹窗。使用Promise异步回调。 无返回结果
notificationManager.requestEnableNotification(context)
.then(() => {
console.log('dxin => 用户已经授权ed')
this.publishNotificationAction()
})
.catch((err: BusinessError) => {
if (1600004 == err.code) {
console.log('dxin => "用户拒绝授权')
}else {
console.log('dxin => 授权失败,原因未知。')
}
})
}
}
// 发布通知的动作。真正发通知的效果。
publishNotificationAction(){
// 准备通知的内容
let notificationRequest: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: '通知标题',
text: '通知文本',
additionalText: 'test_additionalText:通知附加文本',
}
}
};
// 发布通知
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
console.log('dxin => 发布通知时出错了', err.message)
return
} else {
console.log('dxin => 发布通知succeed')
}
});
}
}
export default new NotificationUtils()
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import notificationUtils from '../common/NotificationUtils';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
return;
}
// 成功加载页面 发送通知
notificationUtils.publishNotification()
})
}
// ...
}
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import notificationUtils from '../common/NotificationUtils';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
return;
}
// 成功加载页面 发送通知
notificationUtils.publishNotification()
})
}
// ...
}
在通知页面发送多种通知
1. 优化工具类
设计思路
- 调用相同的函数发送不同种类通知
- 通知内容由参数控制
// 发布通知的工具类
import { common } from '@kit.AbilityKit'
import { notificationManager } from '@kit.NotificationKit'
import { BusinessError } from '@kit.BasicServicesKit'
class NotificationUtils {
// 添加通知类型 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-notificationmanager-V5#slottype
addNotificationType() {
// 添加通知类型 : addslot回调
// 社交通信类通知 : SlotType.SOCIAL_COMMUNICATION
// 内容咨询类通知 : SlotType.CONTENT_INFORMATION
// 服务提醒 : SlotType.SERVICE_INFORMATION
notificationManager.addSlot(notificationManager.SlotType.SERVICE_INFORMATION, (err: BusinessError): void => {
if (err) {
console.log(`dxin => 添加通知失败 ${err.code}, message is ${err.message}`);
} else {
console.log(`dxin => 添加通知成功`);
}
});
}
publishNotification(notificationRequest:notificationManager.NotificationRequest) {
// 添加通知类型 可以调用也可以不调用
// this.addNotificationType()
let context = getContext(this) as common.UIAbilityContext
// 1. 请求通知授权 同步 响应值为 boolean 类型
let authorizationFlag = notificationManager.isNotificationEnabledSync()
if (authorizationFlag) {
// 2.能进来就不是第一次
console.log('dxin => 用户曾经在弹窗授权过')
// 再次发送通知 就是以后打开app页发通知。 如果只有首次打开发送通知。可注释下面这行
this.publishNotificationAction(notificationRequest) // 真正发通知的动作
} else {
// 3.第一次启动app 未授权 拉起弹窗 让用户授权
// 可通过requestEnableNotification的错误码判断用户是否授权。若返回的错误码为1600004,即为拒绝授权。
// 应用请求通知使能模态弹窗。使用Promise异步回调。 无返回结果
notificationManager.requestEnableNotification(context)
.then(() => {
console.log('dxin => 用户已经授权ed')
this.publishNotificationAction(notificationRequest)
})
.catch((err: BusinessError) => {
if (1600004 == err.code) {
console.log('dxin => "用户拒绝授权')
}else {
console.log('dxin => 授权失败,原因未知。')
}
})
}
}
// 发布通知的动作。真正发通知的效果。
publishNotificationAction(notificationRequest:notificationManager.NotificationRequest){
// 发布通知
notificationManager.publish(notificationRequest, (err: BusinessError) => {
if (err) {
console.log('dxin => 发布通知时出错了', err.message)
return
} else {
console.log('dxin => 发布通知succeed')
}
});
}
}
export default new NotificationUtils()
2. 发送不同种类的通知
let notificationBasicContent: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: '普通通知标题',
text: '通知内容(不可为空字符串,大小不超过200字节,超出部分会被截断)',
additionalText: '通知附加内容,是对通知内容的补充',
// lockscreenPicture: image.PixelMap类型。通知在锁屏界面显示的图片。当前仅支持实况窗类型通知。
}
}
};
notificationUtils.publishNotification(notificationBasicContent)
let notificationLongTextContent: notificationManager.NotificationRequest = {
id: 2,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT, // 普通文本类型通知
longText: {
title: '长文本-通知标题',
text: '长文本-通知内容',
additionalText: "通知附加内容,是对通知内容的补充",
longText: "通知的长文本(不可为空字符串,大小不超过1024字节,超出部分会被截断)",
briefText: "通知概要内容,是对通知内容的总结(不可为空字符串,大小不超过200字节,超出部分会被截断)。",
expandedTitle: "通知展开时的标题(不可为空字符串,大小不超过200字节,超出部分会被截断)。"
}
}
};
notificationUtils.publishNotification(notificationLongTextContent)
let multipleLinesNft: notificationManager.NotificationRequest = {
id: 3,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE, // 多行文本类型通知
multiLine: {
title: '多行通知-标题',
text: '多行通知-文本',
briefText: '通知概要内容,是对通知的总结。关键是什么情况下显示呢',
longTitle: '通知展开时的标题(不可为空字符串,大小不超过200字节,超出部分会被截断)',
lines: ['多行通知第1行文本内容', '多行通知第2行文本内容:测试长度超出省略的效果', 'line_03', 'line_04'],
}
}
};
notificationUtils.publishNotification(multipleLinesNft)
let notificationProgress: notificationManager.NotificationRequest = {
id: 4,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: "进度条-通知标题",
text: "进度条-通知内容",
additionalText: "通知附加内容,是对通知内容的补充"
}
},
// 构造进度条模板 name字段当前需要固定配置为downloadTemplate
template: {
name: 'downloadTemplate',
data: { title: "进度条通知data", fileName: "文件名比如歌曲", progressValue: 50 }
}
}
// 3 发布进度条通知
notificationUtils.publishNotification(notificationProgress)
let notificationBasicContent: notificationManager.NotificationRequest = {
id: 1,
badgeNumber:100,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: '角标通知标题',
text: '角标是在logo上显示',
additionalText: '...',
}
}
};
notificationUtils.publishNotification(notificationBasicContent)
3. 案例代码
import notificationUtils from '../common/NotificationUtils';
import { notificationManager } from '@kit.NotificationKit';
@Entry
@Component
struct PublishNotification {
@State message: string = '准备发送通知'
build() {
Column({ space: 20 }) {
Text(this.message).fontSize(20).fontColor('#ffd64a4a')
Divider()
Text('发布不同种类通知').fontSize(30).fontWeight(700)
Button('发布【普通文本】通知').fontSize(22)
.onClick(() => {
// 普通通知
// 准备通知的内容
let notificationBasicContent: notificationManager.NotificationRequest = {
id: 1,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: '普通通知标题',
text: '通知内容(不可为空字符串,大小不超过200字节,超出部分会被截断)',
additionalText: '通知附加内容,是对通知内容的补充',
// lockscreenPicture: image.PixelMap类型。通知在锁屏界面显示的图片。当前仅支持实况窗类型通知。
}
}
};
notificationUtils.publishNotification(notificationBasicContent)
this.message = '发送【普通】通知OK'
})
Button('发布【长文本】通知').fontSize(22)
.onClick(() => {
// 普通通知
// 准备通知的内容
let notificationLongTextContent: notificationManager.NotificationRequest = {
id: 2,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_LONG_TEXT, // 普通文本类型通知
longText: {
title: '长文本-通知标题',
text: '长文本-通知内容',
additionalText: "通知附加内容,是对通知内容的补充",
longText: "通知的长文本(不可为空字符串,大小不超过1024字节,超出部分会被截断)",
briefText: "通知概要内容,是对通知内容的总结(不可为空字符串,大小不超过200字节,超出部分会被截断)。",
expandedTitle: "通知展开时的标题(不可为空字符串,大小不超过200字节,超出部分会被截断)。"
}
}
};
notificationUtils.publishNotification(notificationLongTextContent)
this.message = '发送【长文本】通知OK'
})
Button('发布多行文本通知').fontSize(22)
.onClick(() => {
// 多行通知
let multipleLinesNft: notificationManager.NotificationRequest = {
id: 3,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_MULTILINE, // 多行文本类型通知
multiLine: {
title: '多行通知-标题',
text: '多行通知-文本',
briefText: '通知概要内容,是对通知的总结。关键是什么情况下显示呢',
longTitle: '通知展开时的标题(不可为空字符串,大小不超过200字节,超出部分会被截断)',
lines: ['多行通知第1行文本内容', '多行通知第2行文本内容:测试长度超出省略的效果', 'line_03', 'line_04'],
}
}
};
notificationUtils.publishNotification(multipleLinesNft)
this.message = '发送【多行】通知OK'
})
Button('发布进度条通知').fontSize(22)
.onClick(() => {
// 2 准备进度条通知内容
let notificationProgress: notificationManager.NotificationRequest = {
id: 4,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: "进度条-通知标题",
text: "进度条-通知内容",
additionalText: "通知附加内容,是对通知内容的补充"
}
},
// 构造进度条模板 name字段当前需要固定配置为downloadTemplate
template: {
name: 'downloadTemplate',
data: { title: "进度条通知data", fileName: "文件名比如歌曲", progressValue: 50 }
}
}
// 3 发布进度条通知
notificationUtils.publishNotification(notificationProgress)
this.message ="发布【进度条】通知ok"
// 1. 需要查询系统是否支持进度条模板 由于系统是默认支持的。所以就注释掉了
// notificationManager.isSupportTemplate("downloadTemplate")
// .then((data: boolean) => {
// if (data) {
// //如果支持
// this.message = '系统支持进度条模板'
// // 2 准备进度条通知内容
// let notificationProgress: notificationManager.NotificationRequest = {
// id: 4,
// content: {
// notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
// normal: {
// title: "进度条-通知标题",
// text: "进度条-通知内容",
// additionalText: "通知附加内容,是对通知内容的补充"
// }
// },
// // 构造进度条模板 name字段当前需要固定配置为downloadTemplate
// template: {
// name: 'downloadTemplate',
// data: { title: "进度条通知data", fileName: "文件名比如歌曲", progressValue: 50 }
// }
// }
// // 3 发布进度条通知
// notificationUtils.publishNotification(notificationProgress)
// this.message ="发布【进度条】通知ok"
// } else {
// this.message = '系统不支持进度条模板'
// }
// })
})
Button('发布【角标】通知').fontSize(22)
.onClick(() => {
// 普通通知
// 准备通知的内容
let notificationBasicContent: notificationManager.NotificationRequest = {
id: 1,
badgeNumber:100,
content: {
notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
normal: {
title: '角标通知标题',
text: '角标是在logo上显示',
additionalText: '...',
}
}
};
notificationUtils.publishNotification(notificationBasicContent)
this.message = '发送【角标】通知OK。返回桌面查看'
})
Text('更过种类的通知请参考官方文档扩展学习').fontSize(18)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.theme_color'))
.justifyContent(FlexAlign.Center)
}
}