鸿蒙 Share Kit 目标应用开发指南
鸿蒙 Share Kit 目标应用开发指南。涵盖 UIAbility 与 ShareExtensionAbility 两种接入方式的对比与配置,包括 module.json5 能力声明、数据接收处理逻辑、分享详情页实现及联系人推荐功能。同时提供设计规范建议与常见问题排查方案,帮助开发者完成跨应用分享链路的接收端接入。

鸿蒙 Share Kit 目标应用开发指南。涵盖 UIAbility 与 ShareExtensionAbility 两种接入方式的对比与配置,包括 module.json5 能力声明、数据接收处理逻辑、分享详情页实现及联系人推荐功能。同时提供设计规范建议与常见问题排查方案,帮助开发者完成跨应用分享链路的接收端接入。

目标应用接收分享数据主要有两种方式,分别适配不同的用户体验场景,我们需根据业务需求选择:
| 接入方式 | 核心特点 | 适用场景 | 跳转体验 |
|---|---|---|---|
| UIAbility 接入 | 通过独立的 UIAbility 接收数据,打开完整应用页面 | 需对分享内容进行复杂处理(如编辑、保存到特定目录)的应用(如相册、文档编辑器) | 跳转至应用独立页面,处理完成后需手动返回 |
| ShareExtensionAbility 接入 | 基于 UIExtensionAbility,提供嵌入式分享详情页 | 快速完成分享操作(如发送给好友、发布动态)的应用(如社交、短视频 App) | 弹窗式嵌入分享面板,操作后可直接关闭或返回面板 |
无论哪种接入方式,目标应用都需在 module.json5 中注册分享能力,让系统识别支持的分享类型。核心配置规则:
actions 必须设为 ohos.want.action.sendData(系统分享的标准动作)。uris 需穷举支持的 UTD 类型(如文本、图片),并指定单次可接收的最大文件数。icon 和 label 配置,将显示在分享面板的'分享方式区'。UIAbility 是 HarmonyOS 应用的基础页面容器,适合需要完整页面交互的分享场景(如将图片保存到相册、编辑分享的文本)。
{
"module": {
"abilities": [
{
"name": "ShareReceiveUIAbility",
"srcEntry": "./ets/abilities/ShareReceiveUIAbility.ets",
"exported": true,
"icon": "$media:share_receive_icon",
"label": "$string:share_receive_label",
"skills": [
{
"actions": ["ohos.want.action.sendData"],
"uris": [
{ "scheme": "file", "utd": "general.text", "maxFileSupported": 1 },
{ "scheme": "file", "utd": "general.image", "maxFileSupported": 9 }
]
}
]
}
]
}
}
在 UIAbility 中通过 systemShare.getSharedData() 解析分享数据,并判断应用是否被系统分享拉起:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import { systemShare } from '@kit.ShareKit';
import { BusinessError } from '@kit.BasicServicesKit';
import promptAction from '@ohos.promptAction';
export default class ShareReceiveUIAbility extends UIAbility {
private sharedData: systemShare.SharedData | null = null;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
if (launchParam.launchReasonMessage === 'ReasonMessage_SystemShare') {
console.info('应用被系统分享拉起,开始处理分享数据');
this.parseSharedData(want);
} else {
console.info('应用正常启动,无分享数据');
}
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
if (launchParam.launchReasonMessage === 'ReasonMessage_SystemShare') {
console.info('应用已启动,接收新的分享数据');
this.parseSharedData(want);
}
}
private parseSharedData(want: Want) {
systemShare.getSharedData(want).then((data: systemShare.SharedData) => {
this.sharedData = data;
const records = data.getRecords();
records.forEach((record, index) => {
console.info(`第${index + 1}条分享数据:UTD=${record.utd}, URI=${record.uri}`);
});
this.loadShareHandlePage();
}).catch((error: BusinessError) => {
console.error(`解析分享数据失败:Code=${error.code}`);
promptAction.showToast({ message: '接收分享失败' });
this.terminateSelf();
});
}
private loadShareHandlePage() {
this.onWindowStageCreate = (windowStage: window.WindowStage) => {
windowStage.loadContent('pages/ShareHandlePage', (error) => {
if (error.code) {
console.error(`页面加载失败:${error.message}`);
this.terminateSelf();
return;
}
const pageRouter = windowStage.getMainWindow().getUIContext().router;
pageRouter.pushUrl({ url: 'pages/ShareHandlePage', params: { sharedData: this.sharedData } });
});
};
}
}
创建 ShareHandlePage.ets,提供图片预览、保存等交互功能:
import { Image, Button, Column, Text, ScrollView } from '@kit.ArkUI';
import { systemShare } from '@kit.ShareKit';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import promptAction from '@ohos.promptAction';
@Component
struct ShareHandlePage {
@State sharedData: systemShare.SharedData | null = null;
private context = getContext(this) as common.UIAbilityContext;
build() {
Column({ space: 20 }) {
Text('收到分享内容').fontSize(20).fontWeight(FontWeight.Bold);
if (!this.sharedData) {
Text('暂无有效分享数据').color('#666');
return;
}
ScrollView({ scrollDirection: Axis.Vertical }) {
Column({ space: 15 }) {
this.sharedData.getRecords().forEach((record) => {
if (record.utd.includes('image')) {
Image(record.uri).width(300).height(200).objectFit(ImageFit.Contain);
} else if (record.utd.includes('text')) {
Text(`文本内容:${record.content}`).width('100%').padding(10).backgroundColor('#F5F5F5');
}
});
}.height(300).width('100%');
}
Button('保存到本地').width(200).height(45).backgroundColor('#007AFF').onClick(() => this.saveSharedData());
}.padding(20).width('100%').justifyContent('center');
}
private async saveSharedData() {
if (!this.sharedData) return;
try {
const records = this.sharedData.getRecords();
for (const record of records) {
if (record.utd.includes('image')) {
const filePath = record.uri.replace('file://', '');
const file = fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY);
const fileData = fileIo.readSync(file.fd);
fileIo.closeSync(file);
const saveDir = `${this.context.filesDir}/share_received`;
if (!fileIo.accessSync(saveDir)) fileIo.mkdirSync(saveDir, { recursive: true });
const savePath = `${saveDir}/${Date.now()}.jpg`;
const saveFile = fileIo.openSync(savePath, fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.CREATE);
fileIo.writeSync(saveFile.fd, fileData);
fileIo.closeSync(saveFile);
}
}
promptAction.showToast({ message: '保存成功' });
this.context.terminateSelf();
} catch (error) {
console.error(`保存失败:${(error as Error).message}`);
promptAction.showToast({ message: '保存失败' });
}
}
}
onNewWant 方法:当应用已在后台运行,再次被系统分享拉起时,不会触发 onCreate,而是触发 onNewWant,需在此方法中重新解析分享数据。general.image 可支持所有图片类型(如 PNG、JPEG),无需逐个声明;若需精准限制类型,可指定 general.png、general.jpeg。ohos.permission.WRITE_MEDIA 权限,沙箱内保存无需额外权限。ShareExtensionAbility 是专门用于处理分享的扩展能力,提供嵌入式弹窗界面(分享详情页),用户无需离开分享面板即可完成操作,体验更流畅,适合社交类应用(如发送给好友、发布动态)。
{
"module": {
"extensionAbilities": [
{
"name": "ShareExtensionAbility",
"srcEntry": "./ets/abilities/ShareExtensionAbility.ets",
"type": "share",
"exported": true,
"icon": "$media:share_ext_icon",
"label": "$string:share_ext_label",
"skills": [
{
"actions": ["ohos.want.action.sendData"],
"uris": [
{ "scheme": "file", "utd": "general.text", "maxFileSupported": 1 },
{ "scheme": "file", "utd": "general.image", "maxFileSupported": 3 }
]
}
]
}
]
}
}
import { ShareExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit';
import { systemShare } from '@kit.ShareKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class ShareExtensionAbility extends ShareExtensionAbility {
private session: UIExtensionContentSession | null = null;
private sharedData: systemShare.SharedData | null = null;
private contactInfo: systemShare.ContactInfo | null = null;
onSessionCreate(want: Want, session: UIExtensionContentSession) {
this.session = session;
if (this.launchParam.launchReasonMessage === 'ReasonMessage_SystemShare') {
this.parseShareData(want);
} else {
this.closePanelWithError('非系统分享拉起');
}
}
private async parseShareData(want: Want) {
try {
const [data, contact] = await Promise.all([
systemShare.getSharedData(want),
systemShare.getContactInfo(want).catch(() => null)
]);
this.sharedData = data;
this.contactInfo = contact;
this.session?.loadContent('pages/ShareExtensionPage', { sharedData: data, contactInfo: contact });
} catch (error) {
const err = error as BusinessError;
console.error(`解析分享数据失败:Code=${err.code}`);
this.closePanelWithError('接收分享数据失败');
}
}
private closePanelWithError(message: string) {
promptAction.showToast({ message });
this.session?.terminateSelfWithResult({ resultCode: systemShare.ShareAbilityResultCode.ERROR });
}
public closePanel(resultCode: systemShare.ShareAbilityResultCode) {
this.session?.terminateSelfWithResult({ resultCode });
}
}
创建 ShareExtensionPage.ets,提供快速发送、选择联系人等功能:
import { Column, Text, Button, Image, Flex, List, ListItem } from '@kit.ArkUI';
import { systemShare } from '@kit.ShareKit';
import promptAction from '@ohos.promptAction';
const mockContacts = [
{ id: '1', name: '小明', avatar: '$media:avatar1' },
{ id: '2', name: '小红', avatar: '$media:avatar2' },
{ id: '3', name: '小刚', avatar: '$media:avatar3' }
];
@Component
struct ShareExtensionPage {
@Link sharedData: systemShare.SharedData;
@Link contactInfo: systemShare.ContactInfo | null;
private extension = getContext(this) as unknown as ShareExtensionAbility;
build() {
Column({ space: 15 }) {
Flex({ justifyContent: 'space-between', alignItems: 'center' }) {
Text('发送给好友').fontSize(18).fontWeight(FontWeight.Bold);
Button('取消').textStyle({ fontSize: 14, color: '#666' }).backgroundColor('transparent').onClick(() => {
this.extension.closePanel(systemShare.ShareAbilityResultCode.BACK);
});
}.width('100%');
Column({ space: 8 }) {
Text('分享内容:').fontSize(14).color('#666');
if (this.sharedData.getRecords()[0].utd.includes('image')) {
Image(this.sharedData.getRecords()[0].uri).width(80).height(80).objectFit(ImageFit.Contain);
} else {
Text(this.sharedData.getRecords()[0].content as string).width('100%').padding(8).backgroundColor('#F5F5F5').fontSize(14);
}
}.width('100%');
Text('选择联系人:').fontSize(14).color('#666').alignSelf('flex-start');
List() {
ForEach(mockContacts, (contact) => {
ListItem() {
Flex({ space: 12, alignItems: 'center' }) {
Image(contact.avatar).width(40).height(40).borderRadius(20);
Text(contact.name).fontSize(16);
}.padding(12).width('100%').onClick(() => this.sendToContact(contact));
};
});
}.height(200).width('100%');
Button('立即发送').width('100%').height(45).backgroundColor('#007AFF').onClick(() => {
if (this.contactInfo) {
this.sendToContact({ id: this.contactInfo.contactId, name: this.contactInfo.name });
} else {
promptAction.showToast({ message: '请选择联系人' });
}
});
}.padding(15).width('100%');
}
private sendToContact(contact: { id: string; name: string }) {
try {
console.info(`发送分享内容给 ${contact.name},联系人 ID:${contact.id}`);
promptAction.showToast({ message: `发送给 ${contact.name} 成功` });
this.extension.closePanel(systemShare.ShareAbilityResultCode.CLOSE);
} catch (error) {
console.error(`发送失败:${(error as Error).message}`);
promptAction.showToast({ message: '发送失败' });
this.extension.closePanel(systemShare.ShareAbilityResultCode.ERROR);
}
}
}
通过 terminateSelfWithResult 方法设置 resultCode,可控制分享面板的后续行为:
| ResultCode | 效果 | 适用场景 |
|---|---|---|
BACK | 正常返回分享面板 | 用户取消操作,需保留原分享面板 |
CLOSE | 直接关闭分享面板 | 分享成功,无需返回面板 |
ERROR | 返回面板并显示错误提示 | 分享失败(如网络异常),需告知用户 |
社交类应用可通过意图框架(Intents Kit)将用户常用联系人共享到系统分享面板的'推荐区',用户无需在应用内二次选择,可一步完成分享,大幅提升操作效率。
import { util } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { insightIntent } from '@kit.IntentsKit';
import { common } from '@kit.AbilityKit';
import BuildProfile from 'BuildProfile';
async function shareContactsToRecommendArea() {
try {
const uiContext = getContext(this) as common.UIContext;
const context = uiContext.getHostContext() as common.Context;
const contacts = [
{ contactId: 'user_1001', name: '小明', avatarBase64: 'data:image/png;base64,...', phone: '13800138000' },
{ contactId: 'user_1002', name: '小红', avatarBase64: 'data:image/png;base64,...', phone: '13900139000' }
];
const intents = contacts.map(contact => ({
intentName: 'SendMessage',
intentVersion: '1.0',
identifier: util.generateRandomUUID(),
intentActionInfo: { actionMode: 'EXECUTED', executedTimeSlots: { executedStartTime: new Date().getTime(), executedEndTime: new Date().getTime() } },
intentEntityInfo: {
entityId: contact.contactId,
entityName: 'Contact',
name: contact.name,
icon: contact.avatarBase64,
phoneNumbers: [contact.phone],
extras: {
shareParams: {
bundleName: BuildProfile.BUNDLE_NAME,
moduleName: 'entry',
abilityName: 'ShareExtensionAbility',
action: 'ohos.want.action.sendData'
}
}
}
}));
await insightIntent.shareIntent(context, intents);
console.info('联系人共享到分享推荐区成功');
} catch (error) {
const err = error as BusinessError;
console.error(`联系人共享失败:Code=${err.code}`);
}
}
@Component
struct HomePage {
onPageShow() {
this.shareContactsToRecommendArea();
}
build() {
// 应用首页 UI
}
}
shareIntent,确保推荐区的联系人信息最新。为保证用户在不同应用间的分享体验一致,华为对目标应用的图标、名称等有明确设计规范,违反规范可能导致应用上架被拒。
| 配置项 | 规范要求 | 示例 |
|---|---|---|
应用图标(icon) | 1. 格式:PNG 或 SVG; 2. 尺寸:建议 48x48px; 3. 风格:与系统图标风格一致(圆角、扁平化)。 | 使用系统图标库或符合 HarmonyOS 设计语言的自定义图标 |
应用名称(label) | 1. 长度:不超过 8 个汉字或 16 个英文字符; 2. 语义:明确表达分享功能。 | 正确:'发送到微信''保存到图库';错误:'分享''打开' |
| 多 Ability 配置 | 若应用有多个处理分享的 Ability,需为每个 Ability 配置独立的 icon 和 label。 | '保存到相册'(图库图标)和'发送给好友'(社交图标) |
{
"module": {
"abilities": [
{
"name": "SaveToGalleryAbility",
"label": "$string:save_to_gallery",
"icon": "$media:gallery_icon"
}
],
"extensionAbilities": [
{
"name": "SendToFriendAbility",
"label": "$string:send_to_friend",
"icon": "$media:friend_icon"
}
]
}
}
| 问题场景 | 可能原因 | 解决方案 |
|---|---|---|
| 目标应用未出现在分享面板 | 1. module.json5 中 actions 未设为 ohos.want.action.sendData; 2. UTD 类型配置错误; 3. exported 未设为 true。 | 1. 检查 actions 配置; 2. 确认 UTD 类型与分享内容一致; 3. 设 exported: true。 |
| 解析分享数据时提示'权限不足' | 1. 分享数据 URI 路径不可访问; 2. 目标应用缺少文件读取权限。 | 1. 宿主应用需将分享文件保存到沙箱; 2. 目标应用添加 ohos.permission.READ_USER_STORAGE 权限。 |
| 联系人未显示在分享推荐区 | 1. 未申请意图框架白名单; 2. 联系人数据格式错误; 3. 未获取用户隐私授权。 | 1. 完成白名单申请; 2. 检查 intentName 为 SendMessage; 3. 添加联系人授权弹窗。 |
| 分享详情页无法关闭 | 未调用 terminateSelfWithResult 方法,或 session 实例为 null。 | 确保在操作完成后调用 session?.terminateSelfWithResult,并在 onSessionCreate 中保存 session 实例。 |
本文聚焦目标应用的全流程接入,从两种核心接入方式(UIAbility/ShareExtensionAbility),到联系人推荐、设计规范,覆盖了分享链路的'接收端'关键能力。关键要点总结如下:
module.json5 中 actions 必须为 ohos.want.action.sendData,UTD 类型需精准匹配业务需求。至此,我们已完成 HarmonyOS Share Kit 从'发起分享'到'接收处理'的全链路讲解。无论是宿主应用的定制化分享,还是目标应用的高效接入,Share Kit 都提供了灵活且统一的接口,帮助我们快速构建跨应用、跨设备的分享体验。如需进一步深入,可参考华为官方文档的 目标应用接入示例工程,探索更多复杂场景(如多文件批量处理、自定义分享预览样式)的实现。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online