当前位置: 首页 > news >正文

鸿蒙技术干货7:通知发送与跳转服务

今天开始咱们的系统服务调用系列分享。系统服务是鸿蒙应用与底层系统交互的核心通道,而通知服务(NotificationCenter)更是高频刚需 —— 无论是消息推送、事件提醒还是功能跳转,都离不开它。这篇咱们聚焦 NotificationCenter 的核心用法,从权限申请、通知创建到点击跳转,结合实战代码一步步拆解,为后续位置提醒 APP的开发打牢基础!

一、通知服务核心认知

1. 通知的应用场景

鸿蒙的通知服务支持多种场景:

  • 系统事件提醒(如位置到达、任务到期)

  • 应用内消息推送(如好友消息、更新提示)

  • 功能快捷入口(如通知栏直接操作应用功能)

  • 重要信息展示(如验证码、交易通知)

2. 核心 API 与权限要求

  • 核心模块:@ohos.notification(NotificationCenter)

  • 必备权限:ohos.permission.NOTIFICATION_CONTROLLER(API9+)

  • 关键能力:创建通知、设置样式、发送通知、监听点击事件、取消通知

二、通知开发三步走:权限 - 创建 - 发送

1. 权限申请(合规第一步)

通知权限属于普通权限,但仍需在配置文件声明并动态申请(部分设备默认关闭):

// module.json5 配置声明 { "module": { "requestPermissions": [ { "name": "ohos.permission.NOTIFICATION_CONTROLLER", "reason": "用于发送位置到达提醒通知", "usedScene": { "abilities": ["MainAbility"], "when": "always" } } ] } }

动态申请代码(结合权限管理模块):

import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; import notification from '@ohos.notification'; import common from '@ohos.app.ability.common'; /** * 检查并申请通知权限 */ export async function requestNotificationPermission(context: common.UIAbilityContext): Promise<boolean> { const atManager = abilityAccessCtrl.createAtManager(); try { // 检查权限状态 const authResult = await atManager.checkAccessToken( abilityAccessCtrl.createTokenID(), 'ohos.permission.NOTIFICATION_CONTROLLER' ); if (authResult === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { console.log('通知权限已授予'); return true; } // 动态申请权限 const reqResult = await atManager.requestPermissionsFromUser(context, ['ohos.permission.NOTIFICATION_CONTROLLER']); const granted = reqResult.authResults[0] === 0; console.log(`通知权限申请结果:${granted ? '成功' : '失败'}`); return granted; } catch (err) { console.error(`通知权限处理异常:${JSON.stringify(err)}`); return false; } }

2. 创建通知实例(自定义样式)

鸿蒙支持多种通知样式(普通通知、长文本通知、图片通知等),咱们以位置提醒场景常用的普通通知为例,包含标题、内容和跳转入口:

import notification from '@ohos.notification'; import wantAgent from '@ohos.wantAgent'; import common from '@ohos.app.ability.common'; /** * 创建位置提醒通知实例 * @param context 上下文 * @param title 通知标题 * @param content 通知内容 * @returns 通知实例 */ export async function createLocationReminderNotification( context: common.UIAbilityContext, title: string, content: string ): Promise<notification.Notification> { // 1. 创建跳转代理(点击通知跳转应用页面) const wantAgentInfo = { wants: [{ bundleName: context.applicationInfo.bundleName, abilityName: 'MainAbility', parameters: { 'from': 'notification', 'type': 'location_reminder' } // 携带跳转参数 }], operationType: wantAgent.OperationType.START_ABILITY, requestCode: 1002 }; const jumpAgent = await wantAgent.getWantAgent(wantAgentInfo); // 2. 构建通知内容 const notificationContent = new notification.NotificationContent({ contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title: title, text: content, additionalText: '点击查看详情' } }); // 3. 构建通知请求 const notificationRequest = { id: Date.now(), // 通知唯一ID(用于后续取消) content: notificationContent, wantAgent: jumpAgent, // 绑定跳转事件 priority: notification.Priority.HIGH, // 优先级(高优先级会主动弹窗) showOnLockScreen: true, // 锁屏显示 isAutoCancel: true // 点击后自动取消 }; return notificationRequest; }

3. 发送与取消通知

import notification from '@ohos.notification'; // 全局存储通知ID(用于取消) let currentNotificationId: number = -1; /** * 发送通知 */ export async function sendNotification(notificationRequest: notification.Notification): Promise<boolean> { try { // 保存通知ID currentNotificationId = notificationRequest.id; // 发送通知 await notification.publish(notificationRequest); console.log(`通知发送成功,ID:${currentNotificationId}`); return true; } catch (err) { console.error(`通知发送失败:${JSON.stringify(err)}`); return false; } } /** * 取消通知(单个或全部) */ export async function cancelNotification(notificationId?: number) { try { if (notificationId) { await notification.cancel(notificationId); console.log(`取消通知成功,ID:${notificationId}`); } else { await notification.cancelAll(); console.log('取消所有通知成功'); } } catch (err) { console.error(`取消通知失败:${JSON.stringify(err)}`); } }

三、实战:通知点击跳转与参数接收

1. 接收跳转参数

在目标 Ability 的onCreateonNewWant中接收通知跳转参数:

// MainAbility.ets onNewWant(want: Want) { // 接收通知跳转参数 const from = want.parameters?.['from']; const type = want.parameters?.['type']; if (from === 'notification' && type === 'location_reminder') { console.log('从位置提醒通知跳转进入'); // 跳转到位置详情页 this.context.startAbility({ url: 'pages/LocationDetailPage' }); } }

2. 完整调用流程(UI 组件触发)

@Entry @Component struct NotificationDemoPage { private context = getContext(this) as common.UIAbilityContext; build() { Column({ space: 30 }) .width('100%') .height('100%') .padding(30) .backgroundColor('#f5f5f5') { Text('通知服务演示') .fontSize(32) .fontWeight(FontWeight.Bold) Button('申请通知权限') .type(ButtonType.Capsule) .width(250) .height(60) .backgroundColor('#2f54eb') .onClick(async () => { const granted = await requestNotificationPermission(this.context); Toast.show({ message: granted ? '权限申请成功' : '权限申请失败' }); }) Button('发送位置提醒通知') .type(ButtonType.Capsule) .width(250) .height(60) .backgroundColor('#2f54eb') .onClick(async () => { const notification = await createLocationReminderNotification( this.context, '位置提醒', '您已到达目标区域,点击查看详情' ); const success = await sendNotification(notification); Toast.show({ message: success ? '通知发送成功' : '通知发送失败' }); }) Button('取消当前通知') .type(ButtonType.Capsule) .width(250) .height(60) .backgroundColor('#ff4d4f') .onClick(() => { cancelNotification(currentNotificationId); }) } } }

四、实战踩坑指南

1. 通知不显示的常见原因

❶ 未申请权限:务必先通过动态申请获取NOTIFICATION_CONTROLLER权限;

❷ 通知 ID 重复:每次发送建议使用唯一 ID(如时间戳),避免覆盖已有通知;

❸ 应用处于后台冻结状态:需确保应用有后台运行权限(后续系列会讲);

2. 跳转失败的解决方案

❶ 检查want参数:bundleNameabilityName必须与配置文件一致;

❷ 目标页面未注册:确保跳转的 Ability 或 Page 已在main_pages.json中配置;

❸ 权限不足:部分场景需申请ohos.permission.START_ABILITIES_FROM_BACKGROUND权限。

加入班级,学习鸿蒙开发

http://www.cnnetsun.cn/news/7502.html

相关文章:

  • 5分钟掌握PROPKA:蛋白质pKa预测的终极入门指南
  • dotNetFx40_Full_x86_x64:解决Windows开发环境配置难题的终极方案
  • 终极解决方案:如何快速解除Cursor试用限制
  • PMail个人邮件服务器:3步搭建私有邮箱的完整指南
  • 阿里自研Wan2.2-T2V-A14B如何实现720P高清视频生成?
  • 从0到1,普通开发者也能构建自己的AI Agent(附完整流程)
  • Bonree ONE 发布直通车| 如何利用核心链路,快速排查定位系统故障?
  • 数智先锋 | 博睿数据×海尔消费金融:破解高频并发与强监管难题!
  • Spring AOP 和 AspectJ 怎么选?核心区别一看就懂
  • 如何利用Wan2.2-T2V-A14B提升AIGC内容生产效率?
  • Atmosphere-NX系统升级遇阻?模块兼容性深度解析与实战修复方案
  • 3步掌握PLabel:开启高效半自动标注新时代
  • 专业视频对比工具video-compare:从入门到精通的完整指南
  • WebRTC-Streamer实战指南:从零构建低延迟实时视频系统
  • 深度解密:TensorFlow艺术生成双雄StyleNet与DeepDream实战指南
  • 全网最全——BMS原理之不平衡电桥法
  • 使用Hopfield神经网络解决旅行商问题
  • 基于STM32的温湿度、甲醛、PM2.5空气质量检测系统全套资料及功能详解
  • 40、Linux 软件开发与应用全解析
  • Code Llama-7b-hf 代码智能助手:从零开始掌握AI编程神器
  • 第7篇 目标检测(上):R-CNN家族的“两阶段”进化史
  • 如何快速部署鸿蒙远程投屏工具:HOScrcpy完整使用指南
  • 理解这几个安全漏洞,你也能做安全测试!
  • 爱美剧Mac客户端:重新定义你的美剧追剧体验
  • 告别手动关机:CMD命令效率提升全攻略
  • 终极汽车娱乐系统自定义工具完整指南:快速解锁隐藏功能
  • 小白必看:遇到‘地区不可用‘怎么办?3步解决
  • Wan2.2-T2V-A14B如何应对模糊文本输入的挑战?
  • 基于SpringBoot的计算思维与人工智能学习网站设计与实现
  • 【独家】工具链(Chained Tool Calls)全解析:大厂面试官最看重的技术点,附完整训练方案