给鸿蒙 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主验证环境
编译 SDK5.1.0(18)example 宿主工程 compatibleSdkVersion
设备HUAWEI nova 12 Ultra 星耀版(ADE-AL10)HarmonyOS 6.1.0.135 / API 24

两点提醒:

  1. 编译鸿蒙目标需要使用 ohos 版 Flutter SDK,普通 Flutter SDK 无法编译 ohos 产物,环境搭建见文末官方指南;
  2. 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.412.3.1-ohos-1.0.0-beta.1feat/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");
参数类型说明
contentTextString分享文本,必填
imagePathString?本地图片路径,可选

返回值: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);
参数类型说明
textString?要复制的文本
imageString?要复制的图片本地路径

text 与 image 至少传一个。鸿蒙实现经 pasteboard 写入:文本直写,图片转 PixelMap 写入。粘贴验证:任意输入框长按粘贴,文本原样出现(见图四)。

5.4 shareSms:把内容带进短信编辑界面

场景:邀请好友、客服快捷入口等"带着预填内容进短信"的需求。

await SocialShare.shareSms(
  "这款应用不错,试试:",
  url: "https://example.com",
  trailingText: "\n(来自 XXX 应用)",
);
参数类型说明
messageString分享正文,必填
urlString?链接,拼接在正文后
trailingTextString?尾随文本,拼接在最后

返回值: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!!",
);
参数类型说明
captionTextString分享文案,必填
hashtagsList<String>?话题标签列表,自动补 #
urlString?链接
trailingTextString?尾随文本

鸿蒙实现把文案、话题、链接与尾随文本拼成 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?
shareSmssms:?body= want 进信息应用String?
shareTwitteropenLink 拉起应用或浏览器分享页String?
shareWhatsapp / shareTelegramcanOpenLink 门禁后拉起应用String?,未装返回 ‘error’
shareInstagramStory / shareFacebookStory恒返回 ‘error’(生态暂无)String?
checkInstalledAppsForSharecanOpenLink 六项探测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 侧按方法分发到四类系统能力:

方法系统能力说明
shareOptionssystemShare.ShareController组装系统分享面板并弹出
copyToClipboardpasteboard文本直写,图片经 PixelMap 写入
shareSmswant(ohos.want.action.viewData)sms:?body= URI 拉起信息应用
shareTwitter / shareWhatsapp / shareTelegrambundleManager.canOpenLink + openLink探测 scheme 后拉起应用或浏览器分享页
shareInstagramStory / shareFacebookStory直接回调 ‘error’(生态暂无对应能力)
checkInstalledAppsForSharebundleManager.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 鸿蒙社区,社区入口、环境搭建指南和本文相关链接统一放在这里:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐