HarmonyOS鸿蒙Next中通过发出的通知信息弹框点击后拉起地图应用且同时去处理云数据库中的数据

HarmonyOS鸿蒙Next中通过发出的通知信息弹框点击后拉起地图应用且同时去处理云数据库中的数据 我现在有一开发场景需要去查询云数据库中数据的“是否已读”字段的值为false,如果是的话就使用 notificationManager Kit 发送一个通知,然后当用户点击了通知就会拉起手机的地图应用,同时会把云数据库中的数据的是否读取字段修改为true,并根据我传入的目的地数据进行导航;这个代码该如何书写,我现在能实现的是通知发送之后当用户点击了通知信息能拉起自身应用

async sendNotice(title: string, text: string, additionalText: string) {
  try {
    const wantAgentInfo: wantAgent.WantAgentInfo = {
      wants: [
        {
          bundleName: 'com.TLPTHarmonyOSGeek.ZhiHuYinLing.ShouHuDuan',
          abilityName: 'EntryAbility',
        },
      ],
      operationType: wantAgent.OperationType.START_ABILITY,
      requestCode: 0,
      wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
    };

    const agent = await wantAgent.getWantAgent(wantAgentInfo);

    let notificationRequest: notificationManager.NotificationRequest = {
      id: 11,
      content: {
        notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
        normal: {
          title: title,
          text: text,
          additionalText: additionalText,
        }
      },
      notificationSlotType: notificationManager.SlotType.SERVICE_INFORMATION,
      wantAgent: agent,
      sound: "ringtone.mp3"
    };
    notificationManager.publish(notificationRequest, (err: BusinessError) => {
      if (err) {
        console.error("发送通知信息失败,因为:", JSON.stringify(err))
        return;
      }
      console.info("发送通知成功")
    });

  } catch (err) {
    console.error("发送通知失败,因为:", JSON.stringify(err))
  }
}

我尝试过把bundleName修改为手机的地图应用的包名但是此时通知就会发不出去,报错误码:16000151,求问各位大佬有何办法


更多关于HarmonyOS鸿蒙Next中通过发出的通知信息弹框点击后拉起地图应用且同时去处理云数据库中的数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

开发者您好,

【解决方案】

创建WantAgentInfo信息并填写需要拉起的应用bundleName和abilityName(应用只能设置自己应用的bundleName和abilityName),然后构造NotificationRequest对象并发布通知。

可以通过拉起自己的应用,然后再onNewWant回调函数中进行导航(参考:通过地图应用实现导航等能力)参考代码:

import { notificationManager } from '@kit.NotificationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { common, wantAgent, WantAgent } from '@kit.AbilityKit';

const TAG: string = '[PublishOperation]';
const DOMAIN_NUMBER: number = 0xFF00;

@Entry
@Component
struct Index {

  build() {
    Column(){
      Button('授权')
        .margin({ top: 20, bottom: 20 })
        .onClick(() => {
          let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
          notificationManager.isNotificationEnabled().then((data: boolean) => {
            hilog.info(DOMAIN_NUMBER, TAG, `isNotificationEnabled success, data:  ${data}`);
            if (!data) {
              notificationManager.openNotificationSettings(context).then(() => {
                hilog.info(DOMAIN_NUMBER, TAG, `[ANS] openNotificationSettings success`);
              }).catch((err: BusinessError) => {
                hilog.error(DOMAIN_NUMBER, TAG,
                  `[ANS] openNotificationSettings failed, code is ${err.code}, message is ${err.message}`);
              });
            }
          }).catch((err: BusinessError) => {
            hilog.error(DOMAIN_NUMBER, TAG,
              `isNotificationEnabled fail, code is ${err.code}, message is ${err.message}`);
          });
        })

      Button('发布通知').onClick(async (event: ClickEvent) => {
        try {
          let wantAgentInfo: wantAgent.WantAgentInfo = {
            wants: [
              {
                deviceId: '',
                bundleName: 'com.example.myapplicationnotificationmap', // 自己项目的包名
                abilityName: 'EntryAbility',
                action: '',
                entities: [],
                uri: '',
                parameters: {
                  // 自行替换为需要的位置
                  'destLat': 0,
                  'destLon': 0,
                  'poiId': '',
                }
              }
            ],
            actionType: wantAgent.OperationType.START_ABILITY,
            requestCode: 0,
            wantAgentFlags: [wantAgent.WantAgentFlags.CONSTANT_FLAG]
          };

          let wantAgentData  = await wantAgent.getWantAgent(wantAgentInfo)


          let notificationRequest: notificationManager.NotificationRequest = {
            id: 1,
            content: {
              notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
              normal: {
                title: 'test_title',
                text: 'test_text',
                additionalText: 'test_additionalText',
              }
            },
            wantAgent: wantAgentData,
          };
          notificationManager.publish(notificationRequest, (err: BusinessError) => {
            if (err) {
              hilog.error(DOMAIN_NUMBER, TAG,
                `Failed to publish notification. Code is ${err.code}, message is ${err.message}`);
              return;
            }
            hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in publishing notification.');
          });
        }catch (e) {
          console.error(e)
        }
      })
    }
  }
}
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { petalMaps } from '@kit.MapKit';

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    try {
      this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    } catch (err) {
      hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err));
    }
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
    AppStorage.setOrCreate<Context>('context', this.context);
    AppStorage.setOrCreate('isNavigation', false)
  }

  onDestroy(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');


    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
  }

  async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onNewWant');
    try {
      const wantParams = want.parameters;
      if (!wantParams) return;

      let context = AppStorage.get('context') as common.UIAbilityContext

      // 处理云数据
      // xxx
      
      
      let params: petalMaps.PoiDetailParams = {
        destinationPosition: {
          // 导航
          latitude: wantParams?.destLat as number,
          longitude: wantParams?.destLon as number
        },
        destinationPoiId: wantParams?.poiId as string
      };
      await petalMaps.openMapPoiDetail(context, params);
    } catch (e) {
      console.error(`code:${e.code}, message:${e.message}`);
    }
  }
}

更多关于HarmonyOS鸿蒙Next中通过发出的通知信息弹框点击后拉起地图应用且同时去处理云数据库中的数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,通过通知弹框点击拉起地图应用并处理云数据库数据,需使用通知服务发布通知,并设置Want参数指向地图应用。同时,在通知的点击事件中,通过云数据库API执行数据操作,如查询或更新。整个过程需在应用配置文件中声明相关权限,确保通知和数据库访问功能正常。

要实现通知点击后拉起地图应用并更新云数据库,关键在于正确配置WantAgent和处理好异步操作。你遇到的错误码16000151通常是因为没有声明或请求拉起其他应用所需的权限。

以下是修改后的核心代码思路:

  1. 权限配置:在module.json5文件中,为你的Ability添加拉起其他应用的权限。

    "abilities": [
      {
        // ... 其他配置
        "permissions": [
          "ohos.permission.START_ABILITIES_FROM_BACKGROUND"
        ]
      }
    ]
    
  2. 修改WantAgent配置:将wantAgentInfo中的bundleNameabilityName替换为目标地图应用的信息。你需要提前查询或知道手机中地图应用的具体包名和Ability名(例如,华为地图可能为com.huawei.maps.appMainAbility)。

    const wantAgentInfo: wantAgent.WantAgentInfo = {
      wants: [
        {
          bundleName: '目标地图应用的包名', // 例如:com.huawei.maps.app
          abilityName: '目标地图应用的Ability名', // 例如:MainAbility
          // 可以添加参数传递给地图应用,如目的地坐标
          parameters: {
            'destination': '39.9042,116.4074' // 示例:纬度,经度
          }
        }
      ],
      operationType: wantAgent.OperationType.START_ABILITY,
      requestCode: 0,
      wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
    };
    
  3. 在WantAgent触发时更新数据库:由于拉起地图应用后,你的应用可能不会直接激活,因此需要在发送通知之前就更新云数据库中的“是否已读”字段。将数据库更新逻辑放在sendNotice函数的最开始部分。

    async sendNotice(title: string, text: string, additionalText: string, recordId: string) {
      // 第一步:先更新云数据库,将对应recordId的“是否已读”字段设为true
      try {
        await this.updateCloudData(recordId); // 你的云数据库更新函数
      } catch (err) {
        console.error("更新数据库失败: ", JSON.stringify(err));
        return; // 如果更新失败,可以选择不发送通知
      }
    
      // 第二步:发送通知(配置WantAgent拉起地图应用)
      // ... 上面修改后的WantAgent配置和发送通知代码
    }
    
  4. 传递目的地信息:通过parameters将导航目的地坐标传递给地图应用。地图应用需要支持接收这些参数来启动导航。参数格式需参考目标地图应用的开发文档。

总结步骤

  • 声明后台拉起其他应用的权限。
  • 查询并填写正确的地图应用包名和Ability名。
  • 在发送通知前,先调用云数据库接口更新数据状态。
  • 通过WantAgent的parameters传递目的地参数给地图应用。

这样,当用户点击通知时,系统会先执行数据库更新操作(因为它在通知发送前已完成),然后拉起地图应用并传递目的地参数,地图应用根据参数启动导航。

回到顶部