
本文主线落在 HarmonyOS 6.1.0(23) 的调用策略扩展并顺带讲清算 6.0.0(20) 新增的视频选择器。文中的 API 名称、枚举取值与版本号来自华为官方文档结构、代码示例、调用方向矩阵与自检清单为本人整理编写未在真机逐行验证涉及真机表现的部分以真机实测为准。引子一句话需求三个隐藏前提产品需求单上常出现这么一句在平板上填表需要一张证件照平板没好镜头直接调手机的相机拍一张传回来。听起来像弹个菜单 选设备 收图片。V哥按这个直觉开干第一天就被泼了冷水——菜单弹出来设备列表是空的。不是代码写错是三个前提少了一个。这里有个画面感你按了按钮系统应该弹出一个设备选择菜单里面躺着同一账号下、开了 WLAN 和蓝牙的远端正列表。结果V哥的菜单空空如也只有一个孤零零的无可用设备。那一刻最容易犯的错是回头怀疑createCollaborationServiceMenuItems写错了、怀疑Builder没挂对。其实接口一个都没错是网络那头的灯没亮。这篇就把这三个前提、谁能调谁、怎么收数据一次讲清顺带把最容易混淆的版本线划明白。一、先校准版本别把 5.x 的写法当成 6.x 的能力这是本选题最容易踩的坑。官方《跨设备互通开发指导》的约束与限制里调用策略分了两截调用策略PC/2in1 设备可以调用 Tablet 和 PhoneTablet 可以调用 Phone从 API 6.1.0(23) 开始TV、Phone、Tablet 或 PC/2in1 设备可调用具备拍照、扫描及图库能力的远端设备。Service Collaboration Kit 简介注意后半句——6.1.0(23) 之前接口只能在 PC/2in1、Tablet 上正常调用在 Phone、TV 上直接无法展示设备列表、无法使用能力。6.1.0(23) 之后Phone 和 TV 也能当主控了。V哥自己的判断这套能力的主控方是被系统写死的不是你能看见谁就调谁。6.1.0(23) 是它第一次把主控方从平板/2in1扩到电视/手机也能发起。所以写 6.0 的文章主线就该落在这个扩展上而不是只讲平板调手机这条老链路。另一个 6.0 切口在过滤器上createCollaborationServiceMenuItems的businessFilter在6.0.0(20)起新增了视频选择器VIDEO_PICKER与图文混合选择器IMAGE_VIDEO_PICKER之前只有拍照、扫描、图库三种。顺带说两句排错心得设备列表为空时先按三道门槛排查再对照调用方向矩阵——同类型设备互调是全版本都不行的不是你权限没配对。这两张表对不上代码写得再好也是白跑。另外StateDialog 回调拿到的 ArrayBuffer 要先判空再解码远端设备中途取消时它就是空的这种情况该给用户一个对方已取消的提示别当异常直接抛出去。二、三道门槛同账号、WLAN、蓝牙缺一列表就空不管你用 ArkTS 还是 NDK设备列表能不能出来先看这三件门槛要求V哥的理解华为账号双端登录同一个华为账号不是都登录了就行是同一个。换账号列表直接空网络双端打开 WLAN建议接同一局域网唤醒相机更快蓝牙也得开蓝牙双端打开蓝牙开关和 WLAN 是并列条件不是二选一双端设备需要登录同一华为账号双端设备需要打开 WLAN 和蓝牙开关。Service Collaboration Kit 简介第一个自创口诀远端没登同一个账号设备列表直接是空的——三件套缺一列表就是空的。调试时别先怀疑代码先看这三盏灯。模拟器不支持本能力验证必须在真机双端上做。三、调用方向矩阵谁能动谁系统说了算把官方策略拆成一张本端 → 远端的表配上V哥的使用建议本端主控可调用远端版本边界V哥的理解PC/2in1Tablet、Phone5.0 起即支持最稳的主控方能力全开TabletPhone5.0 起即支持平板调手机镜头的经典链路TV有拍照/扫描/图库的 Phone、Tablet有图库的 PC/2in16.1.0(23) 起电视也能当主控但被控方要带相机Phone同上带相机/图库的远端6.1.0(23) 起手机反向调别家镜头这是 6.x 新开的口同类型设备如手机调手机不可调用全版本同形态互斥别指望手机调手机第二个自创判断同类型设备不可互相调用是一条硬规则不是网络没连上。你想用另一台手机补拍系统不会给你列出来——这跟账号、网络都没关系。四、ArkTS 主线把设备选择器塞进 MenuArkTS 侧两个组件必须配合使用createCollaborationServiceMenuItems拿设备列表和CollaborationServiceStateDialog收远端状态。前者是Builder自定义构建函数必须在Menu内调用。// RemoteShoot.ets —— 自写的跨设备拍照封装命名/注释均为本人整理import{createCollaborationServiceMenuItems,CollaborationServiceStateDialog,CollaborationServiceFilter}fromkit.ServiceCollaborationKit;import{image}fromkit.ImageKit;// 复用官方约定的回传结果码0 成功其余为异常分支constCOLLAB_OK0;constCOLLAB_PEER_CANCEL1001202001;// 远端取消constCOLLAB_FRAMEWORK_ERR1001202002;// 框架内部错误constCOLLAB_LOCAL_CANCEL1001202003;// 本端取消EntryComponentstruct RemoteShootPage{Statesnapshot:image.PixelMap|undefinedundefined;// 设备选择菜单挂在 Menu 里弹出时由系统拉起设备列表BuilderdeviceMenu(){Menu(){// 只匹配跨端拍照能力要图库可换成 IMAGE_PICKERcreateCollaborationServiceMenuItems([CollaborationServiceFilter.TAKE_PHOTO]);}}// 把远端回传的 ArrayBuffer 解码成 PixelMapprivateasyncdecodeToPixelMap(buf:ArrayBuffer):Promiseimage.PixelMap|undefined{if(buf.byteLength0){returnundefined;}try{constsourceimage.createImageSource(buf);returnawaitsource.createPixelMap();}catch(e){console.error(解码远端图片失败);returnundefined;}}build(){Column({space:16}){// 状态弹窗全局组件挂页面即可不占布局CollaborationServiceStateDialog({onState:(stateCode:number,bufferType:string,buffer:ArrayBuffer):void{if(stateCodeCOLLAB_OKbuffer.byteLength0){this.decodeToPixelMap(buffer).then((pm){this.snapshotpm;});return;}console.info(跨设备互通结束stateCodestateCode);}})Button(用手机镜头拍一张).bindMenu(this.deviceMenu)if(this.snapshot){Image(this.snapshot).width(80%).height(300).objectFit(ImageFit.Contain)}}.padding(20).width(100%)}}两个要点createCollaborationServiceMenuItems还有个带canReceiveNumber1~50的重载用来限制图库可选图片张数businessFilter在 6.0.0(20) 起支持VIDEO_PICKER/IMAGE_VIDEO_PICKER老版本传这两个值不会报错但能力不匹配。为什么这个组件必须是放进 Menu而不是你自己在页面画一个列表因为设备列表的拉起、可信设备校验、对端应用唤起全是系统统一兜底的——你自己画列表既拿不到可信设备也绕不开账号/WLAN/蓝牙那三盏灯。换句话说createCollaborationServiceMenuItems不是给你一个 API 让你造界面而是把系统已经做好的设备选择器借你挂一下。理解到这一层你就不会想着去自定义列表样式了那是系统不让动的。五、收数据onState 的三个参数别接反CollaborationServiceStateDialog的核心就是onState回调三个参数顺序是固定的stateCode完成状态0 成功其余见上方常量bufferType回传数据类型目前官方文档标注仅支持general.imagebuffer回传的原始数据ArrayBuffer格式失败时为空。第三个自创判断把解码当成一道独立关卡而不是在 onState 里顺手写。远端回传的是裸ArrayBuffer你要么用image.createImageSource转成PixelMap要么自己落盘。数据坏了、为空、解码异常三种情况要分开处理——别一句 Toast 掩盖掉否则用户只会说拍了没反应。六、NDK 三件套Get / Start / Stop如果你的相机页是 C/C 渲染管线用 NDK 更直接。头文件service_collaboration/service_collaboration_api.h链接库libservice_collaboration_ndk.z.so能力起点5.0.0(12)。核心三件套HMS_ServiceCollaboration_GetCollaborationDeviceInfos按能力类型拿设备列表HMS_ServiceCollaboration_StartCollaboration拉起远端能力HMS_ServiceCollaboration_StopCollaboration主动取消。// collab_entry.cpp —— 自写的 NDK 调用骨架#includeservice_collaboration/service_collaboration_api.hstaticint32_tOnEventProc(ServiceCollaborationEventCode code,uint32_textra){return0;}staticint32_tOnDataProc(ServiceCollaborationEventCode code,ServiceCollaborationDataType type,uint32_tsize,char*data){return0;}voidshootFromPhone(){// 1. 先要设备列表传 TAKE_PHOTO 能力系统回匹配的远端ServiceCollaborationFilterType filters[]{TAKE_PHOTO,SCAN_DOCUMENT,IMAGE_PICKER};ServiceCollaboration_CollaborationDeviceInfoSets*infoHMS_ServiceCollaboration_GetCollaborationDeviceInfos(3,filters);if(infonullptr||info-size0){return;// 列表空回头查三道门槛}// 2. 选第一台设备构造回调ServiceCollaboration_SelectInfo task{TAKE_PHOTO,{0}};auto*dev(info-deviceInfoSets[0]);// deviceNetworkId 拷贝进 task长度上限见 COLLABORATIONDEVICEINFO_DEVICENETWORKID_MAXLENGTHServiceCollaborationCallback cb{.OnEventOnEventProc,.OnDataCallbackOnDataProc};// 3. 拉起远端相机uint32_tidHMS_ServiceCollaboration_StartCollaboration(task,cb);// 需要视频回传时用 StartCollaborationV2支持 IMAGE_VIDEO_PICKER 的远端HMS_ServiceCollaboration_StopCollaboration(id);// 不再需要时取消}NDK 侧的ServiceCollaborationFilterType取值为TAKE_PHOTO1、SCAN_DOCUMENT2、IMAGE_PICKER3、VIDEO_PICKER5、IMAGE_VIDEO_PICKER6回传数据类型ServiceCollaborationDataType有IMAGE1、VIDEO2。要视频回传请用StartCollaborationV2它是 6.0.0(20) 视频能力在 NDK 上的对应入口。ArkTS 还是 NDK怎么选如果业务逻辑就在 ArkTS 页面里、要的也只是弹菜单选设备 收一张图那 ArkTS 两个组件足够省去 NDK 工程化成本。只有当你本来就是 C/C 渲染管线比如相机预览、图像处理全在 native 侧或者要精细控制设备网络 ID、做视频流回传才值得上 NDK。二者底层走的是同一套协同框架能力范围一致区别只在你代码停在哪一层。七、上线自检清单三道门槛双端同一华为账号、WLAN、蓝牙都开了吗模拟器不支持必须在真机双端验证调用方向合规吗本端是不是在 6.1.0(23) 允许的主控范围TV/Phone/Tablet/PC-2in1同类型设备互调会被系统拒主版本够吗要视频选择器VIDEO_PICKER/IMAGE_VIDEO_PICKER必须6.0.0(20)起主控方含 TV/Phone 必须6.1.0(23)起createCollaborationServiceMenuItems放在Menu里了吗Builder写对了吗CollaborationServiceStateDialog挂在页面build里了吗onState三参数顺序对了吗buffer为空和解码失败两种情况分开处理了吗bufferType只认general.image有兜底吗图库多选场景canReceiveNumber落在 1~50 了吗NDK 侧链接libservice_collaboration_ndk.z.so了吗deviceNetworkId拷贝长度没越界吗视频回传走了StartCollaborationV2吗远端取消1001202001、本端取消1001202003都有用户提示吗参考与出处本文涉及的事实性信息API 名称、枚举取值、版本号、官方约束来自以下官方文档文中的结构、代码示例、调用方向矩阵与自检清单为本人整理编写Service Collaboration Kit 简介约束与调用策略跨设备互通开发指导CollaborationServiceArkTS API跨设备互通 NDK 开发指导service_collaboration_api.hNDK C API最后一句跨设备互通真正难的不是调接口是承认它有一张写死的主控表、有一组非黑即白的门槛。把三件套缺一列表就空刻进调试习惯剩下就是把onState三个参数接对、把ArrayBuffer解码成图。