HarmonyOS APP《画伴梦工厂》开发第30篇-跨设备分享——systemShare集成

HarmonyOS APP《画伴梦工厂》开发第30篇-跨设备分享——systemShare集成 第4.4篇跨设备分享——systemShare 集成难度⭐⭐ 进阶前置知识第 2.9 篇 视频导出与本地保存涉及源文件products/default/src/main/ets/services/VideoExportService.ets概述在画伴梦工厂中用户创作完成动画视频后不仅仅希望保存到本地——更希望能与家人、朋友分享甚至发送到其他设备上观看。HarmonyOS 提供了systemShare系统分享能力通过标准化的分享面板让应用可以将内容分享到其他应用或跨设备传输。systemShare是kit.ShareKit中的核心模块它封装了系统级的分享服务支持视频、图片、文本等多种数据类型并且天然具备跨设备分享能力——用户可以将内容一键分享到同一华为账号下的平板、智慧屏、手机等其他设备。本文将深入解析systemShare在项目中的完整集成实践涵盖ShareController创建与配置、SharedData多记录数据构建、uniformTypeDescriptor类型描述、以及跨设备分享的实际应用场景。一、systemShare 整体架构1.1 核心类与接口systemShare模块围绕三个核心概念构建类/接口说明systemShare.ShareController分享控制器负责展示系统分享面板并管理分享流程systemShare.SharedData分享数据容器可包含一条或多条分享记录systemShare.ShareControllerOptions分享控制选项配置选择模式和预览模式systemShare.SelectionMode选择模式枚举SINGLE单选应用、MULTIPLE多选应用systemShare.SharePreviewMode预览模式枚举DETAIL详细预览、SUMMARY概览预览1.2 分享流程概览用户点击分享按钮 │ ▼ prepareVideo() → 准备视频文件缓存目录 │ ▼ buildSharedData() → 构建分享数据视频 文本 │ ▼ new ShareController(data) → 创建分享控制器 │ ▼ controller.show(context, options) → 弹出系统分享面板 │ ├──→ 用户选择目标应用 → 执行分享 │ └──→ 用户取消 → 静默结束整个过程仅需四个步骤——准备文件、构建数据、创建控制器、调用 show 方法——即可完成一次完整的系统分享。二、ShareController分享控制器2.1 创建 ShareControllerShareController是分享流程的入口其构造函数接收一个SharedData实例constdataawaitVideoExportService.buildSharedData(videoUri,title,story,rawFilePath);constcontrollernewsystemShare.ShareController(data);ShareController实例化后会立即解析SharedData中的记录信息准备展示分享面板。2.2 启动分享面板constoptions:systemShare.ShareControllerOptions{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL};awaitcontroller.show(context,options);show方法接收两个参数contextUIAbilityContext实例用于获取当前页面的上下文环境。optionsShareControllerOptions配置对象控制分享面板的行为和外观。show是一个异步方法返回Promisevoid。当用户选择目标应用完成分享或取消操作时Promise 会 resolve。注意ShareController实例为一次性使用。每次分享都需要重新创建ShareController和SharedData。三、ShareControllerOptions 配置详解ShareControllerOptions提供了两个关键的配置项分别控制分享应用的选择方式和预览界面的展示形态。3.1 selectionMode选择模式selectionMode:systemShare.SelectionMode.SINGLE枚举值说明适用场景SelectionMode.SINGLE单次选择模式用户一次只能选择一个目标应用快速分享给单个好友或设备SelectionMode.MULTIPLE多选模式用户可以选择多个目标应用同时分享同时分享到多个社交平台在画伴梦工厂中我们使用SINGLE模式。对于儿童动画视频的分享场景通常用户只会将视频分享给特定的联系人如家人或发送到特定的设备如智慧屏单次选择模式更符合直觉。3.2 previewMode预览模式previewMode:systemShare.SharePreviewMode.DETAIL枚举值说明效果SharePreviewMode.DETAIL详细预览模式分享面板中会显示分享内容的详细预览信息缩略图、标题、描述SharePreviewMode.SUMMARY概览预览模式仅显示简洁的分享概览信息项目中选择了DETAIL模式。当用户分享动画视频时详细预览可以让用户在发送前确认视频的标题和故事描述是否正确提供更好的用户体验。3.3 配置组合效果DETAIL SINGLE: ┌─────────────────────────────────────┐ │ 系统分享面板 │ │ ┌──────────────────────────────┐ │ │ │ 我的小汽车 │ │ │ │ 一辆红色的小汽车在公路上... │ │ │ │ [视频缩略图] │ │ │ └──────────────────────────────┘ │ │ │ │ 选择应用 │ │ [微信] [钉钉] [智慧屏] [蓝牙] │ │ │ └─────────────────────────────────────┘四、SharedData构建分享数据4.1 多记录数据模型systemShare.SharedData支持包含多条记录每条记录可以有不同的数据类型。在项目中我们构建了视频记录和文本记录两条数据staticasyncbuildSharedData(videoUri:Resource|string,title:string,story:string,rawFilePath:string):PromisesystemShare.SharedData{constpreparedawaitVideoExportService.prepareVideo(videoUri,title,rawFilePath);// 视频记录constvideoRecord:ShareVideoRecord{utd:uniformTypeDescriptor.UniformDataType.MPEG4,uri:prepared.uri,title:title,description:story};constdatanewsystemShare.SharedData(videoRecord);// 文本记录添加为次要记录consttextRecord:ShareTextRecord{utd:uniformTypeDescriptor.UniformDataType.PLAIN_TEXT,content:title\nstory,title:title,description:story};data.addRecord(textRecord);returndata;}4.2 记录类型接口项目中定义了两个分享记录接口interfaceShareVideoRecord{utd:string;// Uniform Type Descriptor标识数据类型uri:string;// 视频文件的 URItitle:string;// 作品标题description:string;// 作品故事描述}interfaceShareTextRecord{utd:string;// 数据类型标识content:string;// 文本内容title:string;// 标题description:string;// 描述}4.3 记录添加机制主记录通过new systemShare.SharedData(primaryRecord)在构造函数中指定。次要记录通过data.addRecord(record)方法动态添加支持添加多条。当系统分享面板接收到包含多条记录的SharedData时会根据目标应用的能力自动选择合适的记录进行分享。例如目标应用行为微信/钉钉同时展示视频和文本用户可选择发送智慧屏/电视优先分享视频记录忽略文本记录备忘录/笔记优先分享文本记录视频作为附件蓝牙传输传输视频文件文本作为文件描述这种多条记录、按需选择的机制使得一次分享可以适配多种不同类型的目标应用。五、uniformTypeDescriptor统一类型描述5.1 什么是 UTDuniformTypeDescriptorUniform Type Descriptor统一类型描述符是 HarmonyOS 中用于标识文件和数据类型的标准化描述体系。它类似于 MIME 类型但更加精细和层次化。kit.ArkData中的uniformTypeDescriptor模块预定义了系统中常见的标准数据类型常量对应类型说明UniformDataType.MPEG4视频MPEG-4 视频格式.mp4UniformDataType.PLAIN_TEXT文本纯文本格式UniformDataType.JPEG图片JPEG 图片格式UniformDataType.PNG图片PNG 图片格式UniformDataType.MP3音频MP3 音频格式UniformDataType.PDF文档PDF 文档格式5.2 UTD 在分享中的作用在 systemShare 中每条分享记录都必须指定utd字段其作用包括应用匹配系统根据 UTD 类型筛选出能够处理该类型数据的目标应用。格式识别目标应用通过 UTD 了解收到的数据类型选择合适的处理方式。预览展示系统分享面板根据 UTD 决定如何展示预览内容视频缩略图、文本摘要等。5.3 项目中 UTD 的使用import{uniformTypeDescriptor}fromkit.ArkData;// 视频记录使用 MPEG4 类型constvideoRecord:ShareVideoRecord{utd:uniformTypeDescriptor.UniformDataType.MPEG4,// ...};// 文本记录使用 PLAIN_TEXT 类型consttextRecord:ShareTextRecord{utd:uniformTypeDescriptor.UniformDataType.PLAIN_TEXT,// ...};选择正确的 UTD 类型至关重要——如果视频记录错误地使用PLAIN_TEXT系统分享面板将无法正确识别文件格式目标应用也无法正常打开分享内容。六、完整分享流程从准备到展示6.1 视频准备分享的第一步是确保视频文件在本地可访问。prepareVideo方法处理了两种场景constpreparedawaitVideoExportService.prepareVideo(videoUri,title,rawFilePath);Resourcerawfile 资源通过resourceManager.getRawFileContent读取内置视频写入应用缓存目录。string本地路径校验路径有效性直接使用现有文件。具体细节已在第 2.9 篇中详细讲解此处不再赘述。6.2 数据构建buildSharedData方法接收四个参数参数类型说明videoUriResource | string视频文件资源或路径titlestring作品标题storystring作品故事描述rawFilePathstringrawfile 中的视频路径仅 Resource 类型需要方法内部依次完成准备视频 → 创建视频记录 → 实例化 SharedData → 添加文本记录。6.3 展示分享面板constcontextgetContext()ascommon.UIAbilityContext;constcontrollernewsystemShare.ShareController(data);constoptions:systemShare.ShareControllerOptions{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL};awaitcontroller.show(context,options);controller.show调用后系统会弹出分享面板用户完成选择或取消后Promise resolve。6.4 完整流程时序图VideoExportService.showSystemShare() │ ├── prepareVideo(videoUri, title, rawFilePath) │ ├── typeof videoUri string → 直接使用本地文件 │ └── typeof videoUri Resource → 读取 rawfile → 写入 cacheDir │ └── 返回 PreparedVideoFile { path, uri, fileName } │ ├── buildSharedData(videoUri, title, story, rawFilePath) │ ├── 调用 prepareVideo() 获取 prepared │ ├── 创建 ShareVideoRecord { utd: MPEG4, uri, title, description } │ ├── new SharedData(videoRecord) ← 主记录 │ ├── 创建 ShareTextRecord { utd: PLAIN_TEXT, content, title, description } │ └── data.addRecord(textRecord) ← 添加次要记录 │ ├── new ShareController(data) │ └── controller.show(context, { selectionMode: SINGLE, previewMode: DETAIL }) │ ├── 用户选择应用 → 分享成功 │ └── 用户取消 → 流程结束七、与 UI 层集成在 Index.ets 页面中分享功能通过shareCurrentVideo方法触发privateasyncshareCurrentVideo():Promisevoid{if(this.exportBusy){return;}this.exportBusytrue;this.showNotice(正在打开分享);try{awaitVideoExportService.showSystemShare(this.getCurrentVideo(),this.getCurrentWorkTitle(),this.getCurrentWorkStory(),this.getCurrentRawVideoPath());this.sharedActivetrue;this.showNotice(已打开分享面板);}catch(error){this.showNotice(分享失败this.getErrorMessage(errorasError));}finally{this.exportBusyfalse;}}设计要点1. 防重复操作锁exportBusy是一个State布尔变量用于防止用户在分享进行中重复点击if(this.exportBusy){return;// 正在分享中忽略重复请求}2. 用户反馈分享过程中通过showNotice显示状态提示文字“正在打开分享” → 用户操作触发后立即提示“已打开分享面板” → 分享面板成功弹出后提示“分享失败xxx” → 发生异常时提示错误原因3. try/catch/finally 资源清理try{// 执行分享}catch(error){// 异常处理}finally{this.exportBusyfalse;// 无论成功失败最终释放锁}这种模式确保exportBusy在任何情况下都能正确释放不会出现死锁状态。八、跨设备分享场景systemShare 的跨设备能力是其核心价值之一。当用户在同一华为账号下拥有多台设备时系统分享面板会自动发现并列出可用的跨设备目标。8.1 手机 → 平板场景孩子在手机上用画伴梦工厂制作了一段动画想在大屏平板上全屏观看。流程点击分享按钮 → 系统弹出分享面板分享面板自动显示同一华为账号下的平板设备选择平板 → 视频通过分布式软总线传输到平板平板上打开视频大屏观看体验更佳8.2 手机 → 智慧屏场景家庭聚会时孩子想把自己创作的动画展示在电视上。流程点击分享 → 分享面板显示智慧屏设备选择智慧屏 → 视频传输到电视电视播放动画全家一起观看8.3 手机 → 其他应用场景将视频分享到微信、钉钉等社交应用。流程点击分享 → 分享面板显示已安装的社交应用选择微信 → 系统将视频和文本描述一起发送到微信在微信中选择联系人发送8.4 跨设备分享的技术基础systemShare 的跨设备能力依赖于 HarmonyOS 的分布式软总线技术设备发现自动发现同一华为账号下的在线设备安全传输端到端加密保障数据传输安全类型适配目标设备根据 UTD 类型自动匹配处理方式无缝体验用户无需手动配对或配置九、systemShare vs. 其他分享方式9.1 与 DocumentViewPicker 的对比维度systemShareDocumentViewPicker核心功能分享到其他应用/设备保存到本地文件系统数据流向发送出去保存到本地跨设备✅ 天然支持❌ 仅本地保存数据类型视频、文本、图片等多类型主要是文件用户交互选择目标应用选择保存位置使用场景分享给好友、发送到其他设备备份到本地、导出到电脑9.2 与 startAbilityForResult 的对比startAbilityForResult也可以启动其他应用但它是定向启动——开发者必须预先知道目标应用的 Ability 信息。而systemShare是系统级分发——由用户自由选择目标开发者只需提供数据即可。// startAbilityForResult定向启动awaitcontext.startAbilityForResult({bundleName:com.example.target,abilityName:TargetAbility});// systemShare系统分发awaitcontroller.show(context,options);十、最佳实践与注意事项10.1 数据容量考虑分享数据不宜过大。大文件分享建议先压缩或提供下载链接。文本记录内容长度适中过长的描述可能在某些应用中显示不全。10.2 UTD 类型准确性务必为每条记录指定正确的 UTD 类型否则目标应用可能无法识别数据。常见的视频类型使用UniformDataType.MPEG4图片使用UniformDataType.JPEG或UniformDataType.PNG。10.3 上下文生命周期context必须是有效的UIAbilityContext不能使用已销毁的页面上下文。建议在调用分享前检查上下文状态避免分享面板弹出时页面已关闭。10.4 资源清理ShareController实例不使用时无需手动销毁系统会自动管理。缓存目录中的临时视频文件可以在适当时机清理避免占用过多存储空间。10.5 用户隐私分享内容中不应包含用户敏感信息。项目中的文本记录仅包含作品标题和故事不包含用户个人信息。十一、完整代码总览最终VideoExportService 中与分享相关的完整代码如下// 展示系统分享面板staticasyncshowSystemShare(videoUri:Resource|string,title:string,story:string,rawFilePath:string):Promisevoid{constcontextgetContext()ascommon.UIAbilityContext;constdataawaitVideoExportService.buildSharedData(videoUri,title,story,rawFilePath);constcontrollernewsystemShare.ShareController(data);constoptions:systemShare.ShareControllerOptions{selectionMode:systemShare.SelectionMode.SINGLE,previewMode:systemShare.SharePreviewMode.DETAIL};awaitcontroller.show(context,options);}// 构建分享数据staticasyncbuildSharedData(videoUri:Resource|string,title:string,story:string,rawFilePath:string):PromisesystemShare.SharedData{constpreparedawaitVideoExportService.prepareVideo(videoUri,title,rawFilePath);constvideoRecord:ShareVideoRecord{utd:uniformTypeDescriptor.UniformDataType.MPEG4,uri:prepared.uri,title:title,description:story};constdatanewsystemShare.SharedData(videoRecord);consttextRecord:ShareTextRecord{utd:uniformTypeDescriptor.UniformDataType.PLAIN_TEXT,content:title\nstory,title:title,description:story};data.addRecord(textRecord);returndata;}总结本文深入讲解了 HarmonyOS systemShare 在画伴梦工厂中的完整集成实践知识点说明ShareController分享控制器通过构造函数传入 SharedData调用 show 弹出分享面板ShareControllerOptions配置 selectionMode单选/多选和 previewMode详细/概览预览SharedData 多记录支持主记录 多条次要记录不同目标应用按需选择uniformTypeDescriptor统一类型描述标识数据格式影响应用匹配和预览展示分享流程prepareVideo → buildSharedData → new ShareController → show防重复操作exportBusy 状态锁 try/catch/finally 资源释放跨设备分享手机 → 平板/智慧屏/社交应用基于分布式软总线自动发现设备systemShare的精妙之处在于其一次集成、处处可用的设计理念——开发者只需构建数据、弹出面板系统负责应用的匹配、数据的传输、跨设备的协同。这种设计让应用能够以极低的成本获得强大的分享能力也是 HarmonyOS 全场景智慧体验的典型体现。参考源码本文所有代码均来自项目文件products/default/src/main/ets/services/VideoExportService.ets— 视频导出服务的完整实现包含 systemShare 分享、DocumentViewPicker 保存、文件操作等核心方法