如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。
1、前言
HarmonyOS的一个非常大的特点就是跨设备协同。针对开发者,HarmonyOS提供了一套协同服务套件(Service Collaboration Kit)提供了同账号下多端设备的协同能力。
用户通过此能力实现跨设备交互,使用其他设备的相机、扫描和图库功能。
需要注意的是,使用跨设备协同能力,设备需要具备以下基本条件:
-
双端设备需要登录同一华为账号;双端设备需要打开WLAN和蓝牙开关。
-
本端设备为HarmonyOS版本为HarmonyOS NEXT 4.0及以上的平板或2in1设备, 远端设备:HarmonyOS版本为HarmonyOS NEXT 4.0及以上、具有相机能力的手机或平板设备。
2、特性介绍
跨设备互通提供跨设备的相机、扫描、图库访问能力,平板或2in1设备可以调用手机的相机、扫描、图库等功能。
用户在平板、手机或电脑等设备上使用富文本类编辑应用(如:备忘录、邮件、笔记等)时,想要拍摄一些照片作为素材,但是当前设备拍摄不太方便。
通过跨设备互通-拍照,用户可以在当前设备的应用中指定平板或手机设备,并打开平板或手机的相机来拍摄所需的素材。通过手机或者平板设备拍摄,移动更便利、取景更灵巧、相机能力也更强大。拍摄的照片将实现快速回传到平板、手机或电脑设备的应用中,帮助用户高效完成图文并茂的文档设计。整个过程大致的演示效果如下:
为了实现:协同拍摄设备的选取、拍摄结果的获取,这个两个能力,HarmonyOS提供了两个关键的API,分别是:
-
createCollaborationServiceMenuItems
这个API可以实现自动扫描附近可用的设备,当附近有一个或两个设备时,菜单将会直接平铺显示,显示效果示例如下:
当附近有两个以上的设备时,将会折叠到一个菜单中去,示例效果如下:
关键示例代码如下:
import { createCollaborationServiceMenuItems, CollaborationServiceFilter } from '@kit.ServiceCollaborationKit';
@Builder
MyTestMenu() {
Menu() {
// 第一个参数是过滤类型,第二个参数是可以获取的张数
createCollaborationServiceMenuItems([CollaborationServiceFilter.ALL], 30)
}
}
其中CollaborationServiceFilter 是枚举类型,可以选择的值可以是:
enum CllaborationServiceFilter {
ALL = 0 // 匹配所有业务。
TAKE_PHOTO = 1 // 匹配跨端拍照。
SCAN_DOCUMENT = 2 // 匹配文档扫描。
IMAGE_PICKER = 3 //匹配图库选择器。
}
-
CollaborationServiceStateDialog
这个API用于在调用远端拍照过程中,在本端给用户显示远端状态的提示对话框。同时,如果拍摄完毕后,将会由此组件将拍摄或者获取的数据回调。
关键的示例代码如下:
import { CollaborationServiceStateDialog } from '@kit.ServiceCollaborationKit';
CollaborationServiceStateDialog({
onState: (stateCode: number, bufferType: string, buffer: ArrayBuffer):void => this.doInsertPicture(stateCode, bufferType, buffer)
})
拍摄状态可能为:对端设备拍摄中、图片导入中、协同失败、本端WLAN未开启、对端WLAN未开启。
【远端拍摄中】示例如下:
【图片导入中】示例如下:
【协同失败】示例如下:
【本端WLAN未开启】示例如下:
【对端WLAN未开启】示例如下:
3、开发
一般情况下,我们的开发分为3步。
👉🏻 step 1:导入模块
import { createCollaborationServiceMenuItems, CollaborationServiceStateDialog, CollaborationServiceFilter } from '@kit.ServiceCollaborationKit';
👉🏻 step 2:调用设备选择器组件,显示可用列表。
使用createCollaborationServiceMenuItems 用于显示可用组件,其中支持两个参数
第一个参数传入Array类型的CollaborationServiceFilter枚举值即可使用对应能力,目前支持ALL、TAKE_PHOTO、SCAN_DOCUMENT和IMAGE_PICKER。【ALL为预留值,匹配所有业务,功能将在后续拓展,TAKE_PHOTO匹配跨设备拍照能力,SCAN_DOCUMENT匹配跨设备扫描能力,IMAGE_PICKER匹配跨设备图库能力】
第二个参数可以传入一个数字,表示接收的张数的上限,目前范围是1 ~ 50.
@Builder
MyTestMenu() {
Menu() {
createCollaborationServiceMenuItems([CollaborationServiceFilter.ALL], 30)
}
}
👉🏻 step 3:显示等待弹窗并监听回调数据。
在build方法中添加弹窗组件CollaborationServiceStateDialog,用于提示远端相机拍摄状态和回传数据。需要实现其中的onState方法。
【CollaborationServiceStateDialog是全局的提示框,不会对原有布局产生影响】
CollaborationServiceStateDialog({
onState: (stateCode: number, bufferType: string, buffer: ArrayBuffer):void => this.doInsertPicture(stateCode, bufferType, buffer)
})
一个完整的Demo如下:
import {
createCollaborationServiceMenuItems,
CollaborationServiceStateDialog,
CollaborationServiceFilter
} from '@kit.ServiceCollaborationKit';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
@Entry
@Component
struct Index {
@State picture: PixelMap | undefined = undefined;
@Builder
MyTestMenu() {
Menu() {
createCollaborationServiceMenuItems([CollaborationServiceFilter.ALL], 30)
}
}
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)
}
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;
})
}
}
}