引言
想象一个场景:你正在平板上编辑一份文档,需要插入一张纸质资料的照片。平板没有后置摄像头,或者拍照体验远不如手机——这时候如果能直接调起旁边那台手机的相机,拍完照片自动传回平板,那该多省事。
这就是鸿蒙跨设备互通要解决的问题。它提供了一种能力,让一台设备可以调用同账号下另一台设备的相机、扫描和图库功能,拍照、扫文档、选图片视频,都不用再手动传来传去。
本文基于鸿蒙跨设备互通的开发接口,梳理这项能力的适用范围、使用条件,以及如何在应用中完成一次完整的跨设备调用。适合对鸿蒙开发有一定基础、希望为应用接入多设备协同能力的开发者阅读。
一、哪些设备能互通,谁能调用谁
跨设备互通并不是任意两台鸿蒙设备之间都能随便调用的,它有一套明确的设备关系和调用方向。
1.1 基础调用关系
最初的设计思路很直观——屏幕更大、但拍照能力可能不够好的设备,去调用拍照更强的设备:
- 2in1 设备可以调用平板和手机
- 平板可以调用手机
也就是说,调用方向大致是"大屏调小屏"。
1.2 API 6.1.0(23) 之后的扩展
从 API 6.1.0(23) 开始,调用关系变得更加灵活。手机、平板和 2in1 设备都可以作为发起方,去调用远端设备的能力,但远端设备能提供什么能力,取决于设备类型:
| 远端设备类型 | 可被调用的能力 |
|---|---|
| 手机 | 拍照、扫描、图库(图片与视频) |
| 平板 | 拍照、扫描、图库(图片与视频) |
| 2in1 设备 | 图库(图片与视频) |
简单来说,手机和平板是"全能选手",三项能力都能被远端调用;2in1 设备因为自身定位,只对外开放图库能力。
1.3 必须满足的前提条件
要让跨设备互通正常工作,以下条件缺一不可:
- 系统版本:双端设备都需要运行 HarmonyOS NEXT 及以上版本。
- 同一账号:双端设备必须登录同一个华为账号。
- 网络和蓝牙:双端设备都需要打开 WLAN 和蓝牙开关。如果条件允许,接入同一个局域网可以明显提升唤醒远端相机的速度。
如果在调用视频选择器时遇到资源加载异常,建议先确认双端的设备调用能力是否匹配、系统状态是否正常,然后在稳定的网络环境下重试。
二、核心流程:从发现设备到接收数据
跨设备互通的开发流程可以拆解为三个环节:发现可用设备 → 发起调用 → 接收回传数据。鸿蒙为这三个环节提供了对应的组件支持。
2.1 发现设备:设备列表选择器
第一步是让用户看到周围有哪些设备可以调用。这通过 createCollaborationServiceMenuItems 来实现——它是一个自定义构建函数,作用是在菜单中展示当前组网内具备对应互通能力的设备列表。
使用时需要传入一个能力过滤参数(CollaborationServiceFilter),告诉它你需要哪种能力的设备。目前支持的过滤值包括:
| 过滤值 | 含义 |
|---|---|
ALL | 匹配拍照、扫描和图库选择器(预留值,后续会拓展) |
TAKE_PHOTO | 匹配跨设备拍照能力 |
SCAN_DOCUMENT | 匹配跨设备扫描能力 |
IMAGE_PICKER | 匹配跨设备图库(图片)能力 |
VIDEO_PICKER | 匹配视频选择器 |
IMAGE_VIDEO_PICKER | 匹配图片和视频选择器 |
有一点需要注意:这个方法必须在 Menu 组件内调用,因为它本质上是往菜单里填充设备列表项。同时它是一个 @Builder 自定义构建函数,如果你对 @Builder 的用法还不太熟悉,建议先了解一下相关文档。
2.2 状态提示与数据回传:弹窗组件
当用户选择了一台远端设备并触发操作后(比如在远端手机上拍照),你需要一个组件来做两件事:一是提示用户远端设备当前的操作状态,二是在操作完成后接收回传的数据。
CollaborationServiceStateDialog 就是做这个的。它是一个全局弹窗组件,放在页面的 build 方法中即可,不会影响原有的页面布局。它最关键的部分是 onState 回调方法,这个回调会在远端操作完成时被触发,带回三个参数:
- stateCode:操作完成状态,0 表示成功
- bufferType:回传数据的类型(比如
"general.image"表示图片) - buffer:回传的数据内容本身(
ArrayBuffer格式)
开发者只需要在 onState 里根据这些参数,结合自己的业务逻辑处理回传数据即可。
三、完整开发实践:调用远端相机拍照并显示
理解了上面的核心流程后,我们来看一个完整的实现。这个示例的目标很简单:点击按钮弹出可用设备列表,选择一台远端设备拍照,拍完后把照片显示在本端页面上。
3.1 导入所需模块
import {
createCollaborationServiceMenuItems,
CollaborationServiceStateDialog,
CollaborationServiceFilter
} from '@kit.ServiceCollaborationKit';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
这里引入了三个 Kit:ServiceCollaborationKit 提供跨设备互通的核心能力,ImageKit 用于处理回传的图片数据,PerformanceAnalysisKit 用于日志输出。
3.2 搭建页面结构
@Entry
@Component
struct Index {
@State picture: PixelMap | undefined = undefined;
@Builder
MyTestMenu() {
Menu() {
createCollaborationServiceMenuItems([CollaborationServiceFilter.ALL])
}
}
build() {
Column({ space: 20 }) {
// 状态弹窗:全局组件,不影响布局
CollaborationServiceStateDialog({
onState: (stateCode: number, bufferType: string, buffer: ArrayBuffer): void =>
this.doInsertPicture(stateCode, bufferType, buffer)
})
// 按钮:点击后弹出设备选择菜单
Button('使用远端设备进行拍照')
.type(ButtonType.Normal)
.borderRadius(10)
.bindMenu(this.MyTestMenu)
// 图片展示区:拍照完成后显示回传的照片
if (this.picture) {
Image(this.picture)
.borderStyle(BorderStyle.Dotted)
.borderWidth(1)
.objectFit(ImageFit.Contain)
.height('80%')
.onComplete((event) => {
if (event != undefined) {
hilog.info(0, "MEMOMOCK", "onComplete " + event.loadingStatus)
}
})
}
}
.padding(20)
.width('100%')
.alignItems(HorizontalAlign.Center)
}
}
整个页面结构很清晰:顶部是全局的状态弹窗(用户感知不到它的存在,除非有状态需要提示),中间是触发操作的按钮,底部是照片展示区域。
按钮通过 .bindMenu(this.MyTestMenu) 绑定了设备列表菜单。用户点击按钮后,会看到周围可用的设备列表,选中某台设备就会唤起该设备的相机。
3.3 处理回传的照片数据
doInsertPicture(stateCode: number, bufferType: string, buffer: ArrayBuffer): void {
if (stateCode != 0) {
return
}
if (bufferType == "general.image") {
let imageSource = image.createImageSource(buffer)
imageSource.createPixelMap().then((pixelMap) => {
this.picture = pixelMap;
})
}
}
这段逻辑是整个流程的"收尾"环节:
- 先检查
stateCode是否为 0(即操作成功),不成功则直接返回。 - 确认回传数据类型是图片(
"general.image")。 - 用
ImageKit的createImageSource从ArrayBuffer创建图片源,再转成PixelMap。 - 赋值给状态变量
picture,触发页面刷新,照片就显示出来了。
整个过程中,开发者不需要关心设备发现、连接建立、数据传输这些底层细节,框架已经把这些封装好了。你只需要关注"要什么能力"和"拿到数据后怎么用"。
四、总结与实践建议
跨设备互通的核心价值在于打破了单台设备的能力边界。对于平板、2in1 这类大屏设备来说,它补齐了拍照和扫描的短板;对于多设备协作的场景,它省去了拍照后手动传文件的繁琐操作。
从开发角度看,这项能力的接入成本并不高。核心就是两个组件的配合使用:createCollaborationServiceMenuItems 负责设备发现和选择,CollaborationServiceStateDialog 负责状态提示和数据回传。开发者的主要工作集中在 onState 回调中——根据回传的数据类型,做好业务层面的处理即可。
在实际接入时,有几点值得注意:
- 能力过滤要精准:如果你的场景只需要拍照,传
TAKE_PHOTO而不是ALL,可以让设备列表更准确,避免用户看到不相关的选项。 - 同一局域网能提速:虽然 WLAN + 蓝牙是最低要求,但接入同一局域网对唤醒速度有明显帮助,在产品文案或引导中可以提示用户。
- 关注 API 版本差异:6.1.0(23) 前后的调用方向有变化。如果你的应用需要兼容较早版本,在设备能力判断上要做好区分。
- 回传数据类型判断:
onState回调中的bufferType会区分图片和视频等不同类型,做好类型判断再处理,避免数据解析出错。
对于已经在做多设备协同场景的应用来说,跨设备互通是一个值得优先接入的能力——它的使用门槛低,但带来的体验提升是用户能直接感知到的。