一、方案概述
开发者需要按照意图定义,进行意图注册并实现意图调用;用户通过对小艺对话进行自然语言输入,小艺理解语义转换成意图调用(含意图参数),执行意图调用实现对应交互体验。
端侧意图注册
以“搜索旅游攻略”特性为例,开发者首先要注册“查看旅游攻略”(ViewTravelGuides)。开发者需要编辑对应的意图配置PROJECT_HOME/entry/src/main/resources/base/profile/insight_intent.json文件,实现意图注册。
{"insightIntents": [{"intentName": "ViewTravelGuides","domain": "TravelDomain","intentVersion": "1.0.1","srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets","uiAbility": {"ability": "EntryAbility","executeMode": ["background","foreground"]},"uiExtension": {"ability": "insightIntentUIExtensionAbility"}}]
}
配置说明如下所示:
二、端侧前台意图调用
开发者需自己实现InsightIntentExecutor,并在对应回调实现打开落地页(点击推荐卡片跳转的界面,如旅游攻略落页面)的能力,ViewTravelGuides的意图调用字段定义见查看旅游攻略 (ViewTravelGuides)。
步骤如下:
继承InsightIntentExecutor。
重写对应方法,例如目标拉起前台页面,则可重写onExecuteInUIAbilityForegroundMode方法。
通过意图名称,识别查看旅游攻略意图(ViewTravelGuides),在对应的方法中传递意图参数(param),并拉起对应落地页(点击推荐卡片跳转的界面,如旅游攻略落页面)。
import { insightIntent, InsightIntentExecutor } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';/*** 意图调用样例 */
export default class InsightIntentExecutorImpl extends InsightIntentExecutor {private static readonly VIEW_TRAVEL_GUIDES = 'ViewTravelGuides';/*** override 执行前台UIAbility意图** @param name 意图名称* @param param 意图参数* @param pageLoader 窗口* @returns 意图调用结果*/onExecuteInUIAbilityForegroundMode(name: string, param: Record<string, Object>, pageLoader: window.WindowStage):Promise<insightIntent.ExecuteResult> {// 根据意图名称分发处理逻辑switch (name) {case InsightIntentExecutorImpl.VIEW_TRAVEL_GUIDES:return this.viewTravelGuides(param, pageLoader);default:break;}return Promise.resolve({code: -1,result: {message: 'unknown intent'}} as insightIntent.ExecuteResult)}/*** 实现调用查看旅游攻略功能** @param param 意图参数* @param pageLoader 窗口*/private viewTravelGuides(param: Record<string, Object>, pageLoader: window.WindowStage): Promise<insightIntent.ExecuteResult> {return new Promise((resolve, reject) => {// TODO 实现意图调用,loadContent的入参为旅游攻略落地页路径,例如:pages/TravelGuidePagepageLoader.loadContent('pages/TravelGuidePage').then(() => {let entityId: string = (param.items as Array<object>)?.[0]?.['entityId'];// TODO 调用成功的情况,此处可以打印日志resolve({code: 0,result: {message: 'Intent execute succeed'}});}).catch((err: BusinessError) => {// TODO 调用失败的情况resolve({code: -1,result: {message: 'Intent execute failed'}})});})}
}
三、端侧前台窗口意图调用
开发者需自己实现InsightIntentExecutor,并在对应回调实现窗口页面内容加载的能力。
步骤如下:
继承InsightIntentExecutor。
重写对应方法,例如目标拉起前台窗口化页面,则可重写onExecuteInUIExtensionAbility方法。
通过意图名称,识别打开蓝牙意图(LoadBluetoothCard)调用扩展意图,在对应的方法中传递意图参数(param),并拉起对应窗口化页面(如打开蓝牙窗口化页面)。
import { insightIntent, InsightIntentExecutor, UIExtensionContentSession } from '@kit.AbilityKit';/*** 意图调用样例 */
export default class IntentExecutorImpl extends InsightIntentExecutor {private static readonly TAG: string = 'IntentExecutorImpl';private static readonly LOAD_BLUETOOTH_CARD: string = 'LoadBluetoothCard';/*** override 执行前台UI扩展意图** @param name 意图名称* @param param 意图参数* @param pageLoader 窗口* @returns 意图调用结果*/async onExecuteInUIExtensionAbility(name: string, param: Record<string, Object>,pageLoader: UIExtensionContentSession):Promise<insightIntent.ExecuteResult> {console.info(IntentExecutorImpl.TAG, `onExecuteInUIExtensionAbility`);switch (name) {case IntentExecutorImpl.LOAD_BLUETOOTH_CARD:console.info(IntentExecutorImpl.TAG, `onExecuteInUIAbilityForegroundMode::ForegroundUiAbility intent`);return this.openLoadBluetoothCard(pageLoader);default:console.info(IntentExecutorImpl.TAG, `onExecuteInUIAbilityForegroundMode::invalid intent`);break;}let result: insightIntent.ExecuteResult = {code: -1,result: {message: 'onExecuteInUIExtensionAbility failed'}};return result;}/*** 打开加载蓝牙卡片意图** @param pageLoader 意图内容Session对象* @returns 执行结果*/private async openLoadBluetoothCard(pageLoader: UIExtensionContentSession): Promise<insightIntent.ExecuteResult> {pageLoader.loadContent('pages/UiExtensionPage');let result: insightIntent.ExecuteResult = {code: 0,result: {message: 'intent execute succeed'}}return result;}
}
本文主要参考鸿蒙官方网站材料