鸿蒙应用服务开发【自定义通知角标】

embedded/2024/10/18 19:47:36/

自定义通知角标

介绍

本示例主要展示了设定应用的桌面图标角标的功能,使用@ohos.notificationManager接口,进行桌面角标的设置,通知的发送,获取等。

效果预览

1

使用说明

  1. 在主界面,可以看到当前应用的所有消息通知;
  2. 点击右下角Tab页签进入通知发送页面,点击对应的通知即可发送相应类型的通知,点击几次发送几条;
  3. 点击左下角Tab页签进入消息列表,可以查看刚才发送的消息,消息右边会显示消息数量,点击相应的消息可进行消息读取,取消相应通知;
  4. 下拉通知栏,可以看到角标数量,对应消息数量。

具体实现

  • 允许发送通知,发送通知的功能接口封装在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: numberNOTIFICATION_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: stringLONG_TEXT: stringMULTI_LINE: stringPICTURE: stringCONVERSATION: 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: numberNOTIFICATION_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'))}
}

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!


http://www.ppmy.cn/embedded/93352.html

相关文章

【经验分享】ShardingSphere+Springboot-04:自定义分片算法(COMPLEX/STANDARD)

文章目录 3.4 CLASS_BASED 自定义类分片算法3.4.1 复杂分片自定义算法&#xff08;strategyCOMPLEX &#xff09;3.4.2 STANDARD 标准分片自定义算法## 进阶:star: 自定义算法范围查询优化 3.4 CLASS_BASED 自定义类分片算法 3.4.1 复杂分片自定义算法&#xff08;strategyCOM…

Linux部署MySQL8.0

目录 一、部署前准备1.1、查看系统版本和位数&#xff08;32位或64位&#xff09;1.2、下载对应安装包 二、开始部署1、将安装包解压并且移动到目标安装目录2、准备MySQL数据和日志等存储文件夹3、准备MySQL配置文件 my.cnf4、创建mysql单独用户组和用户&#xff0c;将安装目录…

【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 一、树 1.树的概念与结构 2.树的相关术语 3.树的表示方法 4.树型结构的实际应用场景 二、二叉树 1.二叉树的概念与结构 2.二叉树的…

在CentOS 7上安装Git的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 版本控制已经成为现代软件开发中不可或缺的工具。版本控制系统允许您在源代码级别跟踪软件。您可以跟踪更改、恢复到先前阶段&…

敏捷与DevOps有什么不同?

在软件开发领域&#xff0c;敏捷和DevOps因其对效率、协作和交付高质量产品的关注而受到欢迎。尽管它们有不同的目标&#xff0c;敏捷和DevOps常常被交替使用。本文旨在阐明这些方法之间的区别和共性&#xff0c;展示它们如何无缝协同以产生结果。 图源自Browser Stack 了解敏捷…

Java面试篇(线程池相关专题)

文章目录 1. 为什么要使用线程池2. 线程池的核心参数和线程池的执行原理2.1 线程池的核心参数2.2 线程池的执行原理 3. 线程池中常见的阻塞队列3.1 常见的阻塞队列3.2 ArrayBlockingQueue 和 LinkedBlockingQueue 的区别 4. 如何确定线程池的核心线程数4.1 应用程序中任务的类型…

利用python写一个可视化的界面

要利用Python编写一个可视化界面&#xff0c;你可以使用一些图形库来实现&#xff0c;例如Tkinter、PyQt、wxPython等。以下是一个使用Tkinter的示例代码&#xff1a; import tkinter as tk# 创建一个窗口对象 window tk.Tk()# 定义一个按钮点击事件的处理函数 def buttonCli…

Linux Vim教程

Linux Vim 教程 Vim&#xff08;Vi IMproved&#xff09;是一个强大的文本编辑器&#xff0c;广泛用于编程和系统管理。本文将带你全面了解 Vim 的基础使用、常用命令、高级功能等。 1. 安装 Vim 在大多数 Linux 发行版中&#xff0c;Vim 已经预装。如果没有&#xff0c;可以…