可可图片编辑 HarmonyOS(3)分享图片
可可图片编辑 HarmonyOS(3)应用间分享图片
前言
可可图标编辑也实现了图片的分享功能,演示效果如下。
Share Kit(分享服务) 介绍
hare Kit(分享服务)为应用提供文本、图片、视频等内容跨应用、跨端分享能力。
应用把需要分享的内容和预览样式配置给Share Kit,Share Kit将根据不同的场景进行使用:
- 针对应用间分享的场景,根据分享的数据类型、数量等信息构建分享面板,为用户提供内容预览、推荐分享联系人、关联应用及操作界面,便于用户快速选择分享应用或操作,将内容分发到目标应用。
- 针对跨端分享的场景,根据分享的数据类型、数量等信息构建预览界面,用于跨端分享。
分类
Share Kit 可以分为 systemShare 和 HarmonyShare ,两者区别主要是:
- systemShare 用于应用之间的分享
- HarmonyShare 用于设备之间的分享
在实际开发中,两者可能配合使用:
跨端分享:通过 HarmonyShare 发起碰一碰传输,接收端通过 HarmonyShare 的沙箱监听处理数据。
应用内分享:通过 systemShare 构造分享内容,用户选择目标应用后跳转到对应页面。
systemShare 使用步骤
1. 选择图片
- 配置图片选择参数
- 创建
PhotoSelectOptions
对象,设置MIMEType
为IMAGE_TYPE
限制只能选择图片类型文件 - 通过
maxSelectNumber = 5
限制最大可选择数量,符合鸿蒙系统图片选择器的多选能力
- 创建
- 创建图片选择器实例
- 使用
PhotoViewPicker
类(鸿蒙媒体访问框架)创建选择器实例,体现鸿蒙API的分层设计
- 使用
- 调用异步选择方法
- 通过
select()
方法触发系统图片选择界面,采用Promise异步处理机制:- 成功回调:提取返回结果中的
photoUris
数组,取首元素赋值给组件状态变量fileUri
,并打印完整URI列表 - 异常处理:捕获
BusinessError
异常,输出包含错误码和消息的日志,符合ArkTS错误处理规范
- 成功回调:提取返回结果中的
- 通过
Button(\"选择图片\") .onClick(() => { // 1 设置选择图片的参数 const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE。 photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目。 let uris: Array<string> = []; // 2 创建图片选择器 const photoViewPicker = new photoAccessHelper.PhotoViewPicker(); // 3 开始选择图片 photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { uris = photoSelectResult.photoUris; this.fileUri = uris[0] console.info(\'photoViewPicker.select to file succeed and uris are:\' + uris); }).catch((err: BusinessError) => { console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`); }) })
2. 拷贝到沙箱
- 获取沙箱路径
- 通过
getUIContext().getHostContext()
获取 UIAbility 上下文 - 使用
cacheDir
属性获取应用专属缓存目录(框架提供的安全存储路径)
- 通过
- 生成唯一文件名
- 通过
split(\'.\').pop()
解析原始文件的扩展名(ArkTS 的字符串操作特性) - 使用
Date.now()
生成时间戳作为文件名前缀,确保文件名唯一性
- 通过
- 执行文件拷贝
- 使用
fs.openSync
以只读模式打开源文件(ArkTS 文件系统 API) - 调用
fs.copyFileSync
执行文件描述符到目标路径的同步拷贝操作
- 使用
- 状态反馈
- 成功时通过
AlertDialog
显示操作结果(ArkUI 的声明式 UI 组件) - 失败时捕获异常并显示错误提示(try-catch 异常处理机制)
- 成功时通过
- 数据绑定更新
- 将生成的缓存路径
copyFilePath
赋值给this.cacheUri
,用于后续数据绑定或状态管理(响应式编程特性)
- 将生成的缓存路径
Button(\"复制到沙箱\").onClick(async () => { try { const context = this.getUIContext().getHostContext() as common.UIAbilityContext; const cacheDir = context.cacheDir; const fileType = this.fileUri.split(\'.\').pop() // 后缀名 // 生成一个新的文件名 const fileName = Date.now() + \'.\' + fileType // 通过缓存路径+文件名 拼接出完整的路径 const copyFilePath = cacheDir + \'/\' + fileName // 将文件 拷贝到 临时目录 const file = fs.openSync(this.fileUri, fs.OpenMode.READ_ONLY) fs.copyFileSync(file.fd, copyFilePath) AlertDialog.show({ message: JSON.stringify(\'写入到沙箱\', null, 2) }) this.cacheUri = copyFilePath } catch (e) { AlertDialog.show({ message: JSON.stringify(\'写入失败\', null, 2) }) }})
3. 分享
-
获取UI上下文
- 通过
this.getUIContext()
获取当前UI组件的上下文对象 - 使用
getHostContext()
获取UIAbility上下文,用于后续调用系统分享能力
- 通过
-
确定统一数据类型(UTD)
- 通过文件后缀名(jpg/png/webp)匹配对应的UTD类型ID
- 使用
utd.getUniformDataTypeByFilenameExtension
API获取标准数据类型标识
-
构建分享数据对象
创建
systemShare.SharedData
实例,包含:- utd:统一数据类型标识
- title/description:分享时显示的元数据
- uri:通过
fileUri.getUriFromPath
转换沙箱路径为可访问URI
-
初始化分享控制器
创建
systemShare.ShareController
实例,绑定分享数据 -
显示系统分享界面
调用
controller.show()
步方法,传入:- SelectionMode.SINGLE:单选模式
- SharePreviewMode.DETAIL:详细预览模式
Button(\"分享\").onClick(async () => { try { // 获取UI上下文 const uiContext: UIContext = this.getUIContext(); const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; // 根据图片格式确定UTD类型 let utdTypeId: string; switch (this.fileUri.split(\'.\').pop()) { case \'jpeg\': case \'jpg\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.jpg\', utd.UniformDataType.IMAGE); break; case \'png\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.png\', utd.UniformDataType.IMAGE); break; case \'webp\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.webp\', utd.UniformDataType.IMAGE); break; default: utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.jpg\', utd.UniformDataType.IMAGE); } // 创建分享数据,使用沙箱中的图片URI const shareData: systemShare.SharedData = new systemShare.SharedData({ utd: utdTypeId, title: \'Picture Title\', description: \'Picture Description\', uri: fileUri.getUriFromPath(this.cacheUri), }); // 创建分享控制器 const controller: systemShare.ShareController = new systemShare.ShareController(shareData); // 显示分享界面 await controller.show(context, { selectionMode: systemShare.SelectionMode.SINGLE, previewMode: systemShare.SharePreviewMode.DETAIL }); console.log(\'图片分享成功\'); } catch (e) { console.log(\'图片分享失败\'); }})
总结
本文介绍了在鸿蒙应用中实现图片分享功能的完整流程。通过 Share Kit 的 systemShare 服务,开发者可以轻松实现应用间的图片分享。核心实现包括三个步骤:
- 图片选择:使用
PhotoViewPicker
调用系统图片选择器,支持多选并限制文件类型 - 沙箱拷贝:将选中图片拷贝到应用缓存目录,确保分享时的文件访问权限
- 分享操作:通过
ShareController
构建分享数据,调用系统分享面板完成跨应用分享
整个流程充分利用了鸿蒙系统的媒体访问框架、文件系统 API 和分享服务,为用户提供了原生、流畅的图片分享体验。
案例完整代码
import { photoAccessHelper } from \'@kit.MediaLibraryKit\';import { BusinessError } from \'@kit.BasicServicesKit\';import { fileUri, fileIo as fs } from \'@kit.CoreFileKit\';import { common } from \'@kit.AbilityKit\';import { uniformTypeDescriptor as utd } from \'@kit.ArkData\';import { systemShare } from \'@kit.ShareKit\';@ComponentV2@Entrystruct Index { fileUri: string = \"\" cacheUri: string = \"\" build() { Column({ space: 10 }) { Button(\"选择图片\") .onClick(() => { // 1 设置选择图片的参数 const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions(); photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE。 photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目。 let uris: Array<string> = []; // 2 创建图片选择器 const photoViewPicker = new photoAccessHelper.PhotoViewPicker(); // 3 开始选择图片 photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => { uris = photoSelectResult.photoUris; this.fileUri = uris[0] console.info(\'photoViewPicker.select to file succeed and uris are:\' + uris); }).catch((err: BusinessError) => { console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`); }) }) Button(\"复制到沙箱\") .onClick(async () => { try { const context = this.getUIContext().getHostContext() as common.UIAbilityContext; const cacheDir = context.cacheDir; const fileType = this.fileUri.split(\'.\').pop() // 后缀名 // 生成一个新的文件名 const fileName = Date.now() + \'.\' + fileType // 通过缓存路径+文件名 拼接出完整的路径 const copyFilePath = cacheDir + \'/\' + fileName // 将文件 拷贝到 临时目录 const file = fs.openSync(this.fileUri, fs.OpenMode.READ_ONLY) fs.copyFileSync(file.fd, copyFilePath) AlertDialog.show({ message: JSON.stringify(\'写入到沙箱\', null, 2) }) this.cacheUri = copyFilePath } catch (e) { AlertDialog.show({ message: JSON.stringify(\'写入失败\', null, 2) }) } }) Button(\"分享\") .onClick(async () => { try { // 获取UI上下文 const uiContext: UIContext = this.getUIContext(); const context: common.UIAbilityContext = uiContext.getHostContext() as common.UIAbilityContext; // 根据图片格式确定UTD类型 let utdTypeId: string; switch (this.fileUri.split(\'.\').pop()) { case \'jpeg\': case \'jpg\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.jpg\', utd.UniformDataType.IMAGE); break; case \'png\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.png\', utd.UniformDataType.IMAGE); break; case \'webp\': utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.webp\', utd.UniformDataType.IMAGE); break; default: utdTypeId = utd.getUniformDataTypeByFilenameExtension(\'.jpg\', utd.UniformDataType.IMAGE); } // 创建分享数据,使用沙箱中的图片URI const shareData: systemShare.SharedData = new systemShare.SharedData({ utd: utdTypeId, title: \'Picture Title\', description: \'Picture Description\', uri: fileUri.getUriFromPath(this.cacheUri), }); // 创建分享控制器 const controller: systemShare.ShareController = new systemShare.ShareController(shareData); // 显示分享界面 await controller.show(context, { selectionMode: systemShare.SelectionMode.SINGLE, previewMode: systemShare.SharePreviewMode.DETAIL }); console.log(\'图片分享成功\'); } catch (e) { console.log(\'图片分享失败\'); } }) } .width(\"100%\") .height(\"100%\") .justifyContent(FlexAlign.Center) }}
以往文章
- 可可图片编辑 HarmonyOS 上架应用分享
- 可可图片编辑 HarmonyOS(2) 选择图片和保存到图库
- 懂你的HarmonyOS知识库更新了,已经来到10970个文档了
- AI编程神器!Trae+Claude4.0 简单配置 让 HarmonyOS 开发效率飙升
近期活动
最近想要想要考取 HarmonyOS 基础或者高级证书,或者快要获取的同学都可以点击这个链接,加入我的班级,考取成功有机会获得鸿蒙礼盒一份。
联系我
可以加我微信,带你了解更多HarmonyOS相关的资讯。
.qq.com/s/AsieJTX8RkixgaKyDrzddg)
近期活动
最近想要想要考取 HarmonyOS 基础或者高级证书,或者快要获取的同学都可以点击这个链接,加入我的班级,考取成功有机会获得鸿蒙礼盒一份。
[外链图片转存中…(img-qnXCyWJ1-1756689232084)]
联系我
可以加我微信,带你了解更多HarmonyOS相关的资讯。