段落引用大家好,我是陈杨,8 年前端老兵转型鸿蒙开发,也是一名鸿蒙极客。从前端到鸿蒙,我靠的是 “三天上手 ArkTS” 的技术嗅觉,以及 “居安思危” 的转型魄力。这三年,我不玩虚的,封装了开源组件库「莓创图表」,拿过创新赛大奖,更带着团队上架了 11 款自研 APP,涵盖工具、效率、创意等多个领域。想体验我的作品?欢迎搜索体验:指令魔方、JLPT、REFLEX PRO、国潮纸刻、Wss 直连、ZenithDocs Pro、圣诞相册、CSS 特效。

继碰一碰分享后,HarmonyOS Share Kit再推创新功能——隔空传送。无需设备物理接触,只需通过“伸掌、抓取、移动、放手”的自然手势,即可完成跨端数据传输,让文件分享从“碰一碰”升级为“隔空传”。这种直观的交互方式,彻底解放了设备接触的限制,尤其适合多设备摆放较近但不便触碰的场景(如桌面多设备协同、会议中文件快速分发)。本文基于官方开发文档,详解隔空传送的核心逻辑、开发步骤、特殊场景适配及最佳实践,助力开发者快速集成这一便捷功能。

一、隔空传送核心基础:交互逻辑与环境要求

隔空传送的核心优势在于“手势驱动+精准反馈”,开发者需先明确其交互流程、设备要求与权限说明,确保功能落地时符合用户预期。

1.1 核心交互流程:手势与状态联动

隔空传送的手势交互分为“发送端”和“接收端”两大环节,每个环节对应明确的状态反馈,让用户清晰感知操作进度:

操作阶段 发送端状态 接收端状态 手势动作与反馈
准备阶段 发送起始准备(状态1) 接收起始准备/接收选中(状态5) 双端开启隔空传送开关,发送端在距屏幕20~40厘米处伸掌停留,屏幕出现掌型图标(提示“可抓取”)
选中阶段 发送选中(状态2) - 发送端看到掌型图标后,握拳完成“抓取”动作,图标变为拳型(提示“已选中内容”)
传输阶段 待发送(状态3)→ 发送中(状态4) 待接收(状态6)→ 接收中(状态7) 发送端握拳状态下,将手移动至接收端设备上方,接收端屏幕出现拳型图标(提示“可接收”)
完成阶段 发送完成 接收完成 接收端出现拳型图标后,发送端松开手掌,文件开始传输,传输完成后双端显示“传输成功”提示

关键感知要求:手势动作需在屏幕正前方20~40厘米范围内完成,动作幅度适中且连贯,设备通过传感器精准识别手势轨迹,避免误触发。

1.2 环境与权限要求

1.2.1 系统与开发环境
  • 支持设备:HarmonyOS 5.0及以上版本手机、平板、PC/2in1(需设备配备姿态传感器,支持手势识别);
  • 开发工具:DevEco Studio NEXT Beta1及以上版本(兼容碰一碰分享的开发环境,无需额外升级);
  • 核心依赖:Share Kit核心能力,需通过canIUse判断设备是否支持(参考碰一碰分享的能力检测逻辑)。
1.2.2 开关开启与权限说明

使用隔空传送前,用户需手动开启功能开关,开启后将联动触发相关系统服务与权限:

  1. 开关开启路径:设置 > 系统 > 快捷启动和手势 > 隔空传送(示意图如下);
    ![隔空传送开关开启路径](提示:官方文档附图为设置界面层级截图,开发者可引导用户按此路径操作,或在应用内提供跳转设置的引导)
  2. 权限与服务联动
    • 开启隔空传送后,系统会自动开启蓝牙、WLAN功能(用于设备发现与数据传输);
    • 应用需获取以下权限:读取蓝牙/WLAN的MAC地址、设备标识符、设备名称、WLAN状态,以及账号昵称和登录状态(用于设备连接与身份识别);
    • 用户打开开关即表示同意上述权限使用,开发者无需额外申请单独权限,由系统统一管控。

二、开发核心步骤:从手势监听至数据传输

隔空传送的开发流程与碰一碰分享类似,核心围绕“注册监听→感知手势→构造数据→发起传输→取消监听”展开,但需重点关注手势事件的时效性与状态反馈,具体步骤如下:

2.1 第一步:注册与取消隔空传送监听

需在“可分享界面”(如图片预览页、文件列表页)进入时注册监听,离开时(包括应用退至后台)立即取消,避免无效监听占用系统资源或误触发。

2.1.1 核心代码:监听注册与取消
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { systemShare, harmonyShare } from '@kit.ShareKit';
import { fileUri } from '@kit.CoreFileKit';
import { UIContext, Context } from '@kit.ArkUI';

@Component
export default struct AirSharePage {
  // 标记是否已注册监听,避免重复注册
  private isListening = false;

  // 页面进入可分享状态时,注册隔空传送监听
  aboutToAppear(): void {
    this.registerAirShareListener();
  }

  // 页面消失(关闭/退后台)时,取消监听
  aboutToDisappear(): void {
    this.unregisterAirShareListener();
  }

  // 应用退至后台时,取消监听(补充aboutToDisappear未覆盖的场景)
  onPageHide(): void {
    this.unregisterAirShareListener();
  }

  // 注册隔空传送监听事件
  private registerAirShareListener() {
    if (this.isListening) return;

    // 检查设备是否支持隔空传送能力(推荐添加,避免无效逻辑)
    if (!canIUse('SystemCapability.Collaboration.HarmonyShare.Gestures')) {
      console.log("设备不支持隔空传送,隐藏相关引导");
      return;
    }

    // 注册手势分享监听,回调函数需在3秒内发起分享,否则超时失败
    harmonyShare.on('gesturesShare', this.airShareCallback);
    this.isListening = true;
    console.log("隔空传送监听注册成功");
  }

  // 取消隔空传送监听事件
  private unregisterAirShareListener() {
    if (!this.isListening) return;

    harmonyShare.off('gesturesShare', this.airShareCallback);
    this.isListening = false;
    console.log("隔空传送监听已取消");
  }

  // 隔空传送回调:构造并发送分享数据
  private airShareCallback = (sharableTarget: harmonyShare.SharableTarget) => {
    try {
      // 3秒内必须调用share(),否则系统判定超时,分享失败
      this.buildShareData(sharableTarget);
    } catch (error) {
      console.error("构造分享数据失败:", error);
      // 异常场景:终止分享并提示用户
      sharableTarget.reject(harmonyShare.SharableErrorCode.UNKNOWN_ERROR);
    }
  };

  // 构造分享数据(核心业务逻辑)
  private buildShareData(sharableTarget: harmonyShare.SharableTarget) {
    const uiContext: UIContext = this.getUIContext();
    const context: Context = uiContext.getHostContext() as Context;

    // 1. 示例:分享本地图片(根据实际业务替换为文件、链接等内容)
    const imagePath = context.filesDir + '/air_share_example.jpg';
    const thumbnailUri = fileUri.getUriFromPath(imagePath);

    // 2. 构造分享数据(支持IMAGE、HYPERLINK等多种utd类型)
    const shareData: systemShare.SharedData = new systemShare.SharedData({
      utd: utd.UniformDataType.IMAGE, // 数据类型:图片
      content: thumbnailUri, // 图片实际URI
      title: '隔空传送图片', // 分享卡片标题
      description: '通过HarmonyOS隔空传送发送', // 分享卡片描述
      thumbnailUri: thumbnailUri, // 预览图URI(优化卡片显示)
    });

    // 3. 发起隔空传送
    sharableTarget.share(shareData);
    console.log("隔空传送已发起,等待接收端确认");
  }

  build() {
    // 页面布局:需包含手势引导提示(如“伸掌停留20-40厘米处可抓取”)
    Column() {
      Text("隔空传送引导")
        .fontSize(16)
        .margin(16);
      Text("1. 伸掌停留屏幕前20-40cm,出现掌型图标后握拳抓取")
        .fontSize(14)
        .marginLeft(16);
      Text("2. 握拳移动至接收设备上方,待出现拳型图标后放手")
        .fontSize(14)
        .marginLeft(16)
        .marginTop(8);
    }
  }
}

2.2 关键注意点:超时与生命周期管理

  • 3秒超时限制:收到gesturesShare回调后,必须在3秒内调用sharableTarget.share(),否则系统会判定为“用户操作超时”,分享失败。建议提前预加载分享数据(如预览图、文件URI),避免回调中耗时操作;
  • 监听注册时机:仅在“可分享界面”(如选中文件、打开图片预览页)注册监听,非分享界面需及时取消,避免无关场景误触发手势;
  • 后台取消监听:应用退至后台(onPageHide)时,需主动取消监听,返回前台后重新注册,确保监听状态与页面可见性一致。

二、特殊场景适配:隔空截屏联动与可信任设备

隔空传送并非独立功能,其与隔空截屏存在联动逻辑,且设备信任机制直接影响传输体验,开发者需重点适配这两大场景。

3.1 隔空传送与隔空截屏的联动逻辑

开启隔空传送开关时,系统会自动联动开启“隔空截屏”功能(后续用户可手动关闭),两者共用“伸掌-握拳”手势,触发逻辑需按开关状态区分,避免功能冲突。具体联动规则如下:

隔空传送开关状态 隔空截屏开关状态 功能触发效果
开启 开启 1. 图库场景:传输原图 + 可选保存截屏至本机;
2. 其他场景:传输截屏 + 可选保存截屏至本机;
3. 首次操作默认不保存截屏,系统记录用户选择作为下次默认值
开启 关闭 1. 图库场景:仅传输原图,无截屏;
2. 其他场景:无截屏,不传输
关闭 开启 仅触发隔空截屏,保存至本机,不进行跨端传输
关闭 关闭 无截屏,不传输
开发适配建议
  • 在分享卡片下方添加“保存截屏至本机”提示(系统自动触发,无需额外开发);
  • 针对非图库场景(如文档、链接分享),需提前告知用户“开启隔空截屏后会传输截屏而非原文件”,避免认知偏差;
  • 若应用需禁用截屏联动,可引导用户手动关闭隔空截屏开关(跳转路径:设置 > 系统 > 快捷启动和手势 > 隔空截屏)。

3.2 可信任设备:免确认传输机制

为提升传输效率,隔空传送引入“设备信任”机制,根据双端华为账号状态决定是否需要用户确认:

双端账号状态 信任机制 传输体验
已登录相同华为账号 默认可信 无需用户确认,手势完成后直接开始传输
未登录相同华为账号 需手动信任 1. 首次传输:双端弹出“是否信任该设备”弹窗,均确认后建立信任;
2. 信任有效期:1小时内再次传输,无需重复确认;
3. 超时后:需重新确认信任
开发适配要点
  • 异账号场景下,需在分享卡片中显示对端设备信息(如设备名称、账号昵称,需HarmonyOS 5.0+支持),帮助用户判断是否信任;
  • 传输前需检查网络状态(蓝牙/WLAN需开启),若未开启,通过系统弹窗提示用户开启,避免因网络问题导致信任确认后传输失败;
  • 信任状态变更无需开发者额外处理,由Share Kit底层维护,开发者仅需关注传输结果回调(如成功、失败、被拒绝)。

三、进阶功能:App Linking直达应用

与碰一碰分享类似,隔空传送支持通过App Linking实现“分享链接→直达应用”的闭环体验,无论接收端是否安装应用,都能快速访问分享内容,提升用户转化率。

3.1 核心实现逻辑

  1. 应用接入App Linking Kit(参考华为应用链接服务开发文档);
  2. 构造分享数据时,将content字段设为App Linking链接;
  3. 接收端收到分享后,若已安装应用,直接拉起应用并跳转至对应页面;若未安装,跳转应用市场下载(需配置App Linking直达应用市场能力)。

3.2 代码示例

private buildShareData(sharableTarget: harmonyShare.SharableTarget) {
  // 构造App Linking分享数据(链接需提前通过App Linking Kit生成)
  const shareData: systemShare.SharedData = new systemShare.SharedData({
    utd: utd.UniformDataType.HYPERLINK, // 必须设为HYPERLINK类型
    content: 'https://sharekitdemo.drcn.agconnect.link/ZB3p', // App Linking链接
    title: 'HarmonyOS开发者大会直播回放',
    description: '点击直达应用观看完整视频',
    thumbnailUri: 'file:///data/storage/.../live_cover.jpg', // 预览图URI
  });

  sharableTarget.share(shareData);
}

// 接收端应用获取链接并跳转(在Ability的onCreate/onNewWant中处理)
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    if (want.uri) {
      console.log("收到隔空传送的App Linking链接:", want.uri);
      // 解析链接参数,跳转至对应页面(如直播回放页)
      this.navigateToTargetPage(want.uri);
    }
  }

  onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // 应用已启动时,接收新的分享链接
    this.onCreate(want, launchParam);
  }

  private navigateToTargetPage(uri: string) {
    // 解析uri中的参数(如视频ID、页面路径)
    const params = this.parseAppLinkingParams(uri);
    // 跳转至目标页面(根据参数动态跳转)
    router.pushUrl({ url: `/pages/livePlayback?videoId=${params.videoId}` });
  }

  private parseAppLinkingParams(uri: string): { videoId: string } {
    // 实际开发中需按App Linking生成规则解析参数
    const urlObj = new URL(uri);
    return { videoId: urlObj.searchParams.get('videoId') || '' };
  }
}

四、异常场景处理与用户体验优化

4.1 常见异常场景及处理方案

异常场景 处理方式 代码示例
回调超时(超过3秒未调用share()) 系统自动终止分享,弹窗提示“操作超时” 提前预加载分享数据,避免回调中耗时操作
当前界面无可分享内容 调用clarifyNonShare()终止分享,提示用户 sharableTarget.clarifyNonShare({ message: '当前页面无可用分享内容,请选择文件后重试' })
分享数据下载失败(如云端图片) 调用reject()终止分享,指定错误码 sharableTarget.reject(harmonyShare.SharableErrorCode.DOWNLOAD_ERROR)
接收端拒绝信任/拒绝接收 系统通过通知提示发送端,无需开发者额外处理 -

4.2 用户体验优化建议

  • 手势引导可视化:在可分享界面添加动态引导图(如手势步骤动画),提示用户“伸掌停留→握拳抓取→移动→放手”的操作流程,降低学习成本(可下载官方手势引导资源,放置于rawfile目录);
  • 状态反馈及时化:传输过程中显示进度条(如“传输中30%”),传输成功/失败后给出明确提示(如弹窗、Toast),让用户实时掌握状态;
  • 权限说明透明化:首次开启功能时,通过应用内引导页说明“开启隔空传送将联动开启蓝牙、WLAN,读取设备信息”,避免用户因权限弹窗产生抵触;
  • 设备发现提示:若未检测到可接收设备,提示用户“确保接收端已开启隔空传送且在附近”,帮助用户快速定位问题。

五、开发最佳实践总结

  1. 监听注册与取消时机:严格遵循“进入可分享界面注册,离开/退后台取消”,避免内存泄漏和误触发;
  2. 超时处理优先级:回调中优先发起分享,耗时操作(如图片下载)可通过“先发送核心数据,后更新预览图”的方式(参考碰一碰分享的延迟更新逻辑);
  3. 版本适配:针对HarmonyOS 5.0以下版本,隐藏隔空传送功能入口,避免不支持的设备出现异常;
  4. 安全合规:不存储用户的设备标识符、账号信息等敏感数据,仅通过Share Kit提供的合法接口获取必要信息;
  5. 测试重点:重点测试手势识别成功率(不同距离、光线条件下)、双端账号信任逻辑、与隔空截屏的联动效果,确保功能稳定性。

六、总结

隔空传送作为HarmonyOS全场景交互的重要组成部分,以自然手势打破了设备接触的限制,为用户带来更便捷、更具科技感的分享体验。开发者通过本文的指南,可快速完成功能集成,并结合实际业务场景优化交互细节,让应用在多设备协同生态中更具竞争力。随着鸿蒙生态的持续扩展,隔空传送未来还将支持更多设备类型(如智慧屏、手表)和数据格式,进一步丰富全场景分享能力。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐