前言
ShareKit是 HarmonyOS 的分享服务能力,支持应用间分享文本、图片、文件等数据。在「猫猫大作战」中,玩家完成一局游戏后可以分享战绩到微信、微博等社交平台,吸引更多朋友来挑战。
本文以「猫猫大作战」的战绩分享功能为锚点,讲解 systemShare 的完整使用方法,包括文本分享、图片分享、UniformDataObject 数据封装、以及分享后的回调处理。
提示:本系列不讲 ArkTS 基础语法与环境搭建。本篇是阶段五第 154 篇。
一、systemShare 基础用法
1.1 分享文本
import{systemShare}from'@kit.ShareKit';import{uniformDataStruct}from'@kit.ArkData';asyncfunctionshareText(score:number,playerName:string):Promise<void>{constsharedData:uniformDataStruct.UniformDataObject={value:{text:`我在「猫猫大作战」中获得了${score}分!快来挑战我吧!🐱`,html:`<h3>猫猫大作战</h3><p>得分: <b>${score}</b></p><p>玩家:${playerName}</p>`,},type:'general.text',};awaitsystemShare.share(sharedData);}1.2 参数说明
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
value.text | string | 纯文本内容 | “我在猫猫大作战中获得了 2450 分!” |
value.html | string | HTML 富文本(可选) | <b>2450</b> 分 |
type | string | 统一类型标识符 (UTD) | 'general.text'、'general.image' |
提示:
type字段是 UTD(Uniform Type Descriptor),告诉系统分享数据的类型。常用类型:general.text(文本)、general.image(图片)、general.file(文件)。
二、 UniformDataObject 数据封装
2.1 数据封装方法
import{uniformDataStruct}from'@kit.ArkData';// 文本分享consttextData:uniformDataStruct.UniformDataObject={value:{text:'分享内容',html:'<b>富文本</b>'},type:'general.text',};// 图片分享constimageData:uniformDataStruct.UniformDataObject={value:{image:pixelMap},type:'general.image',};// 文件分享constfileData:uniformDataStruct.UniformDataObject={value:{fileUri:'file://{sandboxPath}/score.png'},type:'general.file',};2.2 数据类型的 UTD 对照
| 分享类型 | UTD 标识 | value 格式 | 目标应用 |
|---|---|---|---|
| 纯文本 | general.text | { text: string } | 微信、短信 |
| 富文本 | general.text | { text, html } | 微信、QQ |
| 图片 | general.image | { image: PixelMap } | 微博、朋友圈 |
| 文件 | general.file | { fileUri: string } | 文件管理器 |
| 链接 | general.url | { url: string } | 浏览器 |
三、游戏中分享战绩的完整实现
3.1 战绩分享按钮
// 游戏结束界面的分享按钮@BuilderShareButton(score:number,playerName:string){Button({icon:$r('app.media.ic_share'),text:'分享战绩'}).width('80%').height(48).fontSize(17).fontColor('#FFFFFF').backgroundColor('#45B7D1').borderRadius(24).onClick(async()=>{try{awaitshareGameResult(score,playerName);promptAction.showToast({message:'分享成功!'});}catch(err){console.error(`分享失败:${err.message}`);promptAction.showToast({message:'分享取消或失败'});}})}3.2 构造分享内容
asyncfunctionshareGameResult(score:number,playerName:string):Promise<void>{// 构造分享文本constscoreText=score.toLocaleString('zh-CN');constshareContent=formatShareText(score,playerName);constsharedData:uniformDataStruct.UniformDataObject={value:{text:shareContent.text,html:shareContent.html,},type:'general.text',};awaitsystemShare.share(sharedData);}functionformatShareText(score:number,playerName:string){constscoreText=score.toLocaleString('zh-CN');return{text:`🐱 我在「猫猫大作战」中获得${scoreText}分!来挑战我的记录吧!下载地址: https://appgallery.huawei.com/cat-battle-war`,html:`<div style="text-align:center;padding:20px;"> <h2>🐱 猫猫大作战</h2> <p style="font-size:24px;color:#E74C3C;"> <b>${scoreText}</b> 分 </p> <p>玩家:${playerName}</p> <p style="font-size:14px;color:#95A5A6;"> 来挑战我的记录吧! </p> </div>`,};}3.3 分享回调处理
// systemShare.share() 返回的 Promise// resolve = 用户选择了分享目标// reject = 用户取消或分享失败try{constresult=awaitsystemShare.share(sharedData);// 分享成功(用户选择了目标应用)console.info('分享成功',JSON.stringify(result));// 可以在这里触发分享成功统计analytics.recordEvent('share_success',{score});}catch(err){// 用户取消或在目标应用分享失败console.info(`分享取消:${err.message}`);// 不视为错误,只记录取消analytics.recordEvent('share_cancel');}四、分享图片(截图)
4.1 截取游戏画面
import{image}from'@kit.ImageKit';asyncfunctioncaptureAndShare():Promise<void>{// 1. 获取当前 UI 的 PixelMap(截图)constuiContext=this.getUIContext();constpixelMap=awaituiContext.createPixelMap({width:360,height:640,});// 2. 编码为 JPEGconstpacker=image.createImagePacker();constbuffer=awaitpacker.packing(pixelMap,{format:'image/jpeg',quality:85,});packer.release();// 3. 保存到临时文件constcontext=getContext()ascommon.UIAbilityContext;consttempPath=`${context.tempDir}/share_score.jpg`;constfile=fileIo.openSync(tempPath,fileIo.OpenMode.CREATE|fileIo.OpenMode.WRITE_ONLY|fileIo.OpenMode.TRUNC);fileIo.writeSync(file.fd,buffer);fileIo.closeSync(file);// 4. 分享图片文件constsharedData:uniformDataStruct.UniformDataObject={value:{fileUri:`file://${tempPath}`},type:'general.file',};awaitsystemShare.share(sharedData);}4.2 图片规��
| 图片类型 | 建议尺寸 | 格式 | 质量 | 文件大小 |
|---|---|---|---|---|
| 战绩分享截图 | 360×640 | JPEG | 85% | ~100KB |
| 邀请横幅 | 720×360 | PNG | - | ~200KB |
| 角色卡片 | 240×240 | PNG | - | ~50KB |
提示:分享图片文件大小建议不超过 1MB。过大的图片在社交平台加载慢,可能被压缩。
五、文件分享(战绩数据导出)
asyncfunctionshareGameData(playerName:string,records:GameRecord[]):Promise<void>{// 1. 序列化战绩数据为 JSONconstdata=JSON.stringify({playerName,exportDate:newDate().toISOString(),records,},null,2);// 2. 写入临时文件constcontext=getContext()ascommon.UIAbilityContext;constfilePath=`${context.tempDir}/game_data_${Date.now()}.json`;constfile=fileIo.openSync(filePath,fileIo.OpenMode.CREATE|fileIo.OpenMode.WRITE_ONLY|fileIo.OpenMode.TRUNC);fileIo.writeSync(file.fd,data);fileIo.closeSync(file);// 3. 分享文件constsharedData:uniformDataStruct.UniformDataObject={value:{fileUri:`file://${filePath}`},type:'general.file',};awaitsystemShare.share(sharedData);}六、ShareKit vs 原生分享方案
| 维度 | systemShare | 原生 systemShare | 自定义分享面板 |
|---|---|---|---|
| 集成复杂度 | 简单(3 行代码) | 中等 | 复杂 |
| 目标应用 | 系统所有支持的应用 | 系统所有 | 手动指定 |
| UI 一致性 | 系统原生界面 | 系统原生 | 需自定义 |
| 支持数据类型 | 文本/图片/文件 | 文本/URI | 任意 |
| 推荐场景 | 通用分享 | 通用分享 | 品牌定制分享 |
七、分享最佳实践
7.1 分享内容策略
- 引人注目的开头:用 Emoji 🐱🏆 吸引注意
- 具体数字:得分要精确(2450 分 比"很高分"更吸引人)
- 行动号召:“来挑战我吧!” 引导好友下载
- 下载链接:附带应用市场下载地址
- 个性化:包含玩家名称,让好友知道是谁在邀请
7.2 性能考虑
// ✅ 分享操作应在用户点击后异步执行,避免阻塞 UIButton('分享').onClick(async()=>{// show loadingthis.isSharing=true;try{awaitshareGameResult(this.score,this.playerName);}finally{this.isSharing=false;}})// ✅ 大图片分享前压缩asyncfunctioncompressForShare(pixelMap:PixelMap):Promise<ArrayBuffer>{constpacker=image.createImagePacker();constbuffer=awaitpacker.packing(pixelMap,{format:'image/jpeg',quality:75,// 适当降低质量减小文件});packer.release();returnbuffer;}八、错误排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 分享界面未弹出 | 数据格式错误 | 检查 UniformDataObject 结构 |
| 分享后无响应 | UTD 类型不匹配 | 确保 type 与实际 value 匹配 |
| 图片分享失败 | 文件路径不存在 | 检查 file:// 路径和文件权限 |
| 内容为空 | value.text 未设 | 确保 text 字段有内容 |
九、权限与合规
// 分享不需要额外权限// 但如果要分享图片,需要读取临时文件的权限// 临时文件在 tempDir 中,应用自有权限可直接读写// 隐私提示:分享内容中包含玩家名称,需在隐私政策中说明constsharePrivacyNotice=`分享功能会包含您的游戏昵称和得分信息。 这些信息仅用于本次分享,不会被我们收集。`;十、多语言分享
functionformatShareByLocale(score:number,locale:string){constscoreText=score.toLocaleString(locale==='zh'?'zh-CN':'en-US');consttemplates:Record<string,{text:string;html:string}>={'zh':{text:`🐱 我在「猫猫大作战」中获得${scoreText}分!`,html:`<b>${scoreText}</b> 分`,},'en':{text:`🐱 I scored${scoreText}in Cat Battle!`,html:`Score: <b>${scoreText}</b>`,},};returntemplates[locale]??templates['en'];}总结
ShareKit 通过systemShare.share()提供系统级分享能力,支持文本、图片、文件三种数据格式。核心要点:UniformDataObject 封装数据、 type 字段标识数据类型、 文本分享附带 HTML 增强展示、 图片先压缩再分享、 分享取消非异常、 包含下载链接传播应用。
下一篇将深入 systemShare——SharedData 与 UTD 类型详解。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- ShareKit 官方文档
- systemShare API 参考
- UniformDataObject 类型定义
- UTD 统一类型描述
- ImageKit 图片编码
- 文件分享最佳实践
- 开源鸿蒙跨平台社区
- HarmonyOS 开发者官方文档
- 第 153 篇:PushKit 推送
- 第 155 篇:SharedData