【HarmonyOS 6】鸿蒙原生应用智能体接入

张开发
2026/4/13 12:36:38 15 分钟阅读

分享文章

【HarmonyOS 6】鸿蒙原生应用智能体接入
本文只讲一个很细的功能如何在首页标题栏右上角接入智能体入口。本文中的代码全部来自项目现有实现核心逻辑集中在entry/src/main/ets/pages/MainMenu.ets。功能效果这个接入点放在首页标题栏最右侧具备三个特点位置固定显示在应用标题右边按能力显示只有设备支持、控制器初始化成功时才渲染生命周期完整页面进入时初始化页面离开时移除监听相关文件本功能的主要实现文件只有一个entry/src/main/ets/pages/MainMenu.ets也就是说这次接入并没有拆到额外的服务层里页面自己完成了状态声明、能力检测、组件渲染和事件解绑结构比较直接适合写成独立教程。一、先引入智能体组件相关能力首页文件顶部先引入FunctionComponent和FunctionControllerimport{common}fromkit.AbilityKitimport{BusinessError}fromkit.BasicServicesKitimport{FunctionComponent,FunctionController}fromkit.AgentFrameworkKit这里三项分别承担不同职责FunctionComponent真正显示在页面上的智能体入口组件FunctionController负责控制组件并监听打开、关闭等事件common.UIAbilityContext做能力检测时需要的上下文对象这个功能直接使用系统 Kit不需要在项目里额外补第三方依赖。二、页面内声明状态与控制器在MainMenu页面里和智能体相关的成员只有三个逻辑很清晰StateisAgentSupport:booleanfalseprivateagentController:FunctionController|nullnullprivateagentId:stringyour_agent_id_here这三个字段的作用分别是isAgentSupport当前设备和环境是否支持该智能体能力agentController智能体组件控制器agentId接入的智能体标识这里把真实 ID 换成了占位符。你在自己的项目里只需要把your_agent_id_here替换成实际智能体 ID 即可。三、在页面出现时初始化智能体能力这个功能没有在页面创建时直接渲染而是先做设备判断再决定是否初始化aboutToAppear():void{constis2In1is2In1Device()if(!is2In1){this.agentControllernewFunctionController()this.initAgentListeners()this.checkAgentSupport()}else{this.agentControllernullthis.isAgentSupportfalsehilog.info(DOMAIN,TAG,Agent entry disabled on 2in1 device)}}这里有两个关键点1. 不是所有设备都直接展示代码里明确对2in1做了排除处理。如果当前设备不适合该能力就直接把入口关闭不继续初始化。2. 初始化顺序很重要接入顺序是固定的创建FunctionController注册监听事件检查能力是否支持这样写的好处是只有在能力确认可用后页面才会真正显示右上角入口避免空白占位或者点击无响应。四、补上打开与关闭事件监听当前实现里还给智能体组件补了两个事件监听privateinitAgentListeners():void{this.agentController?.on(agentDialogOpened,this.onAgentOpenedCallback)this.agentController?.on(agentDialogClosed,this.onAgentClosedCallback)}privatereadonlyonAgentOpenedCallback(){hilog.info(DOMAIN,TAG,agent dialog opened callback)}privatereadonlyonAgentClosedCallback(){hilog.info(DOMAIN,TAG,agent dialog closed callback)}这部分逻辑不复杂但很有必要。因为智能体入口往往不是一个普通按钮它可能会拉起对话框或服务面板。接入监听后后续如果你要统计打开次数、补埋点、做页面联动都可以直接在这两个回调里扩展。当前项目里这两个回调先只做日志记录属于非常稳妥的写法先把链路接通再逐步增加业务逻辑。五、渲染前先做能力检测是否显示入口不是靠写死布尔值而是通过checkAgentSupport()动态判断privateasynccheckAgentSupport():Promisevoid{try{constcontextthis.getUIContext()?.getHostContext()ascommon.UIAbilityContext|undefinedif(!context){this.isAgentSupportfalsehilog.warn(DOMAIN,TAG,UIAbilityContext is unavailable when checking agent support)return}if(!this.agentController){this.isAgentSupportfalsereturn}this.isAgentSupportawaitthis.agentController.isAgentSupport(context,this.agentId)hilog.info(DOMAIN,TAG,Agent support:${this.isAgentSupport})}catch(error){consterrerrorasBusinessErrorthis.isAgentSupportfalsehilog.error(DOMAIN,TAG,Failed to check agent support: code${err.code}, message${err.message})}}这段代码建议重点理解三件事1. 检测依赖页面上下文这里不是直接调用isAgentSupport()而是先从页面里拿到UIAbilityContext。如果上下文拿不到就立即返回并把状态设为false。2. 检测结果直接驱动 UIisAgentSupport是State变量一旦检测完成页面会自动刷新。这样就不需要你手动控制标题栏重绘。3. 错误场景要兜底如果检测异常当前实现会把isAgentSupport置为false记录错误日志也就是说接入失败时页面仍然可以正常使用只是右上角不显示智能体入口不会影响首页其它按钮。六、把智能体入口放到标题栏右上角UI 布局同样写得很直接左边是应用标题右边是智能体入口。关键代码如下Row({space:12}){Column(){Text(左左右右).fontSize(36).fontWeight(FontWeight.Bold).fontColor(#FF6B35)}.height(44).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Start).layoutWeight(1)if(this.isAgentSupportthis.agentController){Column(){FunctionComponent({agentId:this.agentId,onError:(err:BusinessError){hilog.error(DOMAIN,TAG,Agent component error: code${err.code}, message${err.message})},controller:this.agentController})}.padding(6).backgroundColor(getThemeManager().isDark()?#1F2A3A:#FFFFFF).borderRadius(20).shadow({radius:6,color:#00000014,offsetY:2})}}.width(90%).alignItems(VerticalAlign.Center).padding({top:30,bottom:20})这一段可以拆成两个层面来看。1. 布局层左侧标题区域用了.layoutWeight(1)这样右侧智能体入口就会自然被“挤”到最右边外层Row({ space: 12 })负责控制标题和入口之间的间距所以这个右上角布局并不需要额外写Blank()直接用layoutWeight(1)就已经足够。2. 组件层真正的智能体接入只有一行核心FunctionComponent({agentId:this.agentId,onError:(err:BusinessError){hilog.error(DOMAIN,TAG,Agent component error: code${err.code}, message${err.message})},controller:this.agentController})这里最重要的是三个参数agentId指定接入哪个智能体controller把前面创建好的控制器传进去onError兜底处理组件异常外层再用一个Column包起来补上padding、圆角和阴影右上角入口就会更像一个完整的小卡片而不是直接把组件生硬贴在标题旁边。七、页面离开时移除监听这个细节很容易漏但当前项目已经补上了aboutToDisappear():void{this.agentController?.off(agentDialogOpened)this.agentController?.off(agentDialogClosed)}为什么要写这一步原因很简单首页可能会被重复进入如果监听不解绑重复注册后可能出现多次回调长期来看也不利于页面生命周期管理所以完整接入不只是“显示出来”还要把退出阶段的清理动作一起做完。八、接入这类首页智能体入口的最小步骤如果你也要在自己的 HarmonyOS 页面右上角放一个智能体入口最小接入步骤就是下面这 5 步在页面中引入FunctionComponent、FunctionController声明isAgentSupport、agentController、agentId在aboutToAppear()里创建控制器并调用checkAgentSupport()在标题栏右侧通过FunctionComponent渲染入口在aboutToDisappear()里移除监听照着当前项目这套结构接入逻辑会比较完整而且不会把首页写乱。小结首页右上角智能体接入本质上只做了三件事先判断能不能用通过isAgentSupport()控制显隐再把组件放到标题栏右侧通过layoutWeight(1)留出右侧空间最后把生命周期补完整进入时初始化离开时解绑事件这类功能看起来只是页面右上角多了一个入口但真正稳定的关键不在“放上去”而在于能力检测、错误兜底、事件监听和退出清理都要一起做好。当前项目里的实现已经把这条链路串通了直接按这个结构复用即可。

更多文章