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

【FAQ】HarmonyOS SDK 闭源开放能力 — Notification Kit

1.问题描述:

获取应用是否开启了允许通知权限后,如何引导跳转开启权限通知的设置页面?

解决方案:

  1. 通过isNotificationEnabled方法查询通知是否授权,参考isNotificationEnabled用法。

2.若申请通知权限被拒绝后,后续调用requestEnableNotification()方法不再弹窗,同时会返回错误,错误码是1600004。具体参考请求通知授权。

3.如果想二次授权,可以调用openNotificationSettings申请授权,拉起通知管理弹窗或者引导用户跳转应用设置页面开启权限。

完整代码示例如下:


import { notificationManager } from '@kit.NotificationKit';import { BusinessError } from '@kit.BasicServicesKit';import { common } from '@kit.AbilityKit';import { Want } from '@kit.AbilityKit';@Entry@Componentstruct NotificationPage {aboutToAppear(): void {let context = this.getUIContext().getHostContext() as common.UIAbilityContext;notificationManager.isNotificationEnabled().then((data: boolean) => {console.info("isNotificationEnabled success, data: " + data);if (!data) {let requestEnableNotificationCallback = (err: BusinessError): void => {if (err) {console.error(`requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);} else {console.info(`requestEnableNotification success`);}};notificationManager.requestEnableNotification(context, requestEnableNotificationCallback);}}).catch((err: BusinessError) => {console.error(`isNotificationEnabled fail, code is ${err.code}, message is ${err.message}`);});}// 发布基本类型通知publishBasicNotification() {let notificationRequest: notificationManager.NotificationRequest = {id: 1,notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,content: {notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知normal: {title: '基本型消息通知',text: '通知内容XXXXXXX',additionalText: 'TextXXXXXXX',}}};notificationManager.publish(notificationRequest, (err: BusinessError) => {if (err) {console.error(`Failed to publish notification. Code is ${err.code}, message is ${err.message}`);return;}console.info('Succeeded in publishing notification.');});notificationManager.setBadgeNumber(1)}build() {Column() {Button('基本通知').onClick(() => {this.publishBasicNotification()})Button('二次授权').margin({ top: 20 }).onClick(() => {let context = this.getUIContext().getHostContext() as common.UIAbilityContext;notificationManager.openNotificationSettings(context).then(() => {console.info(`openNotificationSettings success`);}).catch((err: BusinessError) => {console.error(`openNotificationSettings failed, code is ${err.code}, message is ${err.message}`);});})Button('点击进入应用设置页面').margin({ top: 20 }).onClick(() => {let context = this.getUIContext().getHostContext() as common.UIAbilityContext;let want: Want = {bundleName: 'com.huawei.hmos.settings',abilityName: 'com.huawei.hmos.settings.MainAbility',uri: 'application_info_entry',parameters: {pushParams: "com.example.myapplication" // 配置应用包名}};context.startAbility(want).then(() => {}).catch((err: BusinessError) => {console.error(`Code is ${err.code}, message is ${err.message}`)});})}.alignItems(HorizontalAlign.Center).width('100%').height('100%')}}

2.问题描述:

使用notificationManager.openNotificationSettings接口打开的弹窗,如何监听弹窗关闭事件?

解决方案:

在页面打开应用通知设置页。

openNotificationSettings接口拉起的设置页面,页面关闭的时候没有回调方法可以直接使用,但是该接口拉起的页面关闭的时候,会触发其他页面聚焦的回调,在这个页面的根组件上注册的onfocus事件,在该回调内自定义一些操作,比如调用isNotificationEnabledSync()来查询应用通知的开启状态。具体实现代码如下:


import { notificationManager } from '@kit.NotificationKit';import { BusinessError } from '@kit.BasicServicesKit';import { common } from '@kit.AbilityKit';@Entry@Componentstruct NotificationManagerDemo {// 组件聚焦状态@State focusState: boolean = truebuild() {Column() {Button('打开弹窗').onClick(() => {let context = this.getUIContext().getHostContext() as common.UIAbilityContext;// 拉起应用通知设置页面notificationManager.openNotificationSettings(context).then(() => {console.info('页面拉起成功')// 拉起成功,改变页面聚焦状态this.focusState = false}).catch((err: BusinessError) => {console.info('页面拉起失败')});})}.onFocus(() => {// 组件聚焦的回调if (!this.focusState) {// 做一些自己的操作console.info('应用通知页面关闭')// 查询通知开关是否开启let res = notificationManager.isNotificationEnabledSync()console.info(`是否开启应用通知:${res}`)this.getUIContext().getPromptAction().showToast({ message: `是否开启应用通知:${res}` })// 重置组件聚焦状态this.focusState = !this.focusState}})}}

3.问题描述:

notificationManager.openNotificationSettings唤起半模态框,如何监听消失并读取最新通知开启状态?

解决方案:

封装通知管理工具类,全局使用。

  1. 创建通知管理工具类:

// NotificationUtil.tsimport { notificationManager } from '@kit.NotificationKit';import { BusinessError } from '@kit.BasicServicesKit';import { common } from '@kit.AbilityKit';/*** 通知管理工具类*/export class NotificationUtil {private static instance: NotificationUtil;private context: common.UIAbilityContext | null = null;private focusStateCallbacks: Array&lt;(isFocused: boolean) =&gt; void&gt; = [];private constructor() {}/*** 获取单例实例*/public static getInstance(): NotificationUtil {if (!NotificationUtil.instance) {NotificationUtil.instance = new NotificationUtil();}return NotificationUtil.instance;}/*** 初始化工具类(必须在应用启动时调用)* @param context UIAbility上下文*/public initialize(context: common.UIAbilityContext): void {this.context = context;}/*** 打开通知设置页面* @returns Promise<boolean> 是否成功打开*/public async openNotificationSettings(): Promise<boolean> {if (!this.context) {console.error('NotificationUtil 未初始化,请先调用 initialize 方法');return false;}try {await notificationManager.openNotificationSettings(this.context);console.info('通知设置页面拉起成功');return true;} catch (err) {const error = err as BusinessError;console.error(`通知设置页面拉起失败: ${error.code} - ${error.message}`);return false;}}/*** 检查通知是否开启(同步)* @returns boolean 通知是否开启*/public isNotificationEnabled(): boolean {try {return notificationManager.isNotificationEnabledSync();} catch (err) {const error = err as BusinessError;console.error(`检查通知状态失败: ${error.code} - ${error.message}`);return false;}}/*** 检查通知是否开启(异步)* @returns Promise<boolean> 通知是否开启*/public async isNotificationEnabledAsync(): Promise<boolean> {try {return await notificationManager.isNotificationEnabled();} catch (err) {const error = err as BusinessError;console.error(`异步检查通知状态失败: ${error.code} - ${error.message}`);return false;}}/*** 注册页面聚焦状态回调* @param callback 回调函数*/public registerFocusCallback(callback: (isFocused: boolean) =&gt; void): void {this.focusStateCallbacks.push(callback);}/*** 注销页面聚焦状态回调* @param callback 回调函数*/public unregisterFocusCallback(callback: (isFocused: boolean) =&gt; void): void {const index = this.focusStateCallbacks.indexOf(callback);if (index &gt; -1) {this.focusStateCallbacks.splice(index, 1);}}/*** 处理页面聚焦事件(需要在页面onFocus中调用)* @param isFocused 是否聚焦*/public handleFocusChange(isFocused: boolean): void {this.focusStateCallbacks.forEach(callback =&gt; {try {callback(isFocused);} catch (err) {console.error('焦点状态回调执行失败:', err);}});}/*** 完整的打开通知设置并监听返回的流程* @param onReturnCallback 返回时的回调函数* @returns Promise<boolean> 是否成功执行*/public async openSettingsAndListenReturn(onReturnCallback?: (isEnabled: boolean) =&gt; void): Promise<boolean> {if (!this.context) {console.error('NotificationUtil 未初始化');return false;}const success = await this.openNotificationSettings();if (success &amp;&amp; onReturnCallback) {// 注册一次性回调const tempCallback = (isFocused: boolean) =&gt; {if (isFocused) {const isEnabled = this.isNotificationEnabled();onReturnCallback(isEnabled);// 执行后立即注销this.unregisterFocusCallback(tempCallback);}};this.registerFocusCallback(tempCallback);}return success;}}// 导出默认实例export default NotificationUtil.getInstance();
  1. 在应用入口初始化工具类:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {try {this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);// 初始化通知工具类NotificationUtil.initialize(this.context);} catch (err) {hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));}hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');}
  1. 使用封装后的工具类:

import NotificationUtil from './NotificationUtil';@Entry@Componentstruct NotificationManagerDemo {@State focusState: boolean = truebuild() {Column() {Button('打开应用通知设置页').onClick(async () =&gt; {await NotificationUtil.openSettingsAndListenReturn((isEnabled: boolean) =&gt; {console.info('从设置页面返回,通知状态:', isEnabled);this.getUIContext().getPromptAction().showToast({message: `通知状态: ${isEnabled ? '已开启' : '已关闭'}`});});})}.width('100%').height('100%').justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center).onFocus(() =&gt; {// 将焦点变化传递给工具类NotificationUtil.handleFocusChange(true);}).onBlur(() =&gt; {NotificationUtil.handleFocusChange(false);})}}

4.问题描述:

如何直接以弹窗方式打开通知管理页面?

解决方案:

  1. 通过isNotificationEnabled方法查询通知是否授权,参考isNotificationEnabled用法。

  2. 若申请通知权限被拒绝后,后续调用requestEnableNotification()方法不再弹窗,同时会返回错误,错误码是1600004。具体参考请求通知授权。

如果想二次授权,可以调用openNotificationSettings申请授权,拉起通知管理弹窗。或者引导用户跳转应用设置页面开启权限,跳转设置页面方法如下:


let context = getContext(this) as common.UIAbilityContext;let want: Want = {bundleName: 'com.huawei.hmos.settings',abilityName: 'com.huawei.hmos.settings.MainAbility',uri: 'application_info_entry',parameters: {pushParams: "bundleName" // 配置应用包名}};context.startAbility(want).then(() =&gt; {}).catch((err: BusinessError) =&gt; {console.error(`Code is ${err.code}, message is ${err.message}`)});

5.问题描述:

notificationManager.requestEnableNotification err.code:1600013,原因是什么?

解决方案:

【背景知识】

应用需要获取用户授权才能发送通知。在通知发布前调用requestEnableNotification()方法,弹窗让用户选择是否允许发送通知,后续再次调用requestEnableNotification()方法时,则不再弹窗。可参考文档请求通知权限。

【问题定位】

  1. 权限请求时机问题,需要在UI加载后再申请。

  2. 是否绑定UiAbilityContext,context是否正常初始化。

  3. 以前有异常弹出的场景,产生了脏数据。

  4. 检查相关参数HashMap使用是否正确。

【分析结论】

  1. 1600013,若窗口未加载完成就请求了通知,导致渲染异常,再次请求就会报这个错,尽量在窗口创建并渲染后再调用。

  2. 建议在entryAbility中调用,或是在对应的页面中调用,不建议在授权时切换页面。

【修改建议】

针对报错code:1600013,可以采用以下两种方案:

  1. 执行重启手机、删除应用的操作,清理脏数据后再次安装应用尝试。申请通知权限代码改为在ui加载后再申请。代码示例:

windowStage.loadContent('pages/Index', (err) =&gt; {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}notificationManager.requestEnableNotification().then(() =&gt; {hilog.info(0x0000, '’testTag', 'requestEnableNotification success');}).catch((error: BusinessError) =&gt; {hilog.error(0x0000, 'testTag', 'requestEnableNotification error : %{public}s', JSON.stringify(error))})hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');});
  1. 绑定UiAbilityContext使用模态弹窗方式,初始化context。代码示例:

let context = getContext(this) as common.UIAbilityContext;notificationManager.isNotificationEnabled().then((data: boolean) =&gt; {hilog.info(DOMAIN_NUMBER, TAG, "isNotificationEnabled success, data: " + JSON.stringify(data));if(!data){notificationManager.requestEnableNotification(context).then(() =&gt; {hilog.info(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification success`);}).catch((err : BusinessError) =&gt; {if(1600004 == err.code){hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification refused, code is ${err.code}, message is ${err.message}`);} else {hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);}});}}).catch((err : BusinessError) =&gt; {hilog.error(DOMAIN_NUMBER, TAG, `isNotificationEnabled fail: ${JSON.stringify(err)}`);});
  • 不在授权时切换页面,建议在window.loadContent回调中请求权限。

http://www.jsqmd.com/news/43672/

相关文章:

  • 2025年中国试验机厂家推荐榜:十强排名与性能评测(山东万辰、盛林试验机领衔国产标杆)
  • 2025 最新压花辊源头厂家权威推荐榜:国际协会测评认证,覆盖多材质适用场景的品质厂商精选布料压花辊 / 木材压花辊 / 真皮压花辊 / 铝膜压花辊 / 珍珠棉压花辊 / 薄膜压花辊公司推荐
  • 2025年铝爬架网厂家权威推荐:新型建筑爬架网/米字爬架网/外墙建筑爬架网源头厂家精选
  • CPP 格式化文件 .clang-format
  • 2025年智能化矿山模型沙盘实力厂家权威推荐榜单:煤矿地质模型/井下开采仿真模型/智能矿井模型源头厂家精选
  • com.unitree.doggo2
  • 通过SSH转发端口
  • Codeforces Round 1064题解
  • 2025 最新工业检测仪源头厂家推荐排行榜:粉尘气体 / 颗粒物 / 固体流量等设备靠谱企业精选固体流量/空间环境粉尘/便携式粉尘检测仪公司推荐
  • CVPR 2024 目标检测!开放词汇
  • 国标GB28181算法算力平台EasyGBS如何实现停车场监控系统的高效统一管理?
  • LiteFlow(规则引擎)
  • SCQL:安全协同查询平台的技术解析
  • linux apache 解析php
  • idea中maven转gradle
  • linux apache 版本
  • LINUX在线扩文件系统(/目录)
  • linux apache 服务器搭建
  • linux apache 域名配置
  • 2025济南留学中介十大排名
  • 2025杭州最好的留学中介是哪家公司
  • 2025成都留学机构十强名单最新
  • 2025年11月国内PMS酒店管理系统公司排行榜:智能化升级的十大优选方案
  • 荒原之梦考研数学:26考研最后冲刺阶段还要重点学习考研数学吗?
  • virtualbox新建centos虚拟机并配置双网卡
  • 687
  • 2025年预防性维护用热像仪厂家权威推荐榜单:手持测温热像仪/TiX560/TiX520红外热像仪/手机测温热像仪源头厂家精选
  • 荒原之梦考研数学 | 做选填题,就不要局限于所用的方法
  • 767
  • drf 查找