HarmonyOS鸿蒙Next特性在Flutter侧的适配

HarmonyOS鸿蒙Next特性在Flutter侧的适配

一、引言

1.1 概述

      欢迎您关注并在Flutter工程中使用HarmonyOS特性功能(意图分享和碰一碰传输)。以下是可参考代码:

1、Flutter侧Sample代码仓库

2、Flutter侧一镜到底依赖库

3、Flutter侧意图框架依赖库

4、Flutter侧碰一碰依赖库

1.2 场景使用说明

      本文档旨在向开发者清晰地传达以下关键信息:

  1. 理解一镜到底、意图框架和碰一碰分享。
  2. 如何在Flutter工程中集成一镜到底、意图框架和碰一碰分享的功能。
  3. 建议在使用开发前,仔细阅读本文档。

二、实例效果展示

      图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 分享的业务流程

分享的业务流程

      流程说明:

  1. 宿主应用注册碰一碰分享事件,并与亮屏的对端设备碰一碰。
  2. 宿主应用发现设备,调用碰一碰分享事件回调,在回调事件中构造分享数据并发送。
  3. 目标设备接收并处理分享数据。
  4. 宿主应用解除注册靠近分享事件。

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

2 回复

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插件实现,具体依赖和示例代码在提供的链接中详细说明。

需要注意以下几点:

  1. 意图框架依赖hadss_intents插件,通过shareIntent方法传递结构化数据实现智慧分发
  2. 碰一碰功能需使用hadss_knock_share插件,包含设备检测、数据传输和监听管理
  3. 一镜到底动效通过hadss_geometry_transition插件提供共享元素转场支持

这些插件需要HarmonyOS 5.0及以上版本,且部分功能有设备类型和地区限制。实际开发时应参考示例代码进行集成,并确保HarmonyOS工程侧有对应的原生模块配合。

回到顶部