跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
TypeScript大前端

鸿蒙 Share Kit 碰一碰分享功能开发指南

介绍 HarmonyOS Share Kit 的碰一碰分享能力,涵盖手机间及手机与 PC/2in1 协同场景。内容包含环境要求、核心业务流程、事件注册、数据构造、预览图优化、App Linking 与 Deep Linking 选择、安全策略及异常处理。通过代码示例详解如何注册监听、发送共享数据、沙箱接收及组队邀请开发,帮助开发者实现跨设备一碰即传体验。

战神发布于 2026/2/8更新于 2026/7/2849 浏览

HarmonyOS 的 Share Kit 推出的'碰一碰分享'能力,通过'设备轻触'这一直观交互,将跨端分享简化为'一碰即传',支持图片、文件、Wi-Fi、组队邀请等多场景。本文将结合官方开发文档,从手机间分享、手机与 PC/2in1 协同两大场景,详解开发流程、核心代码与避坑要点。

一、碰一碰分享核心基础:环境与核心概念

在开始开发前,需先明确功能依赖的环境要求与核心逻辑,避免因版本不兼容导致功能失效。

1.1 环境要求(必看!)

不同设备间的碰一碰分享,对系统版本和开发工具的要求不同,具体如下:

分享场景设备系统要求集成开发环境
手机与手机双端均为 HarmonyOS NEXT Release 及以上(推荐 5.0+)DevEco Studio NEXT Beta1+
手机与 PC/2in1手机:同上方;PC/2in1:HarmonyOS 6.0.0 Beta1+DevEco Studio 6.0.0 Beta1+

关键检查:通过 canIUse 判断设备是否支持碰一碰能力,避免在不支持的设备上触发无效逻辑:

// 检查设备是否支持碰一碰分享
if(canIUse('SystemCapability.Collaboration.HarmonyShare')){
    console.log("设备支持碰一碰分享,可初始化相关逻辑");
    // 后续注册碰一碰事件...
} else {
    console.log("设备不支持碰一碰分享,需隐藏相关引导");
}
1.2 核心业务流程

无论哪种场景,碰一碰分享的核心流程都遵循'注册→触发→传输→解除'四步,以手机与手机为例:

  1. 注册事件:宿主应用进入可分享界面(如选中图片、打开 Wi-Fi 详情)时,注册碰一碰分享监听;
  2. 触发交互:双端设备亮屏、解锁且开启华为分享(关闭则弹窗提示开启),顶端轻碰;
  3. 数据传输:源端构造分享数据(如图片 URI、链接)并发送,目标端接收并拉起对应应用;
  4. 解除监听:离开可分享界面(如关闭图片、退出页面)时,解除碰一碰监听,避免内存泄漏。

二、手机与手机碰一碰开发:从预览到异常处理

手机间碰一碰是最基础的场景,需重点关注预览体验、数据传输方式、安全策略与异常兜底,以下分模块详解。

2.1 第一步:引导用户触发——注册碰一碰事件

用户可能不清楚'何时可碰',需在可分享界面添加引导(文本 + 动图),提升交互感知。

2.1.1 引导资源集成

华为提供统一的碰一碰引导动图,需:

  1. 下载资源包:碰一碰引导资源(完整下载 knock_share_guide 目录);
  2. 放置路径:将资源放入应用 entry/src/main/resources/rawfile 目录;
  3. 界面引导:在可分享界面(如图片预览页)显示文本提示 + 动图,示例文案:
    • '可碰一碰分享至 HarmonyOS 5 及以上版本手机'
    • '对方需在控制中心开启'华为分享''
2.1.2 注册监听事件

在页面 aboutToAppear 生命周期中注册碰一碰事件,aboutToDisappear 中解除,确保资源释放:

import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { systemShare, harmonyShare } from '@kit.ShareKit';
import { fileUri } from '@kit.CoreFileKit';
import { UIContext, Context } from '@kit.ArkUI';

@Component
export default struct ImageSharePage {
    // 页面进入时注册碰一碰监听
    aboutToAppear(): void {
        this.registerKnockShare();
    }

    // 页面销毁时解除监听
    aboutToDisappear(): void {
        this.unregisterKnockShare();
    }

    // 注册碰一碰分享事件
    private registerKnockShare() {
        // 配置监听参数(windowId 需替换为实际页面的窗口 ID,不可用示例值)
        const capabilityRegistry: harmonyShare.SendCapabilityRegistry = {
            windowId: 1001, // 实际开发中通过 UIContext 获取真实 windowId
        };

        // 监听碰一碰事件,触发时构造并发送数据
        harmonyShare.on('knockShare', capabilityRegistry, (sharableTarget: harmonyShare.SharableTarget) => {
            this.buildShareData(sharableTarget);
        });
    }

    // 解除碰一碰分享监听
    private unregisterKnockShare() {
        const capabilityRegistry: harmonyShare.SendCapabilityRegistry = {
            windowId: 1001, // 与注册时的 windowId 一致
        };
        harmonyShare.off('knockShare', capabilityRegistry);
    }

    // 构造分享数据(核心逻辑)
    private buildShareData(sharableTarget: harmonyShare.SharableTarget) {
        // 1. 获取预览图 URI(示例:本地图片路径,实际需替换为业务图片路径)
        const uiContext: UIContext = this.getUIContext();
        const context: Context = uiContext.getHostContext() as Context;
        const imagePath = context.filesDir + '/shared_image.jpg';
        const thumbnailUri = fileUri.getUriFromPath(imagePath);

        // 2. 构造分享数据(utd 类型根据内容调整,图片可设为 IMAGE,链接设为 HYPERLINK)
        const shareData: systemShare.SharedData = new systemShare.SharedData({
            utd: utd.UniformDataType.IMAGE, // 图片类型
            content: thumbnailUri, // 图片 URI
            title: '旅行照片', // 卡片标题(可选,根据模板决定)
            description: '2025 年夏日旅行', // 卡片描述(可选)
            thumbnailUri: thumbnailUri, // 预览图 URI
        });

        // 3. 发起分享(必须在 3 秒内调用,否则超时失败)
        sharableTarget.share(shareData);
    }

    build() {
        // 页面布局(省略,需包含图片预览 + 碰一碰引导动图)
    }
}
2.2 第二步:优化视觉体验——设置分享预览

分享卡片的预览效果直接影响用户接受度,Share Kit 提供 3 种卡片模板,需根据分享内容类型选择:

模板类型适用场景配置要求布局约束
纯图片布局文件、图片(无需文字说明)仅传递 thumbnailUri预览图宽高比≥1:4,超出部分裁剪
沉浸式大卡布局链接(需展示文字)同时传递 title+description+thumbnailUri,且预览图宽高比<1:1标题最多 2 行(超出省略),描述 1 行,显应用图标
白卡上下布局链接(需展示文字)同时传递 title+description+thumbnailUri,且预览图宽高比>1:1同上,预览图仅占卡片上方,不铺满
2.2.1 预览图最佳实践

预览图分辨率影响加载速度与清晰度,推荐按以下标准设置(文档 2):

预览图来源推荐比例推荐分辨率(px)
应用海报3:4最小 600_800,最大 3000_4000
用户上传图片无限制最大 3000*4000(避免过大)
2.2.2 预览图延迟更新(解决云端图片问题)

若预览图存储在云端(如 OSS),碰一碰触发时可能未下载完成,导致卡片空白。可先发送核心数据,待图片下载后更新预览:

private buildShareData(sharableTarget: harmonyShare.SharableTarget) {
    // 1. 先发送无预览图的核心数据(用系统默认图占位)
    const shareData: systemShare.SharedData = new systemShare.SharedData({
        utd: utd.UniformDataType.HYPERLINK,
        content: 'https://example.com/travel', // 分享链接
        title: '旅行攻略',
        description: '超全景点指南',
    });
    sharableTarget.share(shareData);

    // 2. 模拟云端图片下载(实际项目中替换为真实下载回调)
    setTimeout(async () => {
        const uiContext: UIContext = this.getUIContext();
        const context: Context = uiContext.getHostContext() as Context;
        // 假设下载完成,获取本地路径
        const downloadedImagePath = context.filesDir + '/downloaded_poster.jpg';
        const newThumbnailUri = fileUri.getUriFromPath(downloadedImagePath);

        // 3. 更新预览图
        sharableTarget.updateShareData({
            thumbnailUri: newThumbnailUri,
        });
    }, 3000); // 实际不建议用固定延迟,应监听下载完成事件
}
2.3 第三步:选择数据传输方式——App Linking vs Deep Linking

若分享内容为'链接'(如商品页、文章页),需通过以下两种方式实现应用跳转,核心区别在于'未安装应用时的处理逻辑'。

2.3.1 App Linking(推荐)

优势:无论目标端是否安装应用,均能直达内容——

  • 已安装:直接拉起应用并打开链接;
  • 未安装:跳转应用市场(需集成 App Linking Kit);
  • 支持延迟链接:应用下载后仍能获取之前的分享链接。

示例代码:

private buildShareData(sharableTarget: harmonyShare.SharableTarget) {
    const shareData: systemShare.SharedData = new systemShare.SharedData({
        utd: utd.UniformDataType.HYPERLINK, // 必须设为 HYPERLINK
        content: 'https://sharekitdemo.drcn.agconnect.link/ZB3p', // App Linking 链接
        title: '华为商城新品',
        description: 'nova 14 系列限时优惠',
        thumbnailUri: 'file:///data/storage/.../poster.jpg', // 预览图 URI
    });
    sharableTarget.share(shareData);
}
2.3.2 Deep Linking(简单但有局限)

局限:仅在目标端已安装应用时生效,未安装则弹窗提示'暂无可用打开方式'。

示例代码:

// 与 App Linking 代码类似,仅 content 替换为 Deep Linking 链接
content: 'myapp://product/detail?id=123', // 自定义 Deep Linking 协议
2.4 第四步:保障安全与体验——安全策略与异常处理
2.4.1 安全策略:明确设备/账号身份

为避免用户接收陌生设备的分享,Share Kit 会显示发送端/接收端的身份信息(需 HarmonyOS NEXT 5.0.0.123 SP16 及以上版本):

角色对端已登录华为账号对端未登录华为账号
发送端显示接收端账号昵称 + 头像显示接收端设备名(如'Mate 70')
接收端显示发送端账号昵称 + 头像显示发送端设备名

注意:SP16 之前的版本不显示任何身份信息,开发时需考虑版本兼容。

2.4.2 异常场景处理

当无法发起分享时,需主动提示用户,避免用户等待。

场景 1:当前界面无可分享内容

harmonyShare.on('knockShare', (sharableTarget: harmonyShare.SharableTarget) => {
    // 调用 clarifyNonShare 终止分享,并提示用户
    sharableTarget.clarifyNonShare({ message: '当前界面不支持碰一碰,请在图片预览或文件详情页尝试' });
});

效果:系统弹窗提示用户,引导至可分享界面。

场景 2:分享内容下载失败(如云端图片下载超时)

harmonyShare.on('knockShare', (sharableTarget: harmonyShare.SharableTarget) => {
    // 模拟下载失败
    const downloadFailed = true;
    if (downloadFailed) {
        // 调用 reject 终止分享,指定错误码
        sharableTarget.reject(harmonyShare.SharableErrorCode.DOWNLOAD_ERROR);
    }
});

效果:系统提示'分享内容下载失败,请稍后重试'。

三、手机与 PC/2in1 碰一碰开发:跨端协同新体验

手机与 PC/2in1 的碰一碰进一步拓展场景(如手机传图到 PC 编辑、PC 传文档到手机),需关注双向分享限制与沙箱接收特性。

3.1 核心约束与环境
  1. 账号要求:手机与 PC/2in1 必须登录相同华为账号;
  2. 设备形态:仅支持手机直板态/折叠手机直板态,不支持折叠态;
  3. 角度约束(触发成功率关键):
    • 手机与 PC 屏幕俯视夹角≤5°(尽量平行);
    • 侧视夹角>35°(避免过度倾斜);
    • 正视夹角≤25°(正对屏幕);
  4. 保护壳:仅支持官方轻薄保护壳,过厚壳会影响感应。
3.2 双向分享限制(避坑要点)

从 HarmonyOS 6.0.0 Beta5 开始,手机与 PC/2in1 不支持'双向同时分享',遵循以下优先级:

  1. 若手机前台有可分享内容(如打开图片),则手机为发送端,PC 为接收端;
  2. 若手机前台无内容,但 PC 前台有可分享内容(如打开文档),则PC 为发送端,手机为接收端;
  3. 若两者均无内容,触发'无内容分享'提示。

注意:Beta5 之前的版本支持双向分享(双方同时发送接收),开发时需根据版本适配逻辑。

3.3 分享内容直达应用:沙箱接收

PC/2in1 支持'沙箱接收',即手机碰 PC 后,文件直接传入 PC 应用的沙箱目录,无需用户选择保存路径,实现'直达编辑'(如手机传图到 PC 版 PS,直接打开编辑)。

3.3.1 沙箱接收开发步骤
import { uniformTypeDescriptor as utd } from '@kit.ArkData';
import { systemShare, harmonyShare } from '@kit.ShareKit';
import { common } from '@kit.AbilityKit';

@Component
export default struct PCImageEditorPage {
    aboutToAppear(): void {
        this.registerSandboxReceive();
    }

    aboutToDisappear(): void {
        this.unregisterSandboxReceive();
    }

    // 注册沙箱接收事件(仅支持文件类型)
    private registerSandboxReceive() {
        const capabilityRegistry: harmonyShare.RecvCapabilityRegistry = {
            windowId: 2001, // PC 应用窗口 ID
            capabilities: [
                {
                    utd: utd.UniformDataType.IMAGE, // 仅接收图片类型
                    maxSupportedCount: 5, // 最多接收 5 张图片
                },
            ],
        };

        // 监听数据接收事件
        harmonyShare.on('dataReceive', capabilityRegistry, (receivableTarget: harmonyShare.ReceivableTarget) => {
            const uiContext = this.getUIContext();
            const context = uiContext.getHostContext() as common.UIAbilityContext;

            // 指定文件保存路径(应用沙箱目录)
            const savePath = context.filesDir + '/received_images/';

            // 接收文件
            receivableTarget.receive(savePath, {
                // 每接收一个文件触发 onDataReceived
                onDataReceived: (sharedData: systemShare.SharedData) => {
                    const records = sharedData.getRecords();
                    records.forEach((record) => {
                        console.log(`接收文件:${record.uri}`);
                        // 触发应用编辑逻辑(如打开图片编辑界面)
                        this.openImageEditor(record.uri);
                    });
                },
                // 接收完成/失败触发 onResult
                onResult: (resultCode: harmonyShare.ShareResultCode) => {
                    if (resultCode === harmonyShare.ShareResultCode.SHARE_SUCCESS) {
                        console.log("所有文件接收完成");
                    } else {
                        console.log(`接收失败,错误码:${resultCode}`);
                    }
                },
            });
        });
    }

    // 解除沙箱接收监听
    private unregisterSandboxReceive() {
        const capabilityRegistry: harmonyShare.RecvCapabilityRegistry = {
            windowId: 2001,
            capabilities: [
                {
                    utd: utd.UniformDataType.IMAGE,
                    maxSupportedCount: 5,
                },
            ],
        };
        harmonyShare.off('dataReceive', capabilityRegistry);
    }

    // 打开图片编辑界面
    private openImageEditor(imageUri: string) {
        // 业务逻辑:跳转编辑页并加载图片
    }

    build() {
        // PC 应用界面(省略)
    }
}
3.3.2 拒绝沙箱接收

若应用当前无法接收(如编辑中),可调用 reject 拒绝:

harmonyShare.on('dataReceive', (receivableTarget: harmonyShare.ReceivableTarget) => {
    // 业务判断:当前正在编辑,拒绝接收
    if (this.isEditing) {
        receivableTarget.reject(harmonyShare.ReceivableErrorCode.NO_RECEIVABLE_ERROR);
    }
});

四、特殊场景:组队邀请开发

在游戏、运动类应用中,可通过碰一碰发起'组队邀请',需避免'双方同时邀请'导致的冲突,此时需使用单向分享能力。

4.1 核心代码:注册单向分享
aboutToAppear(): void {
    const capabilityRegistry: harmonyShare.SendCapabilityRegistry = {
        windowId: 3001,
        sendOnly: true, // 申明'仅发送邀请,不接收邀请'
    };
    harmonyShare.on('knockShare', capabilityRegistry, (sharableTarget) => {
        // 构造组队链接(含房间 ID、邀请者信息)
        const teamLink = `mygame://team/join?id=12345&inviter=user1`;
        const shareData = new systemShare.SharedData({
            utd: utd.UniformDataType.HYPERLINK,
            content: teamLink,
            title: '邀请加入游戏战队',
            description: '点击立即组队开黑',
            thumbnailUri: 'file:///.../team_poster.jpg',
        });
        sharableTarget.share(shareData);
    });
}
4.2 冲突处理
  • 若双方均设置sendOnly: true:系统终止分享,提示'请任意一方退出当前应用后再试';
  • 若仅一方设置:分享成功,目标端拉起应用并通过 onNewWant 获取组队链接。

获取组队链接:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';

export default class GameAbility extends UIAbility {
    // 应用首次启动时获取链接
    onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        if (want.uri) {
            console.log(`收到组队邀请:${want.uri}`);
            this.joinTeam(want.uri); // 解析链接并加入队伍
        }
    }

    // 应用已启动时获取链接
    onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
        if (want.uri) {
            this.joinTeam(want.uri);
        }
    }

    private joinTeam(teamUri: string) {
        // 解析 URI 中的房间 ID、邀请者信息,发起加入请求
    }
}

五、开发最佳实践总结

  1. 环境检查优先:通过 canIUse 判断设备能力,避免无效逻辑;
  2. 资源及时释放:在 aboutToDisappear 中解除碰一碰监听,防止内存泄漏;
  3. 预览图适配:按推荐分辨率设置预览图,云端图片用延迟更新兜底;
  4. 异常全面覆盖:处理'无内容''下载失败'等场景,避免用户无反馈;
  5. 跨端版本适配:手机与 PC 的系统版本要求不同,双向分享限制需区分版本;
  6. 用户引导清晰:在可分享界面添加文本 + 动图引导,降低使用门槛。

希望开发者可以通过以上开发指南,快速实现 HarmonyOS 碰一碰分享功能,为用户提供'一碰即传'的跨端体验。随着鸿蒙生态的扩展,未来碰一碰还将支持更多设备(如平板、智慧屏),进一步丰富全场景交互。

目录

  1. 一、碰一碰分享核心基础:环境与核心概念
  2. 1.1 环境要求(必看!)
  3. 1.2 核心业务流程
  4. 二、手机与手机碰一碰开发:从预览到异常处理
  5. 2.1 第一步:引导用户触发——注册碰一碰事件
  6. 2.1.1 引导资源集成
  7. 2.1.2 注册监听事件
  8. 2.2 第二步:优化视觉体验——设置分享预览
  9. 2.2.1 预览图最佳实践
  10. 2.2.2 预览图延迟更新(解决云端图片问题)
  11. 2.3 第三步:选择数据传输方式——App Linking vs Deep Linking
  12. 2.3.1 App Linking(推荐)
  13. 2.3.2 Deep Linking(简单但有局限)
  14. 2.4 第四步:保障安全与体验——安全策略与异常处理
  15. 2.4.1 安全策略:明确设备/账号身份
  16. 2.4.2 异常场景处理
  17. 三、手机与 PC/2in1 碰一碰开发:跨端协同新体验
  18. 3.1 核心约束与环境
  19. 3.2 双向分享限制(避坑要点)
  20. 3.3 分享内容直达应用:沙箱接收
  21. 3.3.1 沙箱接收开发步骤
  22. 3.3.2 拒绝沙箱接收
  23. 四、特殊场景:组队邀请开发
  24. 4.1 核心代码:注册单向分享
  25. 4.2 冲突处理
  26. 五、开发最佳实践总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw结合Kimi K2.5开源AI助手本地私有化部署与办公自动化实战
  • 使用 Continue 插件本地部署 AI 代码助手替代 Cursor 与 Copilot
  • C++ 100 道高频经典面试题及答案解析
  • 大模型开发转行指南:必备知识、技能与学习路径详解
  • AI 大模型在职业教育中的应用解决方案
  • AMD 显卡 llama.cpp Vulkan 后端兼容与优化指南
  • Vue3+Spring Boot 若依 RuoYi-Vue3 快速搭建企业级后台
  • C++ 类与对象核心知识点总结
  • Whisper v0.2 本地语音转文字工具安装与使用指南
  • Stable Diffusion 3.5 WebUI Forge 与 SwarmUI 实战指南
  • Python 爬虫实战:爬取汽车之家车型与报价数据
  • 2026 AI智能图+AI视频终极工具箱:10个必备神器合集
  • Claude Code 中 CLAUDE.md 的加载时机与书写最佳实践
  • Linux 进程间通信:命名管道(FIFO)实战指南
  • VR 多相电源架构与设计详解
  • 判断一个需求值不值得做:产品经理的评估思路
  • 正版 Adobe PS 与 LRC AI 填充功能无法使用解决方案
  • OpenCode 安装 oh-my-opencode 插件教程:AI 辅助自动安装
  • 深入理解飞书 Webhook 签名验证:一次踩坑到填坑的完整记录
  • LightRAG:轻量级 RAG 模型构建知识库问答系统

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online