华为HarmonyOS帮助应用接入意图框架 -- 2 接入方案

发布于:2024-12-18 ⋅ 阅读:(13) ⋅ 点赞:(0)

方案概述

当用户在应用/元服务内使用功能时,开发者需要按照标准意图Schema向系统共享行为数据,并支持意图调用(空调用与传参调用),以实现用户点击模板卡后跳转回对应页面。

意图注册

以歌曲续听推荐特性为例,首先要注册播放歌曲意图(PlayMusic),其他意图见各垂域意图Schema。开发者需要编辑对应的意图配置 PROJECT_HOME/entry/src/main/resources/base/profile/insight_intent.json文件,实现意图注册。


  1. {
  2. // 应用支持的意图列表
  3. // 必须声明应用支持插件包含的必选意图,应用上架时会进行校验
  4. "insightIntents": [
  5. {
  6. // 意图名称
  7. // 名称应当遵循意图框架规范,当前仅支持预置垂域意图,不允许自定义
  8. // 应用内意图名称唯一,不允许出现相同的名称定义
  9. "intentName": "PlayMusic",
  10. // 意图所属的垂域
  11. "domain": "MusicDomain",
  12. // 意图版本号
  13. // 插件引用意图时会校验该版本号,只有和插件定义的版本号一致才能正常调用
  14. "intentVersion": "1.0.1",
  15. // 意图调用逻辑入口
  16. "srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets",
  17. "uiAbility": {
  18. // 意图所在module、ability,以及代码相对路径入口
  19. "ability": "EntryAbility",
  20. // UIAbility支持前后台两种执行模式
  21. "executeMode": [
  22. "background",
  23. "foreground"
  24. ]
  25. }
  26. }
  27. ]
  28. }

端侧意图共享

构建意图对象,并且调用shareIntent(),实现意图共享。可同时构建多个PlayMusic或PlayMusicList的意图对象。


  1. import { insightIntent } from '@kit.IntentsKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. let playMusicIntent1: insightIntent.InsightIntent;
  4. let playMusicIntent2: insightIntent.InsightIntent;
  5. // 共享数据接口 意图数组可以是更多的实体
  6. // 根据实际代码上下文自行传入合适的context
  7. insightIntent.shareIntent(context, [playMusicIntent1, playMusicIntent2]).then(() => {
  8. console.info('shareIntent succeed');
  9. }).catch((err: BusinessError) => {
  10. console.error(`error.code: ${err?.code}, failed because ${err?.message}`);
  11. });

PlayMusic的意图共享字段定义见各垂域意图Schema定义,代码示例如下:


  1. import { insightIntent } from '@kit.IntentsKit';
  2. let playMusicIntent: insightIntent.InsightIntent = {
  3. intentName: "PlayMusic",
  4. intentVersion: "1.0",
  5. identifier: "52dac3b0-6520-4974-81e5-25f0879449b5",
  6. intentActionInfo: {
  7. actionMode: "EXECUTED",
  8. executedTimeSlots: {
  9. executedStartTime: 1637393212000,
  10. executedEndTime: 1637393112000,
  11. },
  12. currentPercentage: 50,
  13. },
  14. intentEntityInfo: {
  15. entityName: "Music",
  16. entityId: "C10194368",
  17. entityGroupId: "C10194321312",
  18. displayName: "测试歌曲1",
  19. description: "NA",
  20. logoURL: "https://www-file.abc.com/-/media/corporate/images/home/logo/abc_logo.png",
  21. keywords: ["华为音乐", "化妆"],
  22. rankingHint: 99,
  23. expirationTime: 1637393212000,
  24. metadataModificationTime: 1637393212000,
  25. activityType: ["1", "2", "3"],
  26. artist: ["测试歌手1", "测试歌手2"],
  27. lyricist: ["测试词作者1", "测试词作者2"],
  28. composer: ["测试曲作者1", "测试曲作者2"],
  29. albumName: "测试专辑",
  30. duration: 244000,
  31. playCount: 100000,
  32. musicalGenre: ["流行", "华语", "金曲", "00后"],
  33. isPublicData: false,
  34. }
  35. }

完整的意图共享示例如下所示,该示例构建了一个PlayMusic意图,并进行了shareIntent调用。


  1. import { insightIntent } from '@kit.IntentsKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. let playMusicIntent: insightIntent.InsightIntent = {
  4. intentName: "PlayMusic",
  5. intentVersion: "1.0",
  6. identifier: "52dac3b0-6520-4974-81e5-25f0879449b5",
  7. intentActionInfo: {
  8. actionMode: "EXECUTED",
  9. executedTimeSlots: {
  10. executedStartTime: 1637393212000,
  11. executedEndTime: 1637393112000,
  12. },
  13. currentPercentage: 50,
  14. },
  15. intentEntityInfo: {
  16. entityName: "Music",
  17. entityId: "C10194368",
  18. entityGroupId: "C10194321312",
  19. displayName: "测试歌曲1",
  20. description: "NA",
  21. logoURL: "https://www-file.abc.com/-/media/corporate/images/home/logo/abc_logo.png",
  22. keywords: ["华为音乐", "化妆"],
  23. rankingHint: 99,
  24. expirationTime: 1637393212000,
  25. metadataModificationTime: 1637393212000,
  26. activityType: ["1", "2", "3"],
  27. artist: ["测试歌手1", "测试歌手2"],
  28. lyricist: ["测试词作者1", "测试词作者2"],
  29. composer: ["测试曲作者1", "测试曲作者2"],
  30. albumName: "测试专辑",
  31. duration: 244000,
  32. playCount: 100000,
  33. musicalGenre: ["流行", "华语", "金曲", "00后"],
  34. isPublicData: false,
  35. }
  36. }
  37. // 共享数据接口 意图数组可以是更多的实体
  38. // 根据实际代码上下文自行传入合适的context
  39. insightIntent.shareIntent(context, [playMusicIntent]).then(() => {
  40. console.info('shareIntent succeed');
  41. }).catch((err: BusinessError) => {
  42. console.error(`error.code: ${err?.code}, failed because ${err?.message}`);
  43. });

端侧意图调用

意图执行组件为uiAbility的意图调用

如上文意图注册,当开发者注册的意图承载的运行组件为uiAbility时,开发者需要自己实现InsightIntentExecutor,并在对应回调实现打开落地页(点击推荐卡片跳转的界面)的能力,PlayMusic的意图调用字段定义见各垂域意图Schema

步骤如下:

  1. 继承InsightIntentExecutor。
  2. 重写对应方法,例如目标拉起前台页面,则可重写onExecuteInUIAbilityForegroundMode方法。
  3. 通过意图名称,识别播放歌曲意图(PlayMusic),在对应的方法中传递意图参数(param),并拉起对应落地页(如歌曲落地页)。
    
      
    1. import { insightIntent, InsightIntentExecutor } from '@kit.AbilityKit';
    2. import { window } from '@kit.ArkUI';
    3. import { BusinessError } from '@kit.BasicServicesKit';
    4. /**
    5. * 意图调用样例
    6. */
    7. export default class InsightIntentExecutorImpl extends InsightIntentExecutor {
    8. private static readonly PLAY_MUSIC = 'PlayMusic';
    9. /**
    10. * override 执行前台UIAbility意图
    11. *
    12. * @param name 意图名称
    13. * @param param 意图参数
    14. * @param pageLoader 窗口
    15. * @returns 意图调用结果
    16. */
    17. onExecuteInUIAbilityForegroundMode(name: string, param: Record<string, Object>, pageLoader: window.WindowStage):
    18. Promise<insightIntent.ExecuteResult> {
    19. // 根据意图名称分发处理逻辑
    20. switch (name) {
    21. case InsightIntentExecutorImpl.PLAY_MUSIC:
    22. return this.playMusic(param, pageLoader);
    23. default:
    24. break;
    25. }
    26. return Promise.resolve({
    27. code: -1,
    28. result: {
    29. message: 'unknown intent'
    30. }
    31. } as insightIntent.ExecuteResult)
    32. }
    33. /**
    34. * 实现调用播放歌曲功能
    35. *
    36. * @param param 意图参数
    37. * @param pageLoader 窗口
    38. */
    39. private playMusic(param: Record<string, Object>, pageLoader: window.WindowStage): Promise<insightIntent.ExecuteResult> {
    40. return new Promise((resolve, reject) => {
    41. let para: Record<string, string> = {
    42. 'result': JSON.stringify(param)
    43. };
    44. let localStorage: LocalStorage = new LocalStorage(para);
    45. // TODO 实现意图调用,loadContent的入参为歌曲落地页路径,例如:pages/Index
    46. pageLoader.loadContent('pages/Index', localStorage)
    47. .then(() => {
    48. let entityId: string = (param.items as Array<object>)?.[0]?.['entityId'];
    49. // TODO 调用成功的情况,此处可以打印日志
    50. resolve({
    51. code: 0,
    52. result: {
    53. message: 'Intent execute succeed'
    54. }
    55. });
    56. })
    57. .catch((err: BusinessError) => {
    58. // TODO 调用失败的情况
    59. resolve({
    60. code: -1,
    61. result: {
    62. message: 'Intent execute failed'
    63. }
    64. })
    65. });
    66. })
    67. }
    68. }

意图执行组件为form的意图调用

如上文意图注册,当开发者注册的意图承载的运行组件为form(运行组件FormExtensionAbility)时,则需要开发者在实现的FormExtensionAbility中从want中获取并解析意图名和执行参数,用于卡片展示。

步骤如下:

  1. 在意图执行绑定FormExtensionAbility的onAddForm(want: Want)中获取运行态意图框架传入的意图名(预定义keyName为ohos.insightIntent.executeParam.name)和意图执行参数(预定义keyName为ohos.insightIntent.executeParam.param);
  2. 通过意图名称,识别播放歌曲意图(PlayMusic),在对应的方法中传递意图参数(param),并加载对应数据用于卡片展示。

  1. import { Want } from '@kit.AbilityKit';
  2. import { formBindingData, FormExtensionAbility } from '@kit.FormKit';
  3. /**
  4. * 卡片意图调用示例
  5. */
  6. export default class LoadCardFormAbility extends FormExtensionAbility {
  7. onAddForm(want: Want): formBindingData.FormBindingData {
  8. if (want?.parameters?.['ohos.insightIntent.executeParam.name'] != undefined) {
  9. const intentName = want.parameters['ohos.insightIntent.executeParam.name']; //意图名
  10. //TODO: 根据意图名称分发处理逻辑,若仅一个卡片意图,则可以忽略
  11. }
  12. if (want?.parameters?.['ohos.insightIntent.executeParam.param'] != undefined) {
  13. const executeParameter = want.parameters['ohos.insightIntent.executeParam.param']; //意图执行参数
  14. //TODO: 从 executeParameter 中解析具体意图执行参数,用于卡片内容展示
  15. }
  16. let formData = ''; //TODO: 仅示例,根据具体逻辑封装
  17. return formBindingData.createFormBindingData(formData);
  18. }
  19. }