[鸿蒙2025领航者闯关记]HarmonyOS 6.0 新特性碰一碰分享实现快捷共享带办清单
摘要: “智能带办”应用利用HarmonyOS 6.0的碰一碰分享功能,实现线下快捷共享物品清单。该应用通过AI(如DeepSeek AI)智能生成出行清单,解决用户遗忘物品的痛点。碰一碰分享流程包括注册事件、构造数据(支持三种卡片模板)、发送及处理数据,需双方设备亮屏解锁并开启华为分享。开发中通过生命周期管理注册/注销监听,并优化引导提示,提升分享体验。最终实现高效多人协作整理清单,避免传统分享
引言
HarmonyOS 6.0增强了碰一碰分享能力,支持组队场景的单向发送能力和云预览图延迟个更新,正好开发的“智能带办”应用有线下快捷分享的强诉求,碰一碰分享很满足这个诉求,立马动手进行接入。
项目介绍
“智能带办”应用是干什么的呢?相信每个人都有这样的瞬间:
- 飞到目的地才发现没带充电头?
- 去海边露营结果忘了带驱蚊水?
- 每次出差前都要花半小时在脑子里“过电影”列清单,却还是百密一疏?
智能带办 就是为了解决这些“出门焦虑”而生的。它不是一个普通的待办清单,而是一个深耕于 “出门要带什么” 场景的智能助手。项目的核心亮点是把脑力活交给 AI:
- 输入“要做的事”,秒出“要带的物”: 只需对这输入框 说一句:“我要去哈尔滨看冰雕,待三天”,后台接入的 DeepSeek AI 就会基于气候、时长和活动,自动为你生成一份精准的“带办清单”——从保暖内衣到暖宝宝,从身份证到充电宝,一应俱全。
- 智能场景化推荐: 项目内置了多种典型场景(如:商务出差、户外露营、带娃旅行、极限运动等)。系统会根据你的习惯和高频场景,主动推荐你可能需要的物品,让你清单整理从“白手起家”变成“一键确认”。
AutoTodo,让你每一次出发,都底气十足。
在智能助手页面输入要做的事情,自动生成需要带的物品清单:
点击保存后进入具体事情详情页,可以操作所带物品清单:
也可以从推荐场景中具体的事情进入详情页:
整理带办物品清单时可能是线下和周围的人,比如家人,同事一起处理,生成一份清单多人互相准备、勾选会极大的提高效率。在其他端最常用的分享方式是通过微信分享链接,对方收到后打开,在微信收到的连接一般都不允许直接打开应用,还需要先跳转到浏览器再操作特别繁琐,有了碰一碰分享功能可以很便捷的共享清单给周围人。
碰一碰分享原理介绍
碰一碰是华为Share Kit推出的一种分享方式,支持用户通过碰一碰发起跨端分享,可实现传输图片、共享Wi-Fi等。碰一碰分享的主要流程如下:
- 宿主应用注册碰一碰分享事件,并与亮屏且解锁的对端设备碰一碰。
- 宿主应用发现设备,调用碰一碰分享事件回调,在回调事件中构造分享数据并发送。
- 目标设备接收并处理分享数据。
- 宿主应用解除注册碰一碰分享事件。
整体处理流程图如下:
总结下来就是再提供分享能力的页面注册碰一碰监听事件,再监听到有两个设备碰一碰行为回调后根据业务逻辑构造分享数据,触发分享后被分享方处理分享内容或数据。
注意:手机应用发起碰一碰分享时,双端设备必须满足三个条件:双方均已开启华为分享服务、亮屏、解锁。
碰一碰分享实现
1、准备碰一碰分享物料
在进入支持碰一碰分享的页面时,给出适当的引导和提示,可有效提升用户分享意愿,可以通过文本或者动图提示用户进行碰一碰分享,HarmonyOS官方提供了统一的动图资源文件以方便应用接入。下载https://gitcode.com/HarmonyOS_Samples/share-kit_-sample-code_-clientdemo_-arkts/tree/master/entry/src/main/resources/rawfile后,将完整knock_share_guide目录所有文件,并放置于应用entry/src/main/resources/rawfile目录下。“智能带办中”引导效果如图:
2、构建分享内容
接入碰一碰分享时,需根据不同的分享数据类型,适配相应的卡片模板,Share Kit支持三种卡片模板供手机发起碰一碰分享时选择:
- 纯图片布局:纯图片布局只包括预览图,当分享数据为文件、图片等无需添加标题及描述的场景,推荐使用此卡片模板。
- 使用方法:构造分享数据时,仅传递预览图(thumbnailUri)字段,即可生成此卡片模板。
- 布局要求:预览图支持最小宽高比1:4,超出部分将被裁剪。
- 沉浸式大卡布局:沉浸式大卡布局包括预览图、标题、描述、应用图标。当分享数据为链接类型时,需要向用户传递链接的内容,推荐使用此卡片模板。
- 使用方法,需同时满足以下2个条件
- 构造分享数据时,需同时传入标题(title)、描述(description)字段和预览图(thumbnailUri)字段。
- 预览图宽高比小于1:1。
- 布局要求
- 预览图:支持最小宽高比1:4,超出部分将被裁剪。
- 标题:最大可显示2行,当文本超过2行时,未能正常在屏幕显示的文本用省略号代替。如果标题末尾有重要信息显示,需应用自行控制字数约20个中文左右。
- 描述:仅可显示1行,文本超过1行时,未能正常在屏幕上显示的文本用省略号代替。
- 应用图标:无需配置,系统将默认获取应用图标用于显示在卡片底部。
- 使用方法,需同时满足以下2个条件
- 白卡上下布局:白卡上下布局包括预览图、标题、描述、应用图标。当分享数据为链接类型时,需要向用户传递链接的内容,推荐使用此卡片模板。
- 使用方法,需同时满足以下2个条件:
- 构造分享数据时,需同时传入标题(title)、描述(description)字段和预览图(thumbnailUri)字段。
- 预览图宽高比大于1:1。
- 布局要求
- 预览图:仅显示在卡片上方,不会铺满整个卡片。
- 标题:最大可显示2行,当文本超过2行时,未能正常在屏幕显示的文本用省略号代替。如果标题末尾有重要信息显示,需应用自行控制字数约20个中文左右。
- 描述:仅可显示1行,文本超过1行时,未能正常在屏幕上显示的文本用省略号代替。
- 应用图标:无需配置,系统将默认获取应用图标用于显示在卡片底部。
- 使用方法,需同时满足以下2个条件:
以链接分享为例,在页面出现aboutToAppear生命周期方法中,注册碰一碰事件回调:
aboutToAppear(): void {
if (this.isNoListening()) {
this.tipsListening();
}
const uiContext: UIContext = this.getUIContext();
const context: Context = uiContext.getHostContext() as Context;
//注册页面切换到前台事件监听
context.eventHub.on('onFocus', () => {
if (this.isNoListening()) {
this.tipsListening();
}
});
//注册也卖弄切换到后台事件监听
context.eventHub.on('onBackGround', () => {
this.onBackGround();
});
}
在页面关闭生命周期方法aboutToDisappear注销事件监听:
aboutToDisappear(): void {
Logger.i(TAG, 'aboutToDisappear invoked.');
this.disablingAllListening();
const uiContext: UIContext = this.getUIContext();
const context: Context = uiContext.getHostContext() as Context;
context.eventHub.off('onFocus');
context.eventHub.off('onBackGround');
}
接下来在tipsListening方法中注册监听,构造分享数据:
private sendOnlyCallback = (sharableTarget: harmonyShare.SharableTarget) => {
const uiContext: UIContext = this.getUIContext();
const contextFaker: Context = uiContext.getHostContext() as Context;
let filePath = contextFaker.filesDir + '/knock_share_bg.jpg'; //封面图,采用固定图片
let shareData: systemShare.SharedData = new systemShare.SharedData({
utd: utd.UniformDataType.HYPERLINK,
content: 'https://todo.xxxxxx.com/tododetail?topic=3xdsdv', //分享链接地址
title: this.title, //带办事情名称
description: this.mTodoGroupBean.description, //带办事情描述
thumbnailUri: fileUri.getUriFromPath(filePath), //分享封面图
});
sharableTarget.share(shareData)
}
private tipsListening() {
if (!this.tipsStatus) {
harmonyShare.on('knockShare', this.sendOnlyCallback);
this.tipsStatus = true;
} else {
try {
const uiContext: UIContext = this.getUIContext();
uiContext.getPromptAction().showToast({ message: $r('app.string.knock_close_other') });
} catch (error) {
Logger.e(TAG, `showToast error. Code: ${error?.code}, message: ${error?.message}`);
}
}}
分享的参数topic是服务端生成的用于加入某个带办组的标识,进入页面时请求服务端生成。
3、接收分享内容
要让应用允许被拉起,需要在工程的module.json5中EntryAbility的exported配置为true,并且skills要包含entity.system.browsable和ohos.want.action.home:
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
},
{
"entities": [
// entities必须包含"entity.system.browsable"
"entity.system.browsable"
],
"actions": [
// actions必须包含"ohos.want.action.viewData"
"ohos.want.action.viewData"
],
"uris": [
{
// scheme须配置为https
"scheme": "https",
// host须配置为关联的域名
"host": "todo.xxxxxx.com",
// path可选,表示域名服务器上的目录或文件路径,例如www.example.com/path1中的path1
// 如果应用只能处理部分特定的path,则此处应该配置应用所支持的path,避免出现应用不能处理的path链接也被引流到应用中的问题
"path": "tododetail"
}
],
// domainVerify须设置为true
"domainVerify": true,
}
]
}
],
4、跳转落地页
在EntryAbility的onCreate声明周期方法中解析want,判断是上面分享的url,则执行对应逻辑:
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
// 从want中获取传入的链接信息。
// 如传入的url为:https://todo.xxxxxx.com/tododetail?topic=3dfd3
let uri = want?.uri;
if (uri) {
// 从链接中解析query参数,拿到参数后,根据自己的业务需求进行后续的处理。
try {
let urlObject = url.URL.parseURL(want?.uri);
let action = urlObject.params.get('topic');
// 例如,当topic为不为空时时,跳转到带办事情详情页。
} catch (error) {
hilog.error(0x0000, 'testTag', `Failed to parse url.`);
}
}}
携带topic对应value打开对应详情页请求服务端加入分享,即可开始共同编辑带办组了。
踩坑记:链接分享无法打开应用
按照上面步骤开发完成后发现碰一碰分享后,被分享方无法打开具体应用,而是跳转到浏览器。
因为分享链接时utd类型需配置为"general.hyperlink",采用的是App Linking分享,使用该方式时,当应用已安装时,App Linking可直接拉起应用;当应用未安装时,App Linking的默认行为是通过系统浏览器打开链接对应的网页。通过App Linking Kit的直达应用市场能力,可以实现在应用未安装时直接跳转应用市场。
要使用App Linking需要在App AppGallery Connect开通App Link服务,并配置聚合链接地址:
配置完成后还需要给APP使用正式签名才可以正常使用分享跳转。而且这里注意申请聚合链接时需要一个https的服务,该服务必须可访问,并且把如下的applinking.json文件配置到服务域名的.well-know下(比如填写域名为todo.xxxxxx.com,则文件的访问地址为https://todo.xxxxxx.com/well-know/applinking.json:
{
"applinking": {
"apps": [
{
"appIdentifier": "1234567"//创建应用时生成的APP ID
}
]
}
}
应用链接发布完成后,如果距离上次更新超过24小时,系统会去域名服务器上重新获取配置文件进行交集校验。
如果遇到系统尚未完成域名校验问题,可以先在设备上安装应用,等待至少20秒,以确保系统完成域名校验的流程;系统进行域名校验时,如存在断网、弱网等情况,可能导致域名校验失败,域名校验失败后,系统将在24小时内重新进行域名校验。
如果需要查看应用域名验证结果,可以在DevEco Studio中打开终端,并使用以下命令查询验证结果:
hdc shell hidumper -s AppDomainVerifyManager
输入效果如下说明验证成功:
总结
通过接入 HarmonyOS 6 的“碰一碰”分享,我们在“智能带办”中补齐了线下多人协同的关键一环:同处一室的家人、同事只需轻触手机,即可把“要带的物”一键共享到同一待办组,现场勾选、补充、确认,显著减少口头沟通与重复整理的成本。整套方案以系统级 Share Kit 为底座,遵循“注册监听 → 构造分享数据 → 触发分享 → 被拉起落地”的标准链路,稳定且低门槛;结合 App Linking 直达应用指定页,实现“已装直达、未装引导下载”的闭环体验,兼顾体验与转化。
在工程落地上,我们按“引导提示 → 卡片模板选择 → 生命周期管理 → 接收与路由”的顺序实施:在支持分享的页面展示官方动图提示,按内容类型选用纯图片、沉浸式大卡或白卡上下布局,页面前后台正确注册/注销监听避免误触与泄漏;被分享端在 module.json5 正确声明 exported、skills、uris、domainVerify 等能力,并在 EntryAbility 解析 want.uri 后携带参数(如 topic)跳转至对应详情页,完成组队加入与协同编辑。
更多推荐
所有评论(0)