【FAQ】HarmonyOS SDK 闭源开放本事 — Notification Kit [复制链接]
发表于 2025-11-18 13:58:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1.标题形貌:
获取应用是否开启了答应关照权限后,怎样引导跳转开启权限关照的设置页面?
办理方案:

  • 通过isNotificationEnabled方法查询关照是否授权,参考isNotificationEnabled用法。
2.若申请关照权限被拒绝后,后续调用requestEnableNotification()方法不再弹窗,同时会返回错误,错误码是1600004。详细参考哀求关照授权。
3.如果想二次授权,可以调用openNotificationSettings申请授权,拉起关照管理弹窗大概引导用户跳转应用设置页面开启权限。
完备代码示比方下:
  1. import { notificationManager } from '@kit.NotificationKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { common } from '@kit.AbilityKit';
  4. import { Want } from '@kit.AbilityKit';
  5. @Entry
  6. @Component
  7. struct NotificationPage {
  8.   aboutToAppear(): void {
  9.     let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  10.     notificationManager.isNotificationEnabled().then((data: boolean) => {
  11.       console.info("isNotificationEnabled success, data: " + data);
  12.       if (!data) {
  13.         let requestEnableNotificationCallback = (err: BusinessError): void => {
  14.           if (err) {
  15.             console.error(`requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);
  16.           } else {
  17.             console.info(`requestEnableNotification success`);
  18.           }
  19.         };
  20.         notificationManager.requestEnableNotification(context, requestEnableNotificationCallback);
  21.       }
  22.     }).catch((err: BusinessError) => {
  23.       console.error(`isNotificationEnabled fail, code is ${err.code}, message is ${err.message}`);
  24.     });
  25.   }
  26.   // 发布基本类型通知
  27.   publishBasicNotification() {
  28.     let notificationRequest: notificationManager.NotificationRequest = {
  29.       id: 1,
  30.       notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,
  31.       content: {
  32.         notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
  33.         normal: {
  34.           title: '基本型消息通知',
  35.           text: '通知内容XXXXXXX',
  36.           additionalText: 'TextXXXXXXX',
  37.         }
  38.       }
  39.     };
  40.     notificationManager.publish(notificationRequest, (err: BusinessError) => {
  41.       if (err) {
  42.         console.error(`Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
  43.         return;
  44.       }
  45.       console.info('Succeeded in publishing notification.');
  46.     });
  47.     notificationManager.setBadgeNumber(1)
  48.   }
  49.   build() {
  50.     Column() {
  51.       Button('基本通知')
  52.         .onClick(() => {
  53.           this.publishBasicNotification()
  54.         })
  55.       Button('二次授权')
  56.         .margin({ top: 20 })
  57.         .onClick(() => {
  58.           let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  59.           notificationManager.openNotificationSettings(context).then(() => {
  60.             console.info(`openNotificationSettings success`);
  61.           }).catch((err: BusinessError) => {
  62.             console.error(`openNotificationSettings failed, code is ${err.code}, message is ${err.message}`);
  63.           });
  64.         })
  65.       Button('点击进入应用设置页面')
  66.         .margin({ top: 20 })
  67.         .onClick(() => {
  68.           let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  69.           let want: Want = {
  70.             bundleName: 'com.huawei.hmos.settings',
  71.             abilityName: 'com.huawei.hmos.settings.MainAbility',
  72.             uri: 'application_info_entry',
  73.             parameters: {
  74.               pushParams: "com.example.myapplication" // 配置应用包名
  75.             }
  76.           };
  77.           context.startAbility(want).then(() => {
  78.           }).catch((err: BusinessError) => {
  79.             console.error(`Code is ${err.code}, message is ${err.message}`)
  80.           });
  81.         })
  82.     }
  83.     .alignItems(HorizontalAlign.Center)
  84.     .width('100%')
  85.     .height('100%')
  86.   }
  87. }
复制代码
2.标题形貌:
使用notificationManager.openNotificationSettings接口打开的弹窗,怎样监听弹窗关闭变乱?
办理方案:
在页面打开应用关照设置页。
openNotificationSettings接口拉起的设置页面,页面关闭的时间没有回调方法可以直接使用,但是该接口拉起的页面关闭的时间,会触发其他页面聚焦的回调,在这个页面的根组件上注册的onfocus变乱,在该回调内自界说一些利用,比如调用isNotificationEnabledSync()来查询应用关照的开启状态。详细实当代码如下:
  1. import { notificationManager } from '@kit.NotificationKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { common } from '@kit.AbilityKit';
  4. @Entry
  5. @Component
  6. struct NotificationManagerDemo {
  7.   // 组件聚焦状态
  8.   @State focusState: boolean = true
  9.   build() {
  10.     Column() {
  11.       Button('打开弹窗')
  12.         .onClick(() => {
  13.           let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  14.           // 拉起应用通知设置页面
  15.           notificationManager.openNotificationSettings(context).then(() => {
  16.             console.info('页面拉起成功')
  17.             // 拉起成功,改变页面聚焦状态
  18.             this.focusState = false
  19.           }).catch((err: BusinessError) => {
  20.             console.info('页面拉起失败')
  21.           });
  22.         })
  23.     }
  24.     .onFocus(() => {
  25.       // 组件聚焦的回调
  26.       if (!this.focusState) {
  27.         // 做一些自己的操作
  28.         console.info('应用通知页面关闭')
  29.         // 查询通知开关是否开启
  30.         let res = notificationManager.isNotificationEnabledSync()
  31.         console.info(`是否开启应用通知:${res}`)
  32.         this.getUIContext().getPromptAction().showToast({ message: `是否开启应用通知:${res}` })
  33.         // 重置组件聚焦状态
  34.         this.focusState = !this.focusState
  35.       }
  36.     })
  37.   }
  38. }
复制代码
3.标题形貌:
notificationManager.openNotificationSettings唤起半模态框,怎样监听消散并读取最新关照开启状态?
办理方案:
封装关照管理工具类,全局使用。

  • 创建关照管理工具类:
  1. // NotificationUtil.ts
  2. import { notificationManager } from '@kit.NotificationKit';
  3. import { BusinessError } from '@kit.BasicServicesKit';
  4. import { common } from '@kit.AbilityKit';
  5. /**
  6. * 通知管理工具类
  7. */
  8. export class NotificationUtil {
  9.   private static instance: NotificationUtil;
  10.   private context: common.UIAbilityContext | null = null;
  11.   private focusStateCallbacks: Array<(isFocused: boolean) => void> = [];
  12.   private constructor() {
  13.   }
  14.   /**
  15.    * 获取单例实例
  16.    */
  17.   public static getInstance(): NotificationUtil {
  18.     if (!NotificationUtil.instance) {
  19.       NotificationUtil.instance = new NotificationUtil();
  20.     }
  21.     return NotificationUtil.instance;
  22.   }
  23.   /**
  24.    * 初始化工具类(必须在应用启动时调用)
  25.    * @param context UIAbility上下文
  26.    */
  27.   public initialize(context: common.UIAbilityContext): void {
  28.     this.context = context;
  29.   }
  30.   /**
  31.    * 打开通知设置页面
  32.    * @returns Promise<boolean> 是否成功打开
  33.    */
  34.   public async openNotificationSettings(): Promise<boolean> {
  35.     if (!this.context) {
  36.       console.error('NotificationUtil 未初始化,请先调用 initialize 方法');
  37.       return false;
  38.     }
  39.     try {
  40.       await notificationManager.openNotificationSettings(this.context);
  41.       console.info('通知设置页面拉起成功');
  42.       return true;
  43.     } catch (err) {
  44.       const error = err as BusinessError;
  45.       console.error(`通知设置页面拉起失败: ${error.code} - ${error.message}`);
  46.       return false;
  47.     }
  48.   }
  49.   /**
  50.    * 检查通知是否开启(同步)
  51.    * @returns boolean 通知是否开启
  52.    */
  53.   public isNotificationEnabled(): boolean {
  54.     try {
  55.       return notificationManager.isNotificationEnabledSync();
  56.     } catch (err) {
  57.       const error = err as BusinessError;
  58.       console.error(`检查通知状态失败: ${error.code} - ${error.message}`);
  59.       return false;
  60.     }
  61.   }
  62.   /**
  63.    * 检查通知是否开启(异步)
  64.    * @returns Promise<boolean> 通知是否开启
  65.    */
  66.   public async isNotificationEnabledAsync(): Promise<boolean> {
  67.     try {
  68.       return await notificationManager.isNotificationEnabled();
  69.     } catch (err) {
  70.       const error = err as BusinessError;
  71.       console.error(`异步检查通知状态失败: ${error.code} - ${error.message}`);
  72.       return false;
  73.     }
  74.   }
  75.   /**
  76.    * 注册页面聚焦状态回调
  77.    * @param callback 回调函数
  78.    */
  79.   public registerFocusCallback(callback: (isFocused: boolean) => void): void {
  80.     this.focusStateCallbacks.push(callback);
  81.   }
  82.   /**
  83.    * 注销页面聚焦状态回调
  84.    * @param callback 回调函数
  85.    */
  86.   public unregisterFocusCallback(callback: (isFocused: boolean) => void): void {
  87.     const index = this.focusStateCallbacks.indexOf(callback);
  88.     if (index > -1) {
  89.       this.focusStateCallbacks.splice(index, 1);
  90.     }
  91.   }
  92.   /**
  93.    * 处理页面聚焦事件(需要在页面onFocus中调用)
  94.    * @param isFocused 是否聚焦
  95.    */
  96.   public handleFocusChange(isFocused: boolean): void {
  97.     this.focusStateCallbacks.forEach(callback => {
  98.       try {
  99.         callback(isFocused);
  100.       } catch (err) {
  101.         console.error('焦点状态回调执行失败:', err);
  102.       }
  103.     });
  104.   }
  105.   /**
  106.    * 完整的打开通知设置并监听返回的流程
  107.    * @param onReturnCallback 返回时的回调函数
  108.    * @returns Promise<boolean> 是否成功执行
  109.    */
  110.   public async openSettingsAndListenReturn(onReturnCallback?: (isEnabled: boolean) => void): Promise<boolean> {
  111.     if (!this.context) {
  112.       console.error('NotificationUtil 未初始化');
  113.       return false;
  114.     }
  115.     const success = await this.openNotificationSettings();
  116.     if (success && onReturnCallback) {
  117.       // 注册一次性回调
  118.       const tempCallback = (isFocused: boolean) => {
  119.         if (isFocused) {
  120.           const isEnabled = this.isNotificationEnabled();
  121.           onReturnCallback(isEnabled);
  122.           // 执行后立即注销
  123.           this.unregisterFocusCallback(tempCallback);
  124.         }
  125.       };
  126.       this.registerFocusCallback(tempCallback);
  127.     }
  128.     return success;
  129.   }
  130. }
  131. // 导出默认实例
  132. export default NotificationUtil.getInstance();
复制代码

  • 在应用入口初始化工具类:
  1.   onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  2.     try {
  3.       this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
  4.       // 初始化通知工具类
  5.       NotificationUtil.initialize(this.context);
  6.     } catch (err) {
  7.       hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
  8.     }
  9.     hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
  10.   }
复制代码

  • 使用封装后的工具类:
  1. import NotificationUtil from './NotificationUtil';
  2. @Entry
  3. @Component
  4. struct NotificationManagerDemo {
  5.   @State focusState: boolean = true
  6.   build() {
  7.     Column() {
  8.       Button('打开应用通知设置页')
  9.         .onClick(async () => {
  10.           await NotificationUtil.openSettingsAndListenReturn((isEnabled: boolean) => {
  11.             console.info('从设置页面返回,通知状态:', isEnabled);
  12.             this.getUIContext().getPromptAction().showToast({
  13.               message: `通知状态: ${isEnabled ? '已开启' : '已关闭'}`
  14.             });
  15.           });
  16.         })
  17.     }
  18.     .width('100%')
  19.     .height('100%')
  20.     .justifyContent(FlexAlign.Center)
  21.     .alignItems(HorizontalAlign.Center)
  22.     .onFocus(() => {
  23.       // 将焦点变化传递给工具类
  24.       NotificationUtil.handleFocusChange(true);
  25.     })
  26.     .onBlur(() => {
  27.       NotificationUtil.handleFocusChange(false);
  28.     })
  29.   }
  30. }
复制代码
4.标题形貌:
怎样直接以弹窗方式打开关照管理页面?
办理方案:

  • 通过isNotificationEnabled方法查询关照是否授权,参考isNotificationEnabled用法
  • 若申请关照权限被拒绝后,后续调用requestEnableNotification()方法不再弹窗,同时会返回错误,错误码是1600004。详细参考哀求关照授权
如果想二次授权,可以调用openNotificationSettings申请授权,拉起关照管理弹窗。大概引导用户跳转应用设置页面开启权限,跳转设置页面方法如下:
  1. let context = getContext(this) as common.UIAbilityContext;
  2. let want: Want = {
  3.   bundleName: 'com.huawei.hmos.settings',
  4.   abilityName: 'com.huawei.hmos.settings.MainAbility',
  5.   uri: 'application_info_entry',
  6.   parameters: {
  7.     pushParams: "bundleName" // 配置应用包名
  8.   }
  9. };
  10. context.startAbility(want).then(() => {
  11. }).catch((err: BusinessError) => {
  12.   console.error(`Code is ${err.code}, message is ${err.message}`)
  13. });
复制代码
5.标题形貌:
notificationManager.requestEnableNotification err.code:1600013,缘故因由是什么?
办理方案:
【配景知识】
应用必要获取用户授权才华发送关照。在关照发布前调用requestEnableNotification()方法,弹窗让用户选择是否答应发送关照,后续再次调用requestEnableNotification()方法时,则不再弹窗。可参考文档哀求关照权限
【标题定位】

  • 权限哀求机遇标题,必要在UI加载后再申请。
  • 是否绑定UiAbilityContext,context是否正常初始化。
  • 从前有非常弹出的场景,产生了脏数据。
  • 查抄相干参数HashMap使用是否准确。
【分析结论】

  • 1600013,若窗口未加载完结果哀求了关照,导致渲染非常,再次哀求就会报这个错,只管在窗口创建并渲染后再调用。
  • 发起在entryAbility中调用,或是在对应的页面中调用,不发起在授权时切换页面。
【修改发起】
针对报错code:1600013,可以接纳以下两种方案:

  • 实行重启手机、删除应用的利用,整理脏数据后再次安装应用实验。申请关照权限代码改为在ui加载后再申请。代码示例:
  1. windowStage.loadContent('pages/Index', (err) => {
  2.      if (err.code) {
  3.        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
  4.        return;
  5.      }
  6.      notificationManager.requestEnableNotification().then(() => {
  7.        hilog.info(0x0000, '’testTag', 'requestEnableNotification success');
  8.      })
  9.        .catch((error: BusinessError) => {
  10.          hilog.error(0x0000, 'testTag', 'requestEnableNotification error : %{public}s', JSON.stringify(error))
  11.        })
  12.      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
  13.    });
复制代码

  • 绑定UiAbilityContext使用模态弹窗方式,初始化context。代码示例:
  1. let context = getContext(this) as common.UIAbilityContext;
  2. notificationManager.isNotificationEnabled().then((data: boolean) => {
  3.   hilog.info(DOMAIN_NUMBER, TAG, "isNotificationEnabled success, data: " + JSON.stringify(data));
  4.   if(!data){
  5.     notificationManager.requestEnableNotification(context).then(() => {
  6.       hilog.info(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification success`);
  7.     }).catch((err : BusinessError) => {
  8.       if(1600004 == err.code){
  9.         hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification refused, code is ${err.code}, message is ${err.message}`);
  10.       } else {
  11.         hilog.error(DOMAIN_NUMBER, TAG, `[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);
  12.       }
  13.     });
  14.   }
  15. }).catch((err : BusinessError) => {
  16.   hilog.error(DOMAIN_NUMBER, TAG, `isNotificationEnabled fail: ${JSON.stringify(err)}`);
  17. });
复制代码

  • 不在授权时切换页面,发起在window.loadContent回调中哀求权限。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表