今天开始咱们的系统服务调用系列分享。系统服务是鸿蒙应用与底层系统交互的核心通道,而通知服务(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 的onCreate或onNewWant中接收通知跳转参数:
// 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参数:bundleName和abilityName必须与配置文件一致;
❷ 目标页面未注册:确保跳转的 Ability 或 Page 已在main_pages.json中配置;
❸ 权限不足:部分场景需申请ohos.permission.START_ABILITIES_FROM_BACKGROUND权限。
加入班级,学习鸿蒙开发