《授权通知弹窗》一、NotificationManager模块指南
HarmonyOS NotificationManager 模块完全指南 —— 从入门到精通
适用版本:HarmonyOS 6.1.0 Release (API 23+) 及以上
关键词:NotificationManager、通知授权、权限管理、HarmonyOS开发
📋 效果
1. 模块概述
1.1 什么是 NotificationManager?
@ohos.notificationManager(NotificationManager 模块)是 HarmonyOS Notification Kit 的核心模块,负责管理应用的通知权限与通知发布能力。它提供了从权限检查、授权弹窗拉起到系统设置跳转的完整 API 链,是应用接入通知能力的第一步。
1.2 导入方式
import { notificationManager } from '@kit.NotificationKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
⚠️ 注意:
BusinessError必须从@kit.BasicServicesKit导入,不可遗漏。错误处理中需要使用err as BusinessError进行类型断言以获取code和message属性。
1.3 核心能力一览
| 能力分类 | 接口 | 说明 |
|---|---|---|
| 状态查询 | isNotificationEnabled() |
异步查询通知是否已授权 |
| 状态查询 | isNotificationEnabledSync() |
同步查询通知是否已授权 |
| 一次授权 | requestEnableNotification() |
拉起系统授权对话框 |
| 二次授权 | openNotificationSettings() |
跳转系统通知设置页面 |
| 通知发布 | publish() |
发布一条本地通知 |
| 通知取消 | cancel() / cancelAll() |
取消指定或全部通知 |
| 角标管理 | setBadgeNumber() |
设置桌面角标数字 |
2. 核心 API 详解
2.1 通知状态查询
通知授权状态查询是权限管理的起点。HarmonyOS 提供了同步和异步两种方式:
同步查询(推荐)
// 同步方式 - 性能更优,无需 await
const enabled: boolean = notificationManager.isNotificationEnabledSync();
if (enabled) {
console.info('通知权限已开启');
} else {
console.info('通知权限未开启');
}
优势:同步调用无需 async/await,执行效率更高,适合在
aboutToAppear()等生命周期中快速判断。
异步查询
// 异步方式 - Promise 风格
notificationManager.isNotificationEnabled()
.then((enabled: boolean) => {
if (enabled) {
console.info('通知权限已开启');
} else {
console.info('通知权限未开启');
}
})
.catch((err: BusinessError) => {
console.error(`查询失败: ${err.code}, ${err.message}`);
});
接口对比
| 特性 | isNotificationEnabledSync() |
isNotificationEnabled() |
|---|---|---|
| 调用方式 | 同步 | 异步(Promise) |
| 返回值 | boolean |
Promise<boolean> |
| API 版本 | 12+ | 9+ |
| 适用场景 | 快速状态判断 | 需要链式调用时 |
2.2 请求通知授权(一次授权)
requestEnableNotification() 是调用系统授权弹窗的核心接口。该接口仅在首次调用时弹出系统对话框,用户做出选择后,后续再次调用将不会弹窗。
async function requestPermission(context: common.UIAbilityContext): Promise<void> {
try {
await notificationManager.requestEnableNotification(context);
console.info('用户已授权通知权限');
} catch (err) {
const bizErr = err as BusinessError;
if (bizErr.code === 1600004) {
// 错误码 1600004 = 用户明确拒绝了授权
console.warn('用户拒绝了通知授权');
} else {
console.error(`请求授权失败: ${bizErr.code}, ${bizErr.message}`);
}
}
}
关键理解:
- 该方法返回 Promise,成功表示用户点击了"允许"
- 抛出异常且错误码为
1600004表示用户点击了"拒绝"- 用户拒绝后,该方法将永远不再弹窗,必须通过
openNotificationSettings()引导用户手动开启
调用时序图
2.3 打开通知设置页面(二次授权)
当用户在一次授权中拒绝了通知权限后,应用应通过 openNotificationSettings() 引导用户前往系统设置页面手动开启。
async function openSettings(context: common.UIAbilityContext): Promise<void> {
try {
await notificationManager.openNotificationSettings(context);
console.info('已跳转至系统通知设置页面');
} catch (err) {
const bizErr = err as BusinessError;
console.error(`打开设置失败: ${bizErr.code}, ${bizErr.message}`);
}
}
注意:
- 该接口拉起的是半模态通知管理页面,而非完全跳转到系统设置应用
- 页面关闭时,不会直接回调结果,需通过
onVisibilityChange()或onPageShow()重新检查状态- 该接口在用户拒绝授权后调用才有实际意义
3. 完整授权流程
3.1 推荐流程图
3.2 三步走策略
| 步骤 | 操作 | API | 说明 |
|---|---|---|---|
| Step 1 | 检查状态 | isNotificationEnabledSync() |
判断是否需要授权 |
| Step 2 | 一次授权 | requestEnableNotification() |
系统弹窗请求,仅首次生效 |
| Step 3 | 二次授权 | openNotificationSettings() |
引导用户去设置页面手动开启 |
4. 实战代码示例
4.1 完整授权管理工具类
以下是一个可以直接在项目中使用的通知授权管理工具类,封装了三种授权场景的处理逻辑:
import { notificationManager } from '@kit.NotificationKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const TAG: string = 'NotificationUtil';
const DOMAIN: number = 0x0000;
export class NotificationUtil {
/**
* 同步检查通知权限是否已启用
* @returns true=已启用, false=未启用
*/
static isNotificationEnabled(): boolean {
try {
return notificationManager.isNotificationEnabledSync();
} catch (err) {
hilog.error(DOMAIN, TAG, `检查通知状态异常`);
return false;
}
}
/**
* 请求通知授权 —— 一次授权
* 首次调用弹出系统授权对话框
* @param context UIAbilityContext
* @returns true=授权成功, false=用户拒绝
*/
static async requestPermission(context: common.UIAbilityContext): Promise<boolean> {
try {
await notificationManager.requestEnableNotification(context);
hilog.info(DOMAIN, TAG, '通知授权成功');
return true;
} catch (err) {
const bizErr = err as BusinessError;
if (bizErr.code === 1600004) {
hilog.warn(DOMAIN, TAG, '用户拒绝通知授权');
} else {
hilog.error(DOMAIN, TAG, `请求授权失败: ${bizErr.code}`);
}
return false;
}
}
/**
* 打开系统通知设置 —— 二次授权
* @param context UIAbilityContext
*/
static async openSettings(context: common.UIAbilityContext): Promise<void> {
try {
await notificationManager.openNotificationSettings(context);
hilog.info(DOMAIN, TAG, '已打开通知设置页面');
} catch (err) {
const bizErr = err as BusinessError;
hilog.error(DOMAIN, TAG, `打开设置失败: ${bizErr.code}`);
}
}
/**
* 智能授权流程:自动判断并执行完整的通知授权
* @param context UIAbilityContext
*/
static async smartAuthorize(context: common.UIAbilityContext): Promise<boolean> {
// Step 1: 检查是否已授权
if (this.isNotificationEnabled()) {
hilog.info(DOMAIN, TAG, '通知已授权,无需处理');
return true;
}
// Step 2: 一次授权
const granted = await this.requestPermission(context);
if (granted) {
return true;
}
// Step 3: 二次授权
hilog.info(DOMAIN, TAG, '一次授权被拒,引导用户去设置');
await this.openSettings(context);
return false;
}
}
4.2 在页面中使用
import { NotificationUtil } from '../utils/NotificationUtil';
import { common } from '@kit.AbilityKit';
@Entry
@ComponentV2
struct MyPage {
private context: common.UIAbilityContext =
this.getUIContext().getHostContext() as common.UIAbilityContext;
async aboutToAppear(): Promise<void> {
// 智能授权:自动处理全部流程
const authorized = await NotificationUtil.smartAuthorize(this.context);
if (authorized) {
console.info('通知权限已就绪');
}
}
build() {
Column() {
Text('我的页面')
}
}
}
4.3 使用 V2 状态管理集成
// 在 @ObservedV2 类中管理通知授权状态
@ObservedV2
class NotificationState {
@Trace isAuthorized: boolean = false;
@Trace isChecking: boolean = true;
public checkStatus(): void {
this.isChecking = true;
this.isAuthorized = notificationManager.isNotificationEnabledSync();
this.isChecking = false;
}
public async requestAuth(context: common.UIAbilityContext): Promise<void> {
try {
await notificationManager.requestEnableNotification(context);
this.isAuthorized = true;
} catch (err) {
const bizErr = err as BusinessError;
if (bizErr.code === 1600004) {
this.isAuthorized = false;
}
}
}
}
5. 错误码参考
| 错误码 | 说明 | 处理建议 |
|---|---|---|
1600001 |
内部错误 | 重试或检查系统状态 |
1600002 |
参数错误 | 检查 context 是否有效 |
1600003 |
连接通知服务失败 | 检查系统服务状态 |
1600004 |
用户拒绝通知授权 | 引导用户去设置页面手动开启 |
1600007 |
通知数量超过限制 | 清理不必要的通知 |
1600015 |
应用未被授权发布通知 | 先调用 requestEnableNotification |
重点关注
1600004:这是开发中最常遇到的错误码,代表用户在系统弹窗中点击了"拒绝"。此时不应再次调用requestEnableNotification()(它不会再弹窗),而应调用openNotificationSettings()引导用户手动设置。
6. 最佳实践与避坑指南
6.1 ✅ 推荐做法
-
使用同步 API 进行状态检查
// ✅ 推荐:同步检查,性能更好 const enabled = notificationManager.isNotificationEnabledSync(); -
先检查再请求,避免无效调用
// ✅ 推荐 if (!notificationManager.isNotificationEnabledSync()) { await notificationManager.requestEnableNotification(context); } -
提供二次授权入口,不放弃用户
// ✅ 推荐:拒绝后引导去设置 if (err.code === 1600004) { await notificationManager.openNotificationSettings(context); } -
使用 V2 状态管理驱动 UI 更新
// ✅ 推荐:@ObservedV2 + @Trace 实现细粒度更新 @ObservedV2 class AuthState { @Trace enabled: boolean = false; } -
在页面重新可见时重新检查状态
// ✅ 推荐:从设置页返回后重新检查 onVisibilityChange(visible: boolean): void { if (visible) { this.checkNotificationStatus(); } }
6.2 ❌ 常见错误
-
用户拒绝后反复调用
requestEnableNotification()// ❌ 错误:用户拒绝后该方法永不弹窗 for (let i = 0; i < 3; i++) { await notificationManager.requestEnableNotification(context); // 无效 } -
使用异步 API 做快速判断
// ❌ 不推荐:同步场景下多余的异步开销 const enabled = await notificationManager.isNotificationEnabled(); // ✅ 推荐 const enabled = notificationManager.isNotificationEnabledSync(); -
忽略错误码
1600004// ❌ 错误:未区分用户拒绝和其他错误 try { await notificationManager.requestEnableNotification(context); } catch (err) { // 所有错误统一处理,不区分用户拒绝 console.error('授权失败'); } -
忘记在页面恢复时重新检查状态
// ❌ 错误:从设置返回后未重新检查 // 用户可能在设置中手动开启了通知,但应用不知道
7. 总结
核心要点回顾
| 要点 | 说明 |
|---|---|
| 三个核心 API | isNotificationEnabledSync → 查状态 → requestEnableNotification → 一次授权 → openNotificationSettings → 二次授权 |
| 授权仅一次 | requestEnableNotification 只在首次调用时弹窗,用户拒绝后不再弹窗 |
| 二次授权 | 用户拒绝后必须通过 openNotificationSettings 引导手动开启 |
| 1600004 | 关键错误码,代表用户明确拒绝 |
| V2 状态管理 | 推荐使用 @ObservedV2 + @Trace 管理通知授权状态 |
学习路径建议
- 入门:理解三个核心 API 的作用和调用时机
- 进阶:封装工具类,实现智能授权流程
- 精通:结合 V2 状态管理和生命周期,打造无缝用户体验
📚 参考文档
更多推荐


所有评论(0)