HarmonyOS鸿蒙Next特性在Flutter侧的适配
HarmonyOS鸿蒙Next特性在Flutter侧的适配
一、引言
1.1 概述
欢迎您关注并在Flutter工程中使用HarmonyOS特性功能(意图分享和碰一碰传输)。以下是可参考代码:
1.2 场景使用说明
本文档旨在向开发者清晰地传达以下关键信息:
- 理解一镜到底、意图框架和碰一碰分享。
- 如何在Flutter工程中集成一镜到底、意图框架和碰一碰分享的功能。
- 建议在使用开发前,仔细阅读本文档。
二、实例效果展示
图1 一镜到底
图2 意图分享成功
图3 小艺推荐中出现分享卡片
图4 未开启碰一碰监听
图5 碰一碰分待接收
三、什么是意图框架
3.1 Intents Kit简介
Intents Kit(意图框架服务)是HarmonyOS级的意图标准体系 ,意图连接了应用/元服务内的业务功能。
意图框架能帮开发者将应用/元服务内的业务功能,智能分发到各系统入口,这个过程即智慧分发。其中系统入口包括:小艺对话、小艺搜索、小艺建议。
3.2 Intents Kit优势
利用HarmonyOS的大模型、多维设备感知等AI能力,准确且及时地获取到用户显性、潜在意图,从而实现个性化、多模态、精准的智慧分发。
3.3 意图的运行逻辑
HarmonyOS、应用/元服务的交互中,意图运行方式分为意图调用和意图共享:
3.4 约束与限制
- 设备限制
本Kit仅适用于Phone、Tablet、PC/2in1,暂不支持模拟器使用。
- 地区限制
本Kit仅支持中国境内(不包含中国香港、中国澳门、中国台湾)提供服务。
- 操作系统限制
HarmonyOS 5.0及以上。
3.5 Flutter侧接入实现
依赖包安装
hadss_intents:
git:
url: https://gitcode.com/openharmony-sig/flutter_ohfeatures.git
path: packages/intents
核心接口
Intents().shareIntent(List<Map> intentData)。
代码示例
import 'package:hadss_intents/hadss_intents.dart';
// 以分享音乐为例;注意此处shareIntent方法接受的数组里数据可替换为想分享的数据(如:视频数据)
void handleShareIntentPlayMusic(){
Intents().shareIntent([
{
'intentName': 'PlayMusic',
'intentVersion': '1.0',
'identifier': 'uuid',
'intentActionInfo': {
'actionMode': 'EXECUTED',
'executedTimeSlots': {
'executedStartTime': 1637393212000,
'executedEndTime': 1637393112000
},
'currentPercentage': 50
},
'intentEntityInfo': {
'entityName': 'Music',
'entityId': 'C10194368',
'entityGroupId': 'C10194321312',
'displayName': '测试1',
'description': 'NA',
'logoURL':
'https://www-file.huawei.com/-/media/corporate/images/home/logo/huawei_logo.png',
'keywords': ['华为音乐', '化妆'],
'rankingHint': 99,
'expirationTime': 1637393212000,
'metadataModificationTime': 1637393212000,
'activityType': ['1', '2', '3'],
'artist': ['测试歌手1', '测试歌手2'],
'lyricist': ['测试词作者1', '测试词作者2'],
'composer': ['测试曲作者1', '测试曲作者2'],
'albumName': '测试专辑',
'duration': 244000,
'playCount': 100000,
'musicalGenre': ['流行', '华语', '金曲', '00后'],
'isPublicData': false
}
}
]).then(() => {
Alert.alert(`意图分享成功`);
})
};
GestureDetector(
onTap: () => handleShareIntentPlayMusic(),
)
3.6 HarmonyOS工程处理
在HarmonyOS工程如下目录(src/main/ets/entryability)下加入InsightIntentExecutorImpl.ets文件。
import Logger from '../utils/Logger';
import { insightIntent, InsightIntentExecutor } from '[@kit](/user/kit).AbilityKit';
import { window } from '[@kit](/user/kit).ArkUI';
import type { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
const TAG: string = 'InsightIntentExecutorImpl';
/**
* 意图执行样例
*/
export default class InsightIntentExecutorImpl extends InsightIntentExecutor {
private static readonly PLAY_MUSIC = 'PlayMusic';
private static readonly VIEW_REPAYMENT = 'PlayVideo';
private static readonly ERROR_CODE = -1;
/**
* override 执行前台UiAbility意图
*
* @param name 意图名称
* @param param 意图参数
* @param pageLoader 窗口
* @returns 意图调用结果
*/
onExecuteInUIAbilityForegroundMode(name: string, param: Record<string, Object>, pageLoader: window.WindowStage):
Promise<insightIntent.ExecuteResult> {
Logger.info(TAG, `onExecuteInUIAbilityForegroundMode name: ${name}, param: ${JSON.stringify(param)}`);
// 根据意图名称分发处理逻辑
switch (name) {
case InsightIntentExecutorImpl.PLAY_MUSIC:
Logger.info(TAG, `PLAY_MUSIC}`);
return this.playMusic(param, pageLoader);
case InsightIntentExecutorImpl.VIEW_REPAYMENT:
Logger.info(TAG, `PLAY_Video}`);
return this.viewRepayment(param, pageLoader);
default:
Logger.info(TAG, `no intent match`);
break;
}
Logger.info(TAG, `no intent match`);
return Promise.resolve({
code: InsightIntentExecutorImpl.EERROR_CODE,
result: {
message: 'unknown intent'
}
} as insightIntent.ExecuteResult);
}
/**
* 实现调用播放音乐功能
*
* @param param 意图参数
* @param pageLoader 窗口
*/
private playMusic(param: Record<string, Object>,
pageLoader: window.WindowStage): Promise<insightIntent.ExecuteResult> {
return new Promise(() => {
let para: Record<string, string> = {
'result': `intent execute success, entityId: ${param.entityId}`
};
let localStorage: LocalStorage = new LocalStorage(para);
// TODO 实现意图调用
pageLoader.loadContent('pages/Index', localStorage)
.then(() => {
// TODO 调用成功的情况
Logger.info(TAG, "Intent execute succeed");
})
.catch((err: BusinessError) => {
// TODO 调用失败的情况
Logger.error(TAG, `Intent execute failed: ${JSON.stringify(err)}`);
});
});
}
/**
* 实现调用查看还款功能
*
* @param param 意图参数
* @param pageLoader 窗口
*/
private viewRepayment(param: Record<string, Object>,
pageLoader: window.WindowStage): Promise<insightIntent.ExecuteResult> {
return new Promise(() => {
let para: Record<string, string> = {
'result': JSON.stringify(param)
};
let localStorage: LocalStorage = new LocalStorage(para);
// TODO 实现意图调用
pageLoader.loadContent('pages/Index', localStorage)
.then(() => {
// TODO 调用成功的情况
Logger.info(TAG, "Intent execute succeed");
})
.catch((err: BusinessError) => {
// TODO 调用失败的情况
Logger.error(TAG, `Intent execute failed: ${JSON.stringify(err)}`);
});
});
}
};
四、什么是碰一碰分享
4.1 碰一碰分享简介
Share Kit 推出碰一碰分享,支持用户通过碰一碰发起跨端分享,可实现传输图片、共享Wi-Fi等,并结合App Linking 技术,可实现内容的快速跨设备分享,直达目标应用,无需依赖第三方应用中转,提供高效、便捷、无缝的分享体验。例如视频分享示例
4.2 分享的业务流程
流程说明:
- 宿主应用注册碰一碰分享事件,并与亮屏的对端设备碰一碰。
- 宿主应用发现设备,调用碰一碰分享事件回调,在回调事件中构造分享数据并发送。
- 目标设备接收并处理分享数据。
- 宿主应用解除注册靠近分享事件。
4.3 约束与限制
手机应用发起碰一碰分享时,双端设备需要在亮屏、解锁的状态下并且都已开启华为分享服务(系统默认开启),设备顶部轻碰即可触发。如果用户已手动关闭华为分享服务开关,轻碰事件触发时,用户会接收到系统通知提示开启。
Share Kit的处理机制:
- 任意一端设备不支持碰一碰能力时,轻碰无任何响应。
- 宿主应用无法获得分享结果,Share Kit会通过系统通知消息告知用户对端接收或拒绝。
环境要求:
- 支持的手机系统:HarmonyOS 5.0 Release及以上版本。
- 集成开发环境:DevEco Studio 5.0 Beta1及以上版本。
4.4 Flutter侧接入实现
依赖包安装
hadss_knock_share:
git:
url: https://gitcode.com/openharmony-sig/flutter_ohfeatures.git
path: packages/knock_share
源端设备
代码示例
import 'package:hadss_knock_share/hadss_knock_share.dart';
// 1. 启用碰一碰监听
KnockShare.addKnockShareListener()
// 2. 启用成功后,手机碰一碰
KnockShare.setKnockShareData(shareData)
// 3. 关闭碰一碰监听
KnockShare.removeKnockShareListener();
//要先检测碰一碰支不支持,才去调用其他接口的
Future<void> getCanUseKnockShareState() async {
bool canUseKnockShare = false;
canUseKnockShare = await knockSharePlugin.canUseKnockShare() ?? false;
setState(() {
canUseKnockShareState = canUseKnockShare;
});
}
// 本示例提供三种不同分享场景
1)分享纯图片
var shareBean = SharedRecord(UniformDataType.PNG);
shareBean.thumbnailUri = "缓存图片的file地址";
addKnockShareListener(shareBean);
2)沉浸式分享
var shareBean = SharedRecord(UniformDataType.HYPERLINK);
shareBean.content = "分享的内容";
shareBean.thumbnailUri = "缓存图片的file地址";
shareBean.description = "描述";
shareBean.title = "标题";
addKnockShareListener(shareBean);
3)上下白卡布局
var shareBean = SharedRecord(UniformDataType.HYPERLINK);
shareBean.content = "分享的内容";
shareBean.thumbnailUri = "缓存图片的file地址";
shareBean.description = "描述";
shareBean.title = "标题";
addKnockShareListener(shareBean);
目标设备
需要在HarmonyOS工程下添加碰一碰分享的缓存文件(oho/entity/src/main/resources/rawfile)。在oho/entity/src/main/ets/pages下的index.ets中增加碰一碰分享的缓存读取。
import common from '[@ohos](/user/ohos).app.ability.common';
import { FlutterPage } from '[@ohos](/user/ohos)/flutter_ohos'
import { fileIo } from '[@kit](/user/kit).CoreFileKit';
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
let storage = LocalStorage.getShared()
const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'
const TAG = "Index : "
[@Entry](/user/Entry)(storage)
[@Component](/user/Component)
struct Index {
private context = getContext(this) as common.UIAbilityContext
更多关于HarmonyOS鸿蒙Next特性在Flutter侧的适配的实战教程也可以访问 https://www.itying.com/category-92-b0.html
HarmonyOS Next的Flutter适配主要涉及渲染引擎和平台通道的调整。由于Next不再兼容Android生态,Flutter需通过鸿蒙原生NDK接口对接系统服务。华为提供了鸿蒙专用的Flutter引擎分支,重构了Skia图形渲染与平台插件(如Dart:ffi调用OHOS API)。关键适配点包括渲染管线对接ArkUI、线程模型调整、以及分布式设备发现接口的集成。现有Flutter代码需通过鸿蒙SDK重新编译,部分插件需基于OHOS API重写。
更多关于HarmonyOS鸿蒙Next特性在Flutter侧的适配的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
对于Flutter适配HarmonyOS Next特性的问题,目前提供的资源已经覆盖了核心功能的实现方式。意图框架、碰一碰分享和一镜到底动效均通过对应的Flutter插件实现,具体依赖和示例代码在提供的链接中详细说明。
需要注意以下几点:
- 意图框架依赖
hadss_intents
插件,通过shareIntent
方法传递结构化数据实现智慧分发 - 碰一碰功能需使用
hadss_knock_share
插件,包含设备检测、数据传输和监听管理 - 一镜到底动效通过
hadss_geometry_transition
插件提供共享元素转场支持
这些插件需要HarmonyOS 5.0及以上版本,且部分功能有设备类型和地区限制。实际开发时应参考示例代码进行集成,并确保HarmonyOS工程侧有对应的原生模块配合。