给鸿蒙 App 增加社交分享能力 —— social_share 的鸿蒙使用指南
给鸿蒙 App 增加社交分享能力 —— social_share 的鸿蒙使用指南
本文配套仓库:https://atomgit.com/oh-flutter/social_share(TAG:
2.3.1-ohos-1.0.0-beta.1,分支:feat/ohos_social_share_2.3.1)。本文讲怎么用:引入依赖、调接口、跑通分享与渠道探测;适配是怎么一步步做出来的,见姊妹篇《social_share 的鸿蒙适配教程》。
一、最终运行效果
先看跑起来是什么样子。下面是示例工程的实测截图,主验证环境为 HUAWEI nova 12 Ultra 星耀版真机(ADE-AL10,HarmonyOS 6.1.0.135 / API 24),Flutter 3.41.10-ohos-1.0.1。
点击 Share Options 按钮,插件经 systemShare 拉起系统分享面板,蓝牙、邮件、短信等分享目标一应俱全,面板关闭后回调 true:

图一:shareOptions 拉起系统分享面板
点击 SMS 按钮,信息应用打开新会话,分享文案、链接与尾随文本已自动拼进正文:

图二:shareSms 拉起信息应用,正文已填
点击 Twitter 按钮,未安装 Twitter 应用的设备上浏览器打开分享页,文案与话题标签已拼好——装有应用时系统会直接路由到应用:

图三:shareTwitter 未装应用时浏览器打开分享页
点击 Copy to Clipboard 按钮后,文本进入剪贴板,在任意输入框长按即可粘贴:

图四:copyToClipboard 后文本可粘贴
接入成本如何?往下看。
二、social_share 是什么
social_share 是 pub.dev 上的一个轻量分享插件(作者 ShekarMudaliyar,MIT 协议),职责单一:把文本、图片或链接送进各社交渠道的分享界面。它不代替用户发送,发送动作始终由用户在拉起的界面里确认完成——这也是分享类插件的通用做法。
上游支持 Android 与 iOS,适配鸿蒙后新增 OpenHarmony / HarmonyOS 支持。插件共 10 个接口:shareOptions(系统分享面板)、copyToClipboard(剪贴板)、shareSms(短信)、shareTwitter(Twitter/X)、shareWhatsapp、shareTelegram(应用门禁分享)、shareInstagramStory、shareFacebookStory 与聚合入口 shareMetaStory(Story 分享)、checkInstalledAppsForShare(渠道探测)。
典型的使用场景:邀请好友、活动推广、内容分享、意见反馈引导——只要业务里出现"把一段内容分享出去",先探测可用渠道再逐级分发,这个插件就能覆盖。
三、环境准备
本文所有实测均在以下环境完成:
| 项 | 版本 | 说明 |
|---|---|---|
| Flutter(ohos 版) | 3.41.10-ohos-1.0.1 | 主验证环境 |
| 编译 SDK | 5.1.0(18) | example 宿主工程 compatibleSdkVersion |
| 设备 | HUAWEI nova 12 Ultra 星耀版(ADE-AL10) | HarmonyOS 6.1.0.135 / API 24 |
两点提醒:
- 编译鸿蒙目标需要使用 ohos 版 Flutter SDK,普通 Flutter SDK 无法编译 ohos 产物,环境搭建见文末官方指南;
- Whatsapp / Telegram 接口在设备装有对应应用且宿主声明了 querySchemes 时才能拉起(见 5.6 与 FAQ Q1);Instagram / Facebook Story 两个接口在鸿蒙上恒返回 ‘error’(见 5.7),业务侧注意按失败分支处理。
四、引入依赖
进入工程目录,在 pubspec.yaml 中添加 git 依赖:
dependencies:
social_share:
git:
url: https://atomgit.com/oh-flutter/social_share.git
# ref: 根据下方表格选择不同框架适配的 TAG 版本
ref: 2.3.1-ohos-1.0.0-beta.1
执行命令拉取依赖:
flutter pub get
TAG 命名规则:原库版本-ohos-版本号-beta.x。
| Flutter 框架版本 | TAG 名称 | 分支名 |
|---|---|---|
| 3.41 | 2.3.1-ohos-1.0.0-beta.1 | feat/ohos_social_share_2.3.1 |
该 TAG 已在 3.41.10-ohos-1.0.1 搭配 HUAWEI nova 12 Ultra 星耀版真机(HarmonyOS 6.1.0.135 / API 24)上实测通过。不同 TAG 之间的变更详见仓库中的 CHANGELOG.OpenHarmony.md。
依赖说明:social_share 是单包插件,鸿蒙实现随包自带,不需要额外引入 ohos 平台实现包。若业务里还用到 image_picker(Story 分享前选图的常见搭配)等 federated 插件,对应的 ohos 实现包(如 image_picker_ohos)需要直接写进 dependencies——federated 插件只有被 app 直接依赖才会被识别为 ohos 插件。
五、代码接入
5.1 导入库
import 'package:social_share/social_share.dart';
5.2 shareOptions:一键唤起系统分享面板
场景:不预设渠道,让系统面板列出设备上所有可选的分享目标,用户自选。
final bool? result = await SocialShare.shareOptions("看看这个好东西 https://example.com");
| 参数 | 类型 | 说明 |
|---|---|---|
| contentText | String | 分享文本,必填 |
| imagePath | String? | 本地图片路径,可选 |
返回值:Future<bool?>,true 表示面板拉起成功。上游 iOS 返回 bool、Android 无返回值,鸿蒙对齐 iOS 语义;跨平台代码统一用 if (result == true) 判断(null 也走 false 分支)。
5.3 copyToClipboard:把文本或图片放进剪贴板
场景:验证码快捷复制、口令复制、把生成的图片放进剪贴板供粘贴。
// 文本
await SocialShare.copyToClipboard(text: "This is Social Share plugin");
// 图片(传应用可读的本地路径)
await SocialShare.copyToClipboard(image: localImagePath);
| 参数 | 类型 | 说明 |
|---|---|---|
| text | String? | 要复制的文本 |
| image | String? | 要复制的图片本地路径 |
text 与 image 至少传一个。鸿蒙实现经 pasteboard 写入:文本直写,图片转 PixelMap 写入。粘贴验证:任意输入框长按粘贴,文本原样出现(见图四)。
5.4 shareSms:把内容带进短信编辑界面
场景:邀请好友、客服快捷入口等"带着预填内容进短信"的需求。
await SocialShare.shareSms(
"这款应用不错,试试:",
url: "https://example.com",
trailingText: "\n(来自 XXX 应用)",
);
| 参数 | 类型 | 说明 |
|---|---|---|
| message | String | 分享正文,必填 |
| url | String? | 链接,拼接在正文后 |
| trailingText | String? | 尾随文本,拼接在最后 |
返回值:Future<String?>。鸿蒙实现把三段内容按 message + url + trailingText 顺序拼成 sms:?body= URI,经 want 拉起信息应用新会话,正文就位、收件人栏为空——上游接口本就不带收件人参数,用户填号码发送。
5.5 shareTwitter:分享到 Twitter/X
await SocialShare.shareTwitter(
"This is Social Share twitter example with link. ",
hashtags: ["SocialSharePlugin", "world"],
url: "https://example.com/hello",
trailingText: "cool!!",
);
| 参数 | 类型 | 说明 |
|---|---|---|
| captionText | String | 分享文案,必填 |
| hashtags | List<String>? | 话题标签列表,自动补 # |
| url | String? | 链接 |
| trailingText | String? | 尾随文本 |
鸿蒙实现把文案、话题、链接与尾随文本拼成 twitter.com/intent/tweet 分享 URL 后经 openLink 打开:设备装有 Twitter 时系统路由到应用,未装时浏览器直接打开分享页,文案与话题已拼好(本文真机实测为后者,见图三)。
5.6 shareWhatsapp / shareTelegram:分享到 WhatsApp / Telegram
await SocialShare.shareWhatsapp("Hello World \n https://example.com");
await SocialShare.shareTelegram("Hello World \n https://example.com");
参数为分享文本(含链接时随文本传入),返回 Future<String?>。
鸿蒙实现带应用探测门禁:经 bundleManager.canOpenLink 探测 whatsapp://、tg:// scheme,探测通过则拉起对应应用并带入文本;未装应用直接回调 ‘error’,与上游 Android 在应用不存在时的语义一致。
使用这两个接口(以及 checkInstalledAppsForShare)前,宿主工程需在 entry/src/main/module.json5 的 module 节点里声明要探测的 scheme:
// entry/src/main/module.json5,module 节点内
"querySchemes": ["sms", "whatsapp", "tg", "instagram", "facebook", "twitter"]
没声明的 scheme 探测恒为 false——这是鸿蒙平台上使用本插件唯一的必配项,example 已按上述六项声明。
5.7 shareInstagramStory / shareFacebookStory:Story 分享(鸿蒙暂不支持)
接口签名与上游一致(appId 必填,图片、背景色、背景资源等可选):
await SocialShare.shareInstagramStory(
appId: facebookId,
imagePath: localImagePath,
backgroundTopColor: "#ffffff",
backgroundBottomColor: "#000000",
);
鸿蒙现状:两个 Story 接口(含聚合入口 shareMetaStory,按 platform 参数转发)恒返回 ‘error’——鸿蒙生态没有 Instagram/Facebook 的 Story 分享能力(iOS 走官方 SDK 的 Story API,Android 走其私有 intent),适配时如实保留接口签名,返回与上游"应用不可用"一致的错误语义。业务侧把返回值按失败分支处理,或在鸿蒙平台上隐藏这两个入口。
配套的选图不受影响:image_picker 在鸿蒙上配合 image_picker_ohos 可正常选图,只是选完之后分享这一步返回 ‘error’。
5.8 checkInstalledAppsForShare:探测可分享的目标
final Map? apps = await SocialShare.checkInstalledAppsForShare();
print(apps.toString());
// {sms: true, whatsapp: false, telegram: false, instagram: false, facebook: false, twitter: false}
返回六项布尔 Map:sms 恒为 true(短信是系统能力,shareSms 链路总能用);其余五项按 canOpenLink 探测结果,同时取决于 querySchemes 声明与设备安装情况。分享菜单的入口显隐、渠道降级判断都建议以它为先导。
5.9 跨平台一套代码
各接口在鸿蒙上的行为与返回值一览(上游 Android / iOS 行为以原库文档为准):
| 接口 | 鸿蒙行为 | 返回值 |
|---|---|---|
| shareOptions | 拉起系统分享面板 | bool?,true 为拉起成功(对齐 iOS) |
| copyToClipboard | 经 pasteboard 写入剪贴板 | String? |
| shareSms | 拉 sms:?body= want 进信息应用 | String? |
| shareTwitter | openLink 拉起应用或浏览器分享页 | String? |
| shareWhatsapp / shareTelegram | canOpenLink 门禁后拉起应用 | String?,未装返回 ‘error’ |
| shareInstagramStory / shareFacebookStory | 恒返回 ‘error’(生态暂无) | String? |
| checkInstalledAppsForShare | canOpenLink 六项探测 | Map?,sms 恒 true |
调用侧零分支:除两个 Story 接口在鸿蒙上恒为 ‘error’ 需要按结果兜底外,同一段代码在 Android、iOS、鸿蒙上各自生效,成功/失败语义各端对齐。
5.10 实战:给应用加一个"分享有礼"入口
把前面的内容拼起来,做一个真实的业务场景:设置页里的"推荐给好友"按钮,先探测可用渠道决定分发路径,渠道逐级降级,全部不可用时落到系统分享面板兜底:
import 'package:flutter/material.dart';
import 'package:social_share/social_share.dart';
class ShareService {
static const String inviteLink = 'https://example.com/invite?code=8f3a';
static const String shareText = '发现一个好用的应用,一起来试试:';
// 探测可用渠道,决定分享菜单里哪些入口点亮
static Future<Map<String, bool>> detectChannels() async {
final Map? apps = await SocialShare.checkInstalledAppsForShare();
return {
'whatsapp': apps?['whatsapp'] == true,
'telegram': apps?['telegram'] == true,
'sms': apps?['sms'] == true,
};
}
static Future<void> shareToFriend(BuildContext context) async {
final Map<String, bool> channels = await detectChannels();
final String content = '$shareText \n $inviteLink';
if (channels['whatsapp'] == true) {
await SocialShare.shareWhatsapp(content);
} else if (channels['telegram'] == true) {
await SocialShare.shareTelegram(content);
} else if (channels['sms'] == true) {
await SocialShare.shareSms(shareText, url: inviteLink);
} else {
// 渠道都不可用时降级到系统分享面板(邮件、备忘录等仍可分享)
final bool? ok = await SocialShare.shareOptions(content);
if (ok != true && context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('分享面板未拉起,请重试')),
);
}
}
}
}
在按钮的 onPressed 里调用 ShareService.shareToFriend(context) 即可。探测先行、逐级降级,这段代码在 Android、iOS、鸿蒙上行为一致:装了什么渠道就走什么渠道,都不满足就落到系统分享面板。
六、运行与验证
以下为 example 工程的实测记录。仓库中 example 的 Bundle Name 为 com.shekarmudaliyar.social_share_example,自建工程验证时替换为你自己的包名即可。
| 设备项 | 值 |
|---|---|
| 设备 | HUAWEI nova 12 Ultra 星耀版(ADE-AL10)真机 |
| 系统版本 | HarmonyOS 6.1.0.135 |
| API 版本 | 24 |
构建、安装并启动(在 example 目录执行;签名可用 deveco-cli 在命令行完成,步骤见姊妹篇适配教程 3.1):
cd example
flutter pub get
flutter build hap --debug
# 安装并启动
hdc install build/ohos/hap/entry-default-signed.hap
hdc shell aa start -b com.shekarmudaliyar.social_share_example -a EntryAbility
6.1 验证一:系统分享面板与剪贴板
点击 Share Options 按钮,预期系统分享面板弹出,面板关闭后日志输出 true(图一)。点击 Copy to Clipboard 按钮后到任意输入框长按粘贴,文本原样出现(图四)。
6.2 验证二:短信与 Twitter
点击 SMS 按钮,预期信息应用新会话的正文按 message + url + trailingText 拼好、收件人栏为空(图二)。点击 Twitter 按钮,未装 Twitter 的设备上预期浏览器打开分享页,文案与话题已拼好(图三)。
6.3 验证三:渠道探测与门禁
点击 Get all Apps 按钮,预期日志输出六项探测 Map 且 sms 恒为 true(见 5.8 的输出示例)。点击 Whatsapp / Telegram 按钮,未装应用的设备上预期回调 ‘error’ 且无跳转;装有对应应用时改为拉起应用。
七、工作原理
整个调用链路如下(以 shareOptions 为例):
Dart: SocialShare.shareOptions(contentText)
→ MethodChannel('social_share') / 'shareOptions'
→ ArkTS: SocialSharePlugin.onMethodCall
→ systemShare.ShareController 组装并弹出系统分享面板
→ 面板关闭后回传结果,经 replyOnce 回复 Dart
ArkTS 侧按方法分发到四类系统能力:
| 方法 | 系统能力 | 说明 |
|---|---|---|
| shareOptions | systemShare.ShareController | 组装系统分享面板并弹出 |
| copyToClipboard | pasteboard | 文本直写,图片经 PixelMap 写入 |
| shareSms | want(ohos.want.action.viewData) | 拼 sms:?body= URI 拉起信息应用 |
| shareTwitter / shareWhatsapp / shareTelegram | bundleManager.canOpenLink + openLink | 探测 scheme 后拉起应用或浏览器分享页 |
| shareInstagramStory / shareFacebookStory | — | 直接回调 ‘error’(生态暂无对应能力) |
| checkInstalledAppsForShare | bundleManager.canOpenLink | 六项 scheme 探测后汇总返回 |
所有回复路径统一经 replyOnce 互斥包裹——MethodResult 只允许回复一次,而系统回调可能沿异步与同步两条路径先后到达:
let replied: boolean = false;
const reply = (value: string | boolean | object): void => {
if (!replied) { replied = true; result.success(value); }
};
一个值得了解的平台差异:Android 的 PackageManager 与 iOS 的 canOpenURL 可以直接探测任意应用,鸿蒙的 bundleManager.canOpenLink 只探测宿主在 module.json5 里 querySchemes 声明过的 scheme——这就是 5.6 那段配置存在的原因,也是渠道探测类需求迁移到鸿蒙时最容易漏掉的一步。
八、常见问题
Q1:真机上明明装了 WhatsApp,shareWhatsapp 还是返回 ‘error’?
先检查宿主 entry/src/main/module.json5 是否声明了 "querySchemes": [..., "whatsapp", ...]——未声明的 scheme 探测恒为 false,即使应用已安装。修改 module.json5 后需要重新构建安装才能生效。Telegram 同理检查 tg。
Q2:checkInstalledAppsForShare 除 sms 外全是 false,是插件坏了吗?
不是。两个可能:querySchemes 未声明(见 Q1),或设备确实没装这些应用。sms 恒为 true 是基线——短信是系统能力,不受声明与安装情况影响;拿它对照即可区分是配置问题还是设备问题。
Q3:Instagram / Facebook Story 选图之后返回 ‘error’,是选图失败了吗?
不是。图库选择器属于选图链路,正常拉起;选图完成后分享这一步在鸿蒙上恒返回 ‘error’(见 5.7),这是如实记录的平台差异,不是故障。业务侧按失败分支处理或隐藏入口。
Q4:shareOptions 返回值和其他接口不一样,怎么统一处理?
shareOptions 在鸿蒙上返回 bool(对齐上游 iOS 语义),其余接口返回字符串。跨平台代码里 shareOptions 用 if (result == true) 判断,null 也会走 false 分支;字符串返回值用 == 'error' 识别失败。
Q5:构建或安装报错怎么排查?
编译需使用 ohos 版 Flutter SDK;安装报"此应用暂不支持在当前设备安装"通常是宿主工程 compatibleSdkVersion 高于设备 API(注意版本号带括号的旧格式,如 5.1.0(18));hap 装不上先检查签名配置与 bundleName 是否匹配。这些环境类问题的定位过程见姊妹篇《social_share 的鸿蒙适配教程》第四章。
九、结语
回顾一下:在 pubspec.yaml 中以 git TAG 引入 social_share,SocialShare.shareOptions() 一行即可唤起系统分享面板;shareSms、shareTwitter 打通短信与浏览器分享链路,shareWhatsapp、shareTelegram 带应用门禁直达目标应用,copyToClipboard 与 checkInstalledAppsForShare 覆盖剪贴板与渠道探测;返回值语义与上游对齐,除两个 Story 接口外同一段代码各端生效。插件已在 HUAWEI nova 12 Ultra 星耀版真机(HarmonyOS 6.1.0.135 / API 24)完整实测,10 个接口全覆盖。
使用中发现任何问题,欢迎到配套仓库提 Issue,也欢迎发 PR 共建。
相关链接
欢迎加入 CPF-Flutter 鸿蒙社区,社区入口、环境搭建指南和本文相关链接统一放在这里:
更多推荐



所有评论(0)