从指令魔方 APP 出发,分享鸿蒙 Share Kit 的进阶实战
但在实际开发中,不同应用对分享功能的需求差异显著:有的需要自定义分享面板样式,有的需要限制分享目标范围(如企业内部应用),还有的需要统计分享渠道数据。本文将聚焦 Share Kit 的进阶能力,结合全接/半接接入模式、操作区自定义、企业级权限控制等场景,带大家实现更灵活、更贴合业务需求的分享功能。在实际开发中,建议结合应用的核心场景(如普通工具类应用用全接模式,企业应用用名单限制),灵活组合 Sh
大家好,我是陈杨,8 年前端老兵转型鸿蒙开发,也是一名鸿蒙极客。从前端到鸿蒙,我靠的是 “三天上手 ArkTS” 的技术嗅觉,以及 “居安思危” 的转型魄力。这三年,我不玩虚的,封装了开源组件库「莓创图表」,拿过创新赛大奖,更带着团队上架了 11 款自研 APP,涵盖工具、效率、创意等多个领域。想体验我的作品?欢迎搜索体验:指令魔方、JLPT、REFLEX PRO、国潮纸刻、Wss 直连、ZenithDocs Pro、圣诞相册、CSS 特效。
在上一篇文章中,我们掌握了 Share Kit 的基础用法和跨端分享核心场景。但在实际开发中,不同应用对分享功能的需求差异显著:有的需要自定义分享面板样式,有的需要限制分享目标范围(如企业内部应用),还有的需要统计分享渠道数据。本文将聚焦 Share Kit 的进阶能力,结合全接/半接接入模式、操作区自定义、企业级权限控制等场景,带大家实现更灵活、更贴合业务需求的分享功能。
一、宿主应用接入模式:全接 vs 半接
Share Kit 提供两种接入模式,分别适配不同开发诉求,我们可根据业务场景选择:
1.1 两种接入模式对比
| 接入模式 | 核心特点 | 适用场景 | 开发成本 |
|---|---|---|---|
| 全接模式 | 直接使用系统默认分享面板,无需自定义 UI | 华为自研应用、对分享面板无商业诉求的普通应用(如工具类 App) | 低(无需开发面板,调用接口即可) |
| 半接模式 | 我们自定义分享面板,同时保留系统分享入口 | 有商业推广需求(如优先展示自家应用)、需要独特业务逻辑(如分享前添加水印)的应用 | 中(需开发自定义面板,集成系统分享入口) |
1.2 全接模式实战(快速接入)
全接模式是最常用的接入方式,直接复用系统分享面板,适合快速实现分享功能。以下是多类型内容(文本+图片)分享的完整示例:
核心代码实现
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { common, BusinessError } from '@kit.AbilityKit';
import { fileUri } from '@kit.CoreFileKit';
import promptAction from '@ohos.promptAction';
// 全接模式:分享文本+图片组合内容
async function fullAccessShare() {
try {
// 1. 获取应用沙箱路径(用于图片存储)
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
const imagePath = `${context.cacheDir}/combined_image.png`; // 假设图片已保存到沙箱
// 2. 构造分享数据(支持多记录组合)
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT, // 文本类型
content: '这是一条组合分享内容',
title: '组合分享示例'
});
// 3. 添加图片分享记录(多内容分享)
shareData.addRecord({
utd: utd.UniformDataType.PNG, // 图片类型
uri: fileUri.getUriFromPath(imagePath), // 图片 URI
thumbnailUri: fileUri.getUriFromPath(imagePath) // 缩略图
});
// 4. 构建分享控制器并显示系统面板
const controller = new systemShare.ShareController(shareData);
// 注册面板关闭监听
controller.on('dismiss', () => {
console.info('系统分享面板已关闭');
});
// 显示分享面板(默认样式)
await controller.show(context, {
previewMode: systemShare.SharePreviewMode.DETAIL, // 详细预览模式
selectionMode: systemShare.SelectionMode.SINGLE // 单选模式
});
} catch (error) {
const err = error as BusinessError;
console.error(`全接模式分享失败:Code=${err.code}, Message=${err.message}`);
promptAction.showToast({ message: '分享失败,请重试' });
}
}
关键说明
- 多内容分享:通过
addRecord()方法可添加多个不同类型的分享内容(如文本+图片、多图片),系统面板会自动适配预览样式。 - 预览模式:
SharePreviewMode.DETAIL会显示完整的内容预览(如图片大图+文本全文),DEFAULT则显示简化预览。
1.3 半接模式实战(自定义面板+系统入口)
半接模式允许我们自定义分享面板,同时提供系统分享入口,兼顾业务个性化和生态兼容性。核心要求:系统分享入口的图标和文本必须使用系统资源,不可自定义。
步骤 1:自定义分享面板 UI(ArkUI)
import { Button, Column, Text, SymbolGlyph, Flex } from '@kit.ArkUI';
import { systemShare } from '@kit.ShareKit';
@Component
struct CustomSharePanel {
// 自定义分享回调(如分享到自家应用)
private onCustomShare(type: string) {
console.info(`分享到${type}`);
// 自定义分享逻辑(如跳转到自家应用的分享页面)
}
// 打开系统分享面板
private openSystemShare() {
// 此处调用系统分享接口(同全接模式的核心逻辑)
this.fullAccessShare();
}
build() {
Column({ space: 15 }) {
// 自定义分享选项
Button('分享到我的应用')
.width('100%')
.height(45)
.onClick(() => this.onCustomShare('我的应用'));
Button('分享到朋友圈')
.width('100%')
.height(45)
.onClick(() => this.onCustomShare('朋友圈'));
// 系统分享入口(必须使用系统图标和文本)
Button(
Flex({ alignItems: 'center', justifyContent: 'center', space: 8 }) {
// 系统分享图标(不可自定义)
SymbolGlyph($r('sys.symbol.share'))
.width(20)
.height(20);
// 系统分享文本(不可自定义)
Text('系统分享')
.fontSize(16);
}
)
.width('100%')
.height(45)
.backgroundColor('#F5F5F5')
.onClick(() => this.openSystemShare());
}
.padding(20)
.width(300)
}
// 此处引入全接模式的 fullAccessShare 方法
}
步骤 2:在页面中弹出自定义面板
@Component
struct HomePage {
@State isSharePanelShow: boolean = false;
build() {
Column({ space: 20 }) {
Button('打开自定义分享面板')
.width(250)
.height(45)
.onClick(() => {
this.isSharePanelShow = true;
});
// 自定义分享面板(模态弹窗)
if (this.isSharePanelShow) {
ModalDialog({
confirm: () => this.isSharePanelShow = false,
cancel: () => this.isSharePanelShow = false,
showCancel: false
}) {
CustomSharePanel();
}
.width('80%')
.height('auto');
}
}
.padding(20)
.width('100%')
.justifyContent('center');
}
}
关键规范
- 系统分享入口必须使用
$r('sys.symbol.share')图标和“系统分享”文本,否则会影响应用上架审核。 - 自定义面板需保证操作流程简洁,避免过度复杂的业务逻辑(如分享前强制观看广告),影响用户体验。
二、分享面板个性化配置
Share Kit 支持对分享面板的预览模式、操作区、显示位置等进行精细化配置,满足不同设备和业务场景的需求。
2.1 配置 2in1 设备分享面板位置
2in1 设备(如折叠屏、平板)支持通过 anchor 参数配置分享面板的显示位置,适配大屏操作习惯:
// 2in1 设备分享面板位置配置
function configure2in1SharePosition() {
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
// 构造分享数据(文本类型)
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT,
content: '2in1 设备分享示例'
});
const controller = new systemShare.ShareController(shareData);
// 方式一:关联控件 ID(面板显示在指定控件下方)
controller.show(context, {
anchor: 'shareButton', // 与 UI 中 button 的 id 对应
previewMode: systemShare.SharePreviewMode.DEFAULT
});
// 方式二:指定坐标(绝对位置显示)
// controller.show(context, {
// anchor: {
// windowOffset: { x: 200, y: 300 }, // 相对于屏幕左上角的偏移量
// size: { width: 0, height: 0 } // 组件大小(可选,用于计算对齐方式)
// },
// previewMode: systemShare.SharePreviewMode.DEFAULT
// });
}
2.2 自定义操作区(隐藏不需要的系统功能)
系统操作区默认提供复制、保存、打印、添加到中转站等功能,宿主应用可通过 excludedAbilities 参数隐藏不需要的操作:
// 自定义操作区:隐藏打印功能
function customizeShareOperations() {
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
// 构造图片分享数据
const imagePath = `${context.cacheDir}/example.jpg`;
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.IMAGE,
uri: fileUri.getUriFromPath(imagePath),
title: '自定义操作区示例'
});
const controller = new systemShare.ShareController(shareData);
// 注册面板关闭监听
controller.on('dismiss', () => {
console.info('分享面板关闭,清理临时资源');
});
// 显示面板并隐藏打印功能
controller.show(context, {
previewMode: systemShare.SharePreviewMode.DETAIL,
selectionMode: systemShare.SelectionMode.SINGLE,
excludedAbilities: [systemShare.ShareAbilityType.PRINT] // 隐藏打印操作
});
}
支持隐藏的系统操作类型
| 操作类型 | 说明 |
|---|---|
PRINT |
打印功能 |
COPY |
复制功能 |
SAVE |
保存功能 |
SAVE_AS |
另存为功能 |
ADD_TO_TRANSIT_STATION |
添加到中转站功能 |
2.3 获取分享结果(统计分享渠道)
我们可通过 shareCompleted 事件监听用户的分享行为,获取分享目标渠道信息,用于数据统计(如哪种分享渠道使用率最高):
// 获取分享结果,统计分享渠道
function getShareResult() {
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.PLAIN_TEXT,
content: '分享结果统计示例'
});
const controller = new systemShare.ShareController(shareData);
// 注册分享结果监听
controller.on('shareCompleted', (result: systemShare.ShareOperationResult) => {
const targetName = result.targetAbilityInfo.name;
console.info(`用户分享到:${targetName}`);
// 统计逻辑:如上传到后台服务器
// reportShareChannel(targetName);
// 渠道名称规则:
// 1. 系统操作(如复制):固定名称(参考 ShareAbilityName)
// 2. 第三方应用:格式为 "[bundleName]#[moduleName]#[abilityName]"
});
controller.show(context, {
previewMode: systemShare.SharePreviewMode.DEFAULT
});
}
渠道名称解析示例
- 系统操作“复制”:
ohos.system.share.ability.copy - 微信分享:
com.tencent.mm#module_main#WeChatShareAbility
三、企业级功能:限制分享目标应用名单
对于企业应用,往往需要限制内部数据只能分享到企业信任的应用(如集团内部 App),避免数据泄露。Share Kit 提供了目标应用名单配置功能,仅对企业应用开放。
3.1 前置条件
- 权限申请:需要申请受限权限
ohos.permission.SET_SYSTEMSHARE_APPLAUNCHTRUSTLIST,申请时需说明企业信息和管控场景(如“用于 XX 集团内部资料仅分享给集团应用”)。 - 应用类型:仅企业应用支持该功能,普通我们应用无法使用。
3.2 完整实现步骤
步骤 1:在 module.json5 中声明权限
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.SET_SYSTEMSHARE_APPLAUNCHTRUSTLIST",
"reason": "$string:permission_reason", // 权限申请理由(需填写企业管控场景)
"usedScene": {
"ability": ["com.example.enterprise.ShareAbility"],
"when": "always"
}
}
]
}
}
步骤 2:配置目标应用名单
通过 appLaunchTrustInfo 参数指定允许分享的应用 AppIdentifier(可在华为我们联盟后台查询应用的 AppIdentifier):
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';
@Component
export struct EnterpriseSharePage {
build() {
Button('企业内部分享')
.onClick(() => this.enterpriseRestrictedShare());
}
private enterpriseRestrictedShare() {
// 1. 构造分享数据(企业内部文档)
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.DOCUMENT,
uri: 'file:///data/storage/el2/base/cache/enterprise_doc.pdf',
title: '企业内部文档'
});
// 2. 获取上下文
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
// 3. 构建控制器并配置信任应用名单
const controller = new systemShare.ShareController(shareData);
controller.show(context, {
previewMode: systemShare.SharePreviewMode.DEFAULT,
selectionMode: systemShare.SelectionMode.SINGLE,
// 目标应用 AppIdentifier 列表(最多支持 50 个)
appLaunchTrustInfo: [
'5765880207853060000', // 企业应用 A 的 AppIdentifier
'1171817433862770000' // 企业应用 B 的 AppIdentifier
]
});
}
}
关键说明
- AppIdentifier 是应用的唯一标识,需从华为我们联盟后台“应用信息”中查询,不可随意填写。
- 配置后,系统分享面板仅显示名单内的应用,其他应用不会出现在推荐区和分享方式区。
- 该功能仅限制分享目标,不影响分享数据的传输安全性,企业需额外确保数据本身的加密(如文档加密)。
四、多场景分享示例:App Linking 直达应用
除了文本、图片等基础类型,Share Kit 还支持分享 App Linking 链接,用户点击后可直达应用指定页面(如商品详情页),提升转化效率。
4.1 核心原理
- App Linking 是 HarmonyOS 提供的深度链接服务,支持跨应用跳转。
- 分享 App Linking 时,目标设备接收后会自动打开对应的应用(如未安装则拉起应用市场)。
4.2 完整代码实现
import { systemShare } from '@kit.ShareKit';
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { common } from '@kit.AbilityKit';
// 分享 App Linking 直达应用页面
function shareAppLinking() {
const uiContext = this.getUIContext();
const context = uiContext.getHostContext() as common.UIAbilityContext;
// 1. 构造 App Linking 分享数据(需先通过 App Linking 服务生成链接)
const appLinking = 'https://applinking.huawei.com/abc123?page=productDetail&id=10086';
const shareData = new systemShare.SharedData({
utd: utd.UniformDataType.APP_LINKING, // App Linking 类型
content: appLinking,
title: '点击查看商品详情',
description: '直达华为商城商品页面'
});
const controller = new systemShare.ShareController(shareData);
// 2. 显示分享面板
controller.show(context, {
previewMode: systemShare.SharePreviewMode.DEFAULT,
selectionMode: systemShare.SelectionMode.SINGLE
});
// 3. 监听分享结果
controller.on('shareCompleted', (result) => {
console.info(`App Linking 分享到:${result.targetAbilityInfo.name}`);
});
}
接收端处理逻辑
目标设备接收后,会按照以下规则处理:
- 若已安装对应应用:直接打开应用并跳转到
page=productDetail&id=10086对应的页面。 - 若未安装应用:拉起华为应用市场,展示该应用的下载页面(需在 App Linking 配置中关联应用)。
- 若为 PC/2in1 设备:通过浏览器打开链接(如应用支持 PC 端,可跳转至 PC 应用)。
五、常见问题与进阶技巧
5.1 常见问题排查
| 问题场景 | 可能原因 | 解决方案 |
|---|---|---|
| 企业应用无法配置目标应用名单 | 1. 未申请受限权限 2. 权限申请理由未说明企业管控场景 | 1. 在 module.json5 中声明权限 2. 重新提交权限申请,详细描述企业名称、管控场景(如“内部资料防泄露”) |
| 2in1 设备分享面板位置异常 | anchor 参数配置错误(如控件 ID 不存在、坐标超出屏幕范围) |
1. 确保 anchor 对应的控件 ID 在 UI 中存在 2. 坐标值需根据设备屏幕尺寸动态计算(避免硬编码) |
| 分享 App Linking 无法跳转应用 | 1. App Linking 未正确关联应用 2. 目标设备未安装应用且未配置应用市场跳转 | 1. 在华为我们联盟后台配置 App Linking 与应用的关联关系 2. 检查 App Linking 生成时的跳转规则配置 |
5.2 进阶技巧
- 分享数据加密:对于敏感数据(如企业文档),分享前可通过 AES 加密,目标应用接收后解密,提升数据安全性。
- 多语言适配:分享面板的标题、描述需支持多语言,可通过
$string:资源引用实现(如title: $r('app.string.share_title'))。 - 性能优化:分享多张大图时,先压缩图片(建议单张图片小于 5MB),避免分享数据超过 200KB 限制。
- 兼容性处理:通过
deviceInfo模块判断设备类型(如 TV、平板),针对性调整分享面板配置(如 TV 设备仅支持分享到周边设备)。
六、总结
本文聚焦 Share Kit 的进阶能力,覆盖了接入模式选择、面板个性化配置、企业级权限控制、App Linking 分享等核心场景,关键要点总结如下:
- 接入模式:全接模式快速实现,半接模式支持自定义,根据业务诉求选择。
- 个性化配置:支持隐藏系统操作、配置面板位置、获取分享结果,适配不同设备和业务需求。
- 企业级功能:通过受限权限配置目标应用名单,保障内部数据安全(仅企业应用支持)。
- 场景扩展:App Linking 分享支持直达应用页面,提升用户转化效率。
Share Kit 的核心优势在于“统一接口+灵活扩展”,我们无需关注跨应用、跨设备的底层通信细节,只需通过简单配置即可实现复杂的分享功能。如需进一步深入,可参考华为我们文档的 Share Kit 进阶指南,探索更多高级特性(如自定义分享预览样式、多设备协同分享)。
通过本文的实战案例,相信大家已能应对大多数业务场景的分享需求。在实际开发中,建议结合应用的核心场景(如普通工具类应用用全接模式,企业应用用名单限制),灵活组合 Share Kit 的各项能力,打造更优质的用户体验。
更多推荐



所有评论(0)