自定义通知角标
介绍
本示例主要展示了设定应用的桌面图标角标的功能,使用@ohos.notificationManager接口,进行桌面角标的设置,通知的发送,获取等。
效果预览
使用说明
- 在主界面,可以看到当前应用的所有消息通知;
- 点击右下角Tab页签进入通知发送页面,点击对应的通知即可发送相应类型的通知,点击几次发送几条;
- 点击左下角Tab页签进入消息列表,可以查看刚才发送的消息,消息右边会显示消息数量,点击相应的消息可进行消息读取,取消相应通知;
- 下拉通知栏,可以看到角标数量,对应消息数量。
具体实现
-
允许发送通知,发送通知的功能接口封装在NotificationUtil,源码参考:[NotificationUtil.ets]
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { notificationManager } from '@kit.NotificationKit';
import { logger } from '../util/Logger';
import { notificationManagement } from '../notification/NotificationManagementUtil';
import { BusinessError } from '@kit.BasicServicesKit';const TAG: string = 'NotificationUtilModel';
class NotificationUtil {
/**
* enable notification
*/
private id: number = 0async enableNotification() { try { notificationManager.requestEnableNotification(AppStorage.get('context'), (err: BusinessError): void => { if (err) { logger.error(TAG, `requestEnableNotification failed, code is ${err.code}, message is ${err.message}`); } else { logger.info(TAG, 'requestEnableNotification success'); } }); logger.info(TAG, `enableNotification success`); } catch (err) { logger.info(TAG, `enableNotification err ${JSON.stringify(err)}`); } } /** * * @param notificationRequest * @param id, Support specifying notification id when publishing notifications */ async publishNotification(notificationRequest: notificationManager.NotificationRequest, group?: string) { notificationRequest.id = this.id; this.id++; if (group) { notificationRequest.groupName = group; } try { await notificationManager.publish(notificationRequest); logger.info(TAG, `publish notification success`); // 通知管理器添加新通知 await notificationManagement.addNotification(notificationRequest); } catch (err) { if (err) { logger.info(TAG, `publishNotification err ${JSON.stringify(err)}`); } } } /** * cancel notification by id */ async cancelNotificationById(id: number) { try { await notificationManager.cancel(id); logger.info(TAG, `cancel success`); } catch (err) { if (err) { logger.info(TAG, `cancel err ${JSON.stringify(err)}`); } } } /** * cancel all notification */ async cancelAllNotifications() { try { await notificationManager.cancelAll(); logger.info(TAG, `cancel all success`); } catch (err) { if (err) { logger.info(TAG, `cancel all err ${JSON.stringify(err)}`); } } }
}
export let notificationUtil = new NotificationUtil();
-
允许发送通知:在进入[Index.ets] 前通过notificationUtil.enableNotification()调用notification.requestEnableNotification()接口向用户请求发送通知;
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { NotificationList } from '../components/NotificationList';
import { NoticePublish } from '../components/NotificationPublish';export interface TabImage {
selectedImage: Resource,
unselectedImage: Resource,
}const MESSAGE_TAB: TabImage = {
selectedImage: $r('app.media.ic_messages_filled'),
unselectedImage: $r('app.media.ic_messages'),
}
const NOTIFICATION_TAB: TabImage = {
selectedImage: $r('app.media.ic_public_send_filled'),
unselectedImage: $r('app.media.ic_public_send'),
}interface TAB_INDEX_TYPE {
MESSAGE_TAB: number
NOTIFICATION_TAB: number
}const TAB_INDEX: TAB_INDEX_TYPE = {
MESSAGE_TAB: 0,
NOTIFICATION_TAB: 1
}@Entry
@Component
struct Index {
@State tabsIndex: number = 0@Builder TabBarBuilder(index: number, item: TabImage, tabBarName: Resource) { Column() { Image(this.tabsIndex === index ? item.selectedImage : item.unselectedImage) .width(24) .height(24) .margin({ bottom: 10 }) Text(tabBarName) .fontSize(10) } .width('100%') .padding({ top: 0, bottom: 0 }) .alignItems(HorizontalAlign.Center) .id(`tabBar${index}`) } build() { Column() { Tabs({ barPosition: BarPosition.End }) { TabContent() { Column() { if (this.tabsIndex === TAB_INDEX.MESSAGE_TAB) { NotificationList() } Blank() } .height('100%') } .tabBar(this.TabBarBuilder(TAB_INDEX.MESSAGE_TAB, MESSAGE_TAB, $r('app.string.messages_list_title'))) TabContent() { Column() { NoticePublish() Blank() } .height('100%') } .tabBar(this.TabBarBuilder(TAB_INDEX.NOTIFICATION_TAB, NOTIFICATION_TAB, $r('app.string.notification_publish_title')),) } .barHeight(74) .barWidth('100%') .vertical(false) .onChange((index: number) => { this.tabsIndex = index }) }.width('100%').height('100%') .backgroundColor($r('app.color.background_light_gray')) }
}
-
发送通知:通过publishNotification()封装发布通知的接口;
-
获取应用所有消息通知、取消相关类型通知,角标管理接口封装在NotificationManagementUtil,源码参考:[NotificationManagementUtil.ets]
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { notificationManager } from '@kit.NotificationKit';
import { logger } from '../util/Logger';
const NOTIFICATION_TYPE_SIZE = 5;
export interface getAllNotificationsResultType {
groupNotifications: Array<Array<notificationManager.NotificationRequest>>
countsByType: Array<number>
}// 通知管理
class NotificationManagementUtil {
typeNotifications: Array<Array<notificationManager.NotificationRequest>> = new Array(NOTIFICATION_TYPE_SIZE + 1);
countsByType: Array<number> = new Array(NOTIFICATION_TYPE_SIZE + 1);
badgeNum: number = 0;constructor() { this.countsByType.fill(0); for (let i = 0; i < NOTIFICATION_TYPE_SIZE + 1; i++) { this.typeNotifications[i] = new Array(); } // 获取当前应用所有通知 notificationManager.getActiveNotifications().then((notifications) => { for (let i = 0; i < notifications.length; i++) { let typeId = notifications[i].content.notificationContentType; this.countsByType[typeId as number] += 1; this.typeNotifications[typeId as number].push(notifications[i]); } logger.info(`getAllActiveNotifications success, data: ${JSON.stringify(notifications)}`) // 计算角标数量 this.countsByType.forEach((num: number) => { this.badgeNum += num; }) }) } // 取消属于该类型的通知 cancelNotificationType(typeId: number) { this.typeNotifications[typeId].forEach(item => { notificationManager.cancel(item.id); }) } // 设置角标 async setBadgeNumber(num: number) { await notificationManager.setBadgeNumber(num).then(() => { this.badgeNum = num; logger.info("displayBadge success"); }); } // 获取角标数量 getBadgeNumber(): number { return this.badgeNum; } // 添加一条消息 async addNotification(notification: notificationManager.NotificationRequest) { const typeId: notificationManager.ContentType = notification.content.notificationContentType as notificationManager.ContentType; this.typeNotifications[typeId].push(notification); this.countsByType[typeId] += 1; this.badgeNum += 1; await notificationManagement.setBadgeNumber(this.badgeNum); logger.info("add Message success"); } // 获取当前所有消息及数量 async getAllNotifications() { let result: getAllNotificationsResultType = { groupNotifications: this.typeNotifications, countsByType: this.countsByType } return result; }
}
export let notificationManagement = new NotificationManagementUtil();
-
获取应用所有消息通知:在constructor()构造函数中调用@ohos.notificationManager中的getActiveNotifications接口获取所有通知及相应类型通知数量,通过封装getAllNotifications()对外提供接口获取当前消息及消息数量。
-
取消相关类型通知:通过cancelNotificationType()封装取消相关通知类型的接口;
-
角标管理接口:通过setBadgeNumber()封装设置应用角标数量的接口,通过getBadgeNumber()封装获取当前应用角标数量的接口。
- 添加一条通知:通过addNotification()封装接口添加一条通知到消息管理器,当发送通知的时候进行调用。
-
NotificationOperations向外提供接口,在页面中调用它们来实现功能,源码参考:[NotificationOperations.ets]
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { image } from '@kit.ImageKit';
import { notificationManager } from '@kit.NotificationKit';
import { logger, notificationUtil, notificationContentUtil, notificationRequestUtil } from '@ohos/notification';const TAG: string = 'Sample_Notification';
const MULTI_LINE_CONTENT: Array<string> = ['line0', 'line1', 'line2', 'line3']; // 多行文本通知的多行文本内容interface NOTIFICATION_GROUP_TYPE {
BASIC: string
LONG_TEXT: string
MULTI_LINE: string
PICTURE: string
CONVERSATION: string
}const NOTIFICATION_GROUP: NOTIFICATION_GROUP_TYPE = { // 定义不同类型通知的通知组
BASIC: 'BASIC',
LONG_TEXT: 'LONG_TEXT',
MULTI_LINE: 'MULTI_LINE',
PICTURE: 'PICTURE',
CONVERSATION: 'CONVERSATION'
}export default class NotificationOperations {
private context: Context;
private basicContent: notificationManager.NotificationBasicContent;// 在初始化函数初始化基本通知类型的参数 constructor(context: Context) { this.context = context; let notificationTitle = ''; let notificationText = this.context.resourceManager.getStringSync($r('app.string.notification_content')); let notificationAdditional = this.context.resourceManager.getStringSync($r('app.string.notification_additional')); this.basicContent = { title: notificationTitle, text: notificationText, additionalText: notificationAdditional } } // 发布基本类型通知 publishBasicNotification = () => { try { logger.info(TAG, 'publishBasicNotification'); this.basicContent.title = this.context.resourceManager.getStringSync($r('app.string.basic_notification')); let notificationContent = notificationContentUtil.initBasicNotificationContent(this.basicContent); notificationUtil.publishNotification(notificationRequestUtil.initBasicNotificationRequest(notificationContent as notificationManager.NotificationContent) as notificationManager.NotificationRequest); } catch (error) { logger.info(TAG, `publishBasicNotification error, error = ${JSON.stringify(error)}`); } } // 发布长文本类型通知 publishLongTextNotification = () => { try { logger.info(TAG, 'publishLongTextNotification'); this.basicContent.title = this.context.resourceManager.getStringSync($r('app.string.long_text_notification')); let notificationLongText = this.context.resourceManager.getStringSync($r('app.string.notification_long_text')); let notificationBriefText = this.context.resourceManager.getStringSync($r('app.string.notification_brief_text')); let notificationExpandedText = this.context.resourceManager.getStringSync($r('app.string.notification_expanded_title')); let notificationContent = notificationContentUtil.initNotificationLongTextContent(this.basicContent, notificationLongText, notificationBriefText, notificationExpandedText); notificationUtil.publishNotification(notificationRequestUtil.initBasicNotificationRequest(notificationContent as notificationManager.NotificationContent) as notificationManager.NotificationRequest); } catch (error) { logger.info(TAG, `publishLongTextNotification error, error = ${JSON.stringify(error)}`); } } // 发布多行文本类型通知 publishMultiLineNotification = () => { try { logger.info(TAG, 'publishMultiLineNotification'); this.basicContent.title = this.context.resourceManager.getStringSync($r('app.string.multiline_notification')); let notificationBriefText = this.context.resourceManager.getStringSync($r('app.string.notification_brief_text')); let notificationLongTitle = this.context.resourceManager.getStringSync($r('app.string.notification_expanded_title')); let notificationContent = notificationContentUtil.initNotificationMultiLineContent(this.basicContent, notificationBriefText, notificationLongTitle, MULTI_LINE_CONTENT); notificationUtil.publishNotification(notificationRequestUtil.initBasicNotificationRequest(notificationContent as notificationManager.NotificationContent) as notificationManager.NotificationRequest); } catch (error) { logger.info(TAG, `publishMultiLineNotification error, error = ${JSON.stringify(error)}`); } } // 发布图片类型通知 publishPictureNotification = async () => { try { logger.info(TAG, 'publishPictureNotification'); this.basicContent.title = this.context.resourceManager.getStringSync($r('app.string.picture_notification')); let notificationBriefText = this.context.resourceManager.getStringSync($r('app.string.notification_brief_text')); let notificationExpandedText = this.context.resourceManager.getStringSync($r('app.string.notification_expanded_title')); let imageArray = await this.context.resourceManager.getMediaContent($r('app.media.notification_icon').id); let imageResource = image.createImageSource(imageArray.buffer as ArrayBuffer); let picture = await imageResource.createPixelMap(); let notificationContent = notificationContentUtil.initNotificationPictureContent(this.basicContent, notificationBriefText, notificationExpandedText, picture); notificationUtil.publishNotification(notificationRequestUtil.initBasicNotificationRequest(notificationContent as notificationManager.NotificationContent) as notificationManager.NotificationRequest); } catch (error) { logger.info(TAG, `publishPictureNotification error, error = ${JSON.stringify(error)}`); } } // 发布社交类型的通知 publishConversationNotification = async () => { try { logger.info(TAG, 'publishConversationNotification'); this.basicContent.title = this.context.resourceManager.getStringSync($r('app.string.conversation_notification')); let notificationContent = notificationContentUtil.initNotificationConversationContent(this.basicContent); notificationUtil.publishNotification(notificationRequestUtil.initBasicNotificationRequest(notificationContent as notificationManager.NotificationContent) as notificationManager.NotificationRequest, NOTIFICATION_GROUP.CONVERSATION); } catch (error) { logger.info(TAG, `publishNotificationWithWantAgent error, error = ${JSON.stringify(error)}`); } }
}
-
发布通知:在[Index.ets]页面中进入发送通知Tab页签,通过点击事件调用NotificationOperations中封装的对应的方法,然后从NotificationContentUtil中获取对应的主体内容content,将 content传递给NotificationRequestUtil得到完整的发布信息,最后调用NotificationUtil.publishNotification()发布内容,并调用NotificationManagementUtil的addNotification()添加一条消息;
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License")
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { NotificationList } from '../components/NotificationList';
import { NoticePublish } from '../components/NotificationPublish';export interface TabImage {
selectedImage: Resource,
unselectedImage: Resource,
}const MESSAGE_TAB: TabImage = {
selectedImage: $r('app.media.ic_messages_filled'),
unselectedImage: $r('app.media.ic_messages'),
}
const NOTIFICATION_TAB: TabImage = {
selectedImage: $r('app.media.ic_public_send_filled'),
unselectedImage: $r('app.media.ic_public_send'),
}interface TAB_INDEX_TYPE {
MESSAGE_TAB: number
NOTIFICATION_TAB: number
}const TAB_INDEX: TAB_INDEX_TYPE = {
MESSAGE_TAB: 0,
NOTIFICATION_TAB: 1
}@Entry
@Component
struct Index {
@State tabsIndex: number = 0@Builder TabBarBuilder(index: number, item: TabImage, tabBarName: Resource) { Column() { Image(this.tabsIndex === index ? item.selectedImage : item.unselectedImage) .width(24) .height(24) .margin({ bottom: 10 }) Text(tabBarName) .fontSize(10) } .width('100%') .padding({ top: 0, bottom: 0 }) .alignItems(HorizontalAlign.Center) .id(`tabBar${index}`) } build() { Column() { Tabs({ barPosition: BarPosition.End }) { TabContent() { Column() { if (this.tabsIndex === TAB_INDEX.MESSAGE_TAB) { NotificationList() } Blank() } .height('100%') } .tabBar(this.TabBarBuilder(TAB_INDEX.MESSAGE_TAB, MESSAGE_TAB, $r('app.string.messages_list_title'))) TabContent() { Column() { NoticePublish() Blank() } .height('100%') } .tabBar(this.TabBarBuilder(TAB_INDEX.NOTIFICATION_TAB, NOTIFICATION_TAB, $r('app.string.notification_publish_title')),) } .barHeight(74) .barWidth('100%') .vertical(false) .onChange((index: number) => { this.tabsIndex = index }) }.width('100%').height('100%') .backgroundColor($r('app.color.background_light_gray')) }
}
以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线 ,展示如下:
除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下:
内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!
鸿蒙【北向应用开发+南向系统层开发】文档
鸿蒙【基础+实战项目】视频
鸿蒙面经
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!