引言

跨设备传文件这件事,我们已经做了太多年了——蓝牙配对、扫码互传、聊天窗口转发、甚至给自己发邮件。这些方式都能用,但都不够"顺手"。

鸿蒙 Share Kit 新推出的隔空传送,尝试用一种更自然的交互来解决这个问题:用户对着屏幕做一个"抓取"手势,内容就被"拿"起来了,再对着另一台设备"放下",内容就传过去了。整个过程不需要打开任何传输工具,也不需要手动选择接收设备。

本文面向希望在应用中接入隔空传送能力的鸿蒙开发者,梳理这项功能的工作机制、与系统其他功能的联动关系,以及具体的接入方法。


一、隔空传送是怎么工作的

1.1 基本交互逻辑

隔空传送的核心交互是"一抓一放"——用户在一台设备前做出握拳抓取的手势,设备捕捉到这个动作后,将当前页面的分享内容"抓起来";然后用户面向另一台设备做出释放手势,内容就传送到了对端设备上。

这个手势并不是凭空工作的。它依赖应用侧主动注册分享事件——只有当前页面注册了隔空传送的监听,系统才知道"这个页面有东西可以分享"。如果页面没注册,手势不会触发隔空传送。

1.2 使用前提:打开隔空传送开关

隔空传送默认不是开启状态,用户需要手动打开:

设置 → 系统 → 快捷启动和手势 → 隔空传送

这是设备级的开关,对所有支持隔空传送的应用生效。

1.3 设备信任机制

传输的安全性通过设备信任关系来保障,分两种情况:

  • 同账号设备:如果两台设备登录了相同的华为账号,系统默认它们互相信任,传输时无需额外确认,直接发送。
  • 不同账号设备:需要双端用户各自确认"信任对方设备"。确认后,1 小时内再次传输无需重复确认。超过 1 小时则需要重新建立信任。

这种设计在便捷性和安全性之间取了一个平衡——自己的设备间传东西零障碍,借别人设备传也不会被滥用。


二、隔空传送与隔空截屏的关系

一个容易让人困惑的地方是:隔空传送和隔空截屏共用同一个手势触发。这意味着用户做"抓取"动作时,可能同时触发两件事。系统通过两个开关的组合状态来决定具体行为:

隔空传送开启 隔空传送关闭
隔空截屏开启 图库场景传输原图;其他场景传送截屏 仅截屏,不传送
隔空截屏关闭 图库场景传送原图;其他场景无截屏也不传送 什么都不发生

几个值得注意的细节:

  • 当两个开关都打开,且当前页面注册了隔空传送事件时,抓取手势会同时触发隔空传送和隔空截屏。此时隔空传送的卡片下方会出现"保存截屏至本机"的提示。
  • 首次触发时,默认不保存截屏。用户可以手动勾选保存,系统会记住这个选择,作为下次的默认值。
  • 如果只开了隔空截屏、没开隔空传送,那抓取手势就只是截屏,不会有任何传输行为。

对于开发者来说,不需要关心截屏逻辑——这完全是系统层面的行为。你只需要关注隔空传送的注册和数据准备。


三、接入隔空传送的开发实践

接入隔空传送的核心工作就是三件事:在对的时机注册监听、在回调中准备分享数据、在离开时取消监听

3.1 导入所需模块

import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { systemShare, harmonyShare } from '@kit.ShareKit';
import { fileUri } from '@kit.CoreFileKit';

这里涉及三个 Kit:ShareKit 提供隔空传送和分享的核心能力,ArkData 中的 uniformTypeDescriptor 用于声明分享内容的数据类型,CoreFileKit 用于将文件路径转换为 URI。

3.2 定义手势触发时的分享逻辑

当用户做出抓取手势时,系统会通过注册的回调把一个 SharableTarget 对象传给你。你需要在这个回调里准备好分享数据,然后调用 sharableTarget.share() 把数据发出去。

private immersiveCallback = (sharableTarget: harmonyShare.SharableTarget) => {
  let uiContext: UIContext = this.getUIContext();
  let contextFaker: Context = uiContext.getHostContext() as Context;
  let filePath = contextFaker.filesDir + '/exampleKnock1.jpg';

  let shareData: systemShare.SharedData = new systemShare.SharedData({
    utd: utd.UniformDataType.HYPERLINK,
    content: 'https://sharekitdemo.drcn.agconnect.link/ZB3p',
    thumbnailUri: fileUri.getUriFromPath(filePath),
    title: '隔空传送分享卡片标题',
    description: '隔空传送分享卡片描述'
  });

  sharableTarget.share(shareData);
}

这里有一个关键的时间约束:收到回调后,建议在 3 秒内调用 sharableTarget.share(),否则可能因为超时导致传输失败。所以分享数据的准备不宜太重——如果需要读取大文件或做复杂处理,建议提前准备好,在回调中直接使用。

分享数据通过 SharedData 构造,几个关键字段的含义:

  • utd:声明分享内容的统一数据类型。上面的示例使用的是 HYPERLINK,表示分享一个链接。
  • content:实际的分享内容,这里是一个 App Linking 链接。
  • thumbnailUri:传送卡片上显示的缩略图,需要传入文件的 URI。
  • titledescription:传送卡片上的标题和描述文字。

3.3 分享 App Linking 实现直达应用

上面的示例中,content 字段传入的是一个 App Linking 链接。这样做的好处是:对端设备收到后,点击卡片可以直接跳转到对应的应用页面,而不只是打开一个网页。如果你希望实现这种"传送即直达"的体验,应用需要先接入 App Linking。

3.4 在正确的时机注册和取消监听

这一步直接决定了功能能否正常工作。原则很简单:

  • 进入可分享页面时注册,告诉系统"这个页面有内容可以分享"。
  • 离开可分享页面时取消,包括页面销毁和应用退到后台的场景。

注册和取消的方法很直接:

private immersiveListening() {
  harmonyShare.on('gesturesShare', this.immersiveCallback);
}

private immersiveDisablingListening() {
  harmonyShare.off('gesturesShare', this.immersiveCallback);
}

但"什么时候算离开"需要仔细处理。除了页面销毁(aboutToDisappear),应用退到后台也应该取消监听。一个完整的处理方式如下:

aboutToAppear(): void {
  // 页面出现时注册监听
  this.immersiveListening();

  // 同时监听应用退后台事件
  let uiContext: UIContext = this.getUIContext();
  let context: Context = uiContext.getHostContext() as Context;
  context.eventHub.on('onBackGround', this.onBackGround);
}

aboutToDisappear(): void {
  // 页面销毁时取消监听
  this.immersiveDisablingListening();

  let uiContext: UIContext = this.getUIContext();
  let context: Context = uiContext.getHostContext() as Context;
  context.eventHub.off('onBackGround', this.onBackGround);
}

// 页面隐藏时(包括退后台),通过事件总线通知
onPageHide(): void {
  let uiContext: UIContext = this.getUIContext();
  let context: Context = uiContext.getHostContext() as Context;
  context.eventHub.emit('onBackGround');
}

private onBackGround = () => {
  this.immersiveDisablingListening();
}

这里的思路是:通过 onPageHide 捕捉页面隐藏事件(退后台会触发),然后通过 eventHub 发出通知,在通知处理中取消隔空传送监听。这样无论是页面销毁还是应用退后台,监听都会被正确清理。

为什么要这么认真地处理取消监听? 因为如果应用退到后台后监听还在,用户在其他应用中做抓取手势时,可能会意外触发你的应用的分享逻辑,导致不可预期的行为。


四、总结

隔空传送提供了一种非常直觉化的跨设备内容传输方式。从开发者的角度看,它的接入并不复杂,但有几个关键点需要把握好:

  1. 时效性:收到手势回调后 3 秒内必须完成分享调用。分享数据要提前准备,不要在回调中做耗时操作。
  2. 生命周期管理:注册和取消监听必须与页面的生命周期严格对应。特别是应用退后台的场景,容易被忽略。
  3. 与隔空截屏的共存:理解两个开关的组合行为,在产品设计上给用户清晰的预期。
  4. 信任机制:同账号设备间传输是无感的,不同账号需要双向确认。如果你的应用场景经常涉及跨账号传输,可以在引导中提示用户。

如果你的应用有内容分享的需求——无论是链接、图片还是文件——隔空传送都是一种值得接入的自然交互方式。结合 App Linking,还能实现"传送即打开对应页面"的完整体验,这在跨设备协作场景中会非常实用。

Logo

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

更多推荐