第7.14篇:碰一碰精准分享------跨设备素材插入
难度 :⭐⭐⭐ 高级
前置知识 :第 4.4 篇 跨设备分享------systemShare 集成
涉及源文件:参考 Share Kit 开发文档

概述
在第 4.4 篇中,我们深入讲解了 systemShare------HarmonyOS 的通用分享能力。它通过系统分享面板让用户选择目标应用,完成内容的分发。但 systemShare 有一个根本性的局限:它只能"发给应用",不能"发到位置"。
想象这样一个场景:你在平板上用"画伴梦工厂"画了一幅涂鸦,希望把它插入到电脑上的 WPS 文档中。使用传统的 systemShare,你需要:
- 平板上分享文件
- 电脑上接收文件到某个文件夹
- 在 WPS 中手动找到文件再插入
整个过程涉及多个步骤,用户体验断断续续。
HarmonyOS 7(API 26)在 HDC 2026 上推出的碰一碰精准分享(Tap-to-Share Precise Sharing) 彻底改变了这一体验。它利用 NFC 触碰精准识别目标设备的窗口和插入位置,实现了"碰一下,内容直达目的地"的零跳转体验。
本文将深入解析碰一碰精准分享的技术原理、Share Kit 的 API 升级、开发者集成方式,以及与现有 systemShare 的完整对比,并探讨在"画伴梦工厂"项目中如何利用这一能力实现跨设备绘画协作。
一、碰一碰精准分享的技术原理
1.1 什么是精准分享
碰一碰精准分享是 HarmonyOS 7 基于 NFC 近场通信和分布式窗口管理能力实现的新一代分享机制。与传统分享将内容发送到目标应用不同,精准分享将内容直接插入到目标应用在目标设备上的指定窗口中的指定位置。
传统分享:
手机 ──→ 分享面板 ──→ 选择微信 ──→ 选择联系人 ──→ 发送 ──→ 接收方手动下载并插入
精准分享:
手机碰一下平板 ──→ 内容直接插入到平板上当前活动窗口的光标位置
1.2 NFC 触碰的三大识别任务
当用户将手机 NFC 区域靠近平板或电脑屏幕时,系统在200 毫秒内完成三项识别任务:
任务一:设备识别------识别目标设备
NFC 标签中携带了目标设备的分布式设备 ID。系统通过分布式软总线在毫秒级完成设备认证和通信链路建立。
任务二:窗口识别------识别前台应用窗口
目标设备的窗口管理器(Window Manager)返回当前焦点窗口的标识信息,包括:
| 信息 | 说明 |
|---|---|
bundleName |
目标应用的包名 |
abilityName |
前台 Ability 名称 |
windowId |
窗口唯一标识 |
windowBounds |
窗口在屏幕上的位置和尺寸 |
任务三:坐标识别------精确计算插入位置
这是最精妙的部分。NFC 天线通常位于设备边缘,触碰时系统记录 NFC 信号最强点相对于屏幕的物理坐标。然后结合目标窗口的边界信息,计算出内容插入点在该窗口内的逻辑坐标。
┌─────────────────────────────────────────────┐
│ 平板屏幕 │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ WPS 文档窗口 │ │
│ │ │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ 文档内容区域 │ │ │
│ │ │ │ │ │
│ │ │ ✦ ← NFC 触碰点 │ │ │
│ │ │ (坐标映射到文档内) │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ │
│ NFC 天线区域 ──────── 手机触碰 │
└─────────────────────────────────────────────┘
1.3 坐标映射的核心算法
窗口坐标映射是精准分享的技术关键。系统执行以下计算链:
触碰物理坐标 (touchX, touchY)
│
▼
归一化为屏幕百分比坐标
normX = touchX / screenWidth
normY = touchY / screenHeight
│
▼
映射到目标窗口内
windowX = normX * windowWidth
windowY = normY * windowHeight
│
▼
应用内部坐标(如有滚动偏移)
contentY = windowY + scrollOffset
│
▼
最终插入坐标 (contentX, contentY)
由于 NFC 触碰精度在毫米级(约 3-5mm),加上不同设备 NFC 天线位置的差异,系统还会对坐标进行校准补偿------通过设备出厂校准数据消除系统误差,实现像素级的贴合度。
二、Share Kit 更新------API 26 精准分享能力
2.1 Share Kit 架构升级
HarmonyOS 7 对 @kit.ShareKit 进行了重大升级,新增了精准分享相关的模块和接口。升级后的 Share Kit 架构如下:
@kit.ShareKit
├── systemShare(通用分享)
│ ├── ShareController
│ ├── SharedData
│ └── ShareControllerOptions
│
└── preciseShare(精准分享 --- 新增)
├── PreciseShareController
├── PreciseShareData
├── ShareTargetFilter
└── PreciseReceiveHandler
其中 preciseShare 子模块是 API 26 的全新能力,与 systemShare 并列存在,两者互不依赖。
2.2 核心新增接口
PreciseShareController------精准分享发送端控制器:
| 接口 | 说明 |
|---|---|
createPreciseShareController(data) |
创建精准分享控制器实例 |
startNfcDetection(context) |
启动 NFC 检测,等待触碰 |
cancelDetection() |
取消 NFC 检测 |
on('targetDetected', callback) |
检测到目标设备时的回调 |
on('shareComplete', callback) |
分享完成回调 |
PreciseShareData------精准分享数据结构:
typescript
interface PreciseShareData {
records: PreciseShareRecord[];
shareMode: PreciseShareMode;
}
interface PreciseShareRecord {
utd: string; // 统一类型描述符
uri?: string; // 文件 URI
content?: string; // 文本内容
thumbnail?: PixelMap; // 缩略图
title?: string; // 标题
}
enum PreciseShareMode {
SINGLE_FILE, // 单文件模式
MULTI_FILE, // 多文件模式
DATA_STREAM // 数据流模式
}
ShareTargetFilter------目标过滤条件(可选配置):
typescript
interface ShareTargetFilter {
allowedBundles?: string[]; // 限制仅特定应用可接收
windowType?: WindowType; // 限制窗口类型
minWindowWidth?: number; // 最小窗口宽度
}
PreciseReceiveHandler------接收端处理器(在目标应用中注册):
typescript
interface PreciseReceiveHandler {
onReceive(context: UIAbilityContext, data: PreciseReceiveData): Promise<ReceiveResult>;
onCoordinate(context: UIAbilityContext, coordinate: InsertCoordinate): Promise<void>;
}
interface PreciseReceiveData {
records: PreciseShareRecord[];
sourceDeviceId: string; // 来源设备
coordinate?: InsertCoordinate; // 插入坐标(可选)
}
interface InsertCoordinate {
x: number; // 窗口内逻辑 X 坐标(vp)
y: number; // 窗口内逻辑 Y 坐标(vp)
windowId: string; // 目标窗口 ID
}
2.3 工作流程总览
发送端(手机) 接收端(平板/电脑)
│ │
│ createPreciseShareController │
│ startNfcDetection() │
│ │
│ ── NFC 触碰 ──────────────────→ │
│ │
│ on('targetDetected') │
│ ← 设备+窗口+坐标信息 ────── │
│ │
│ 用户确认分享内容 │
│ │
│ ── 传输数据 ─────────────────→ │
│ │ onReceive()
│ │ 内容插入到指定位置
│ on('shareComplete') │
│ │
三、开发者集成------发送端实现
3.1 发送端基础流程
在发送端(如手机端的"画伴梦工厂"应用),精准分享的集成分为以下步骤:
typescript
import { preciseShare } from '@kit.ShareKit';
import { fileIo } from '@kit.CoreFileKit';
async function preciseShareImage(context: UIAbilityContext, imageUri: string): Promise<void> {
// 1. 构建精准分享数据
const data: preciseShare.PreciseShareData = {
records: [
{
utd: 'public.image',
uri: imageUri,
title: '我的涂鸦作品',
thumbnail: await generateThumbnail(imageUri)
}
],
shareMode: preciseShare.PreciseShareMode.SINGLE_FILE
};
// 2. 创建精准分享控制器
const controller = preciseShare.createPreciseShareController(data);
// 3. 监听目标设备检测
controller.on('targetDetected', (targetInfo) => {
console.info(`检测到目标设备: ${targetInfo.deviceName}`);
console.info(`目标窗口: ${targetInfo.windowInfo.bundleName}`);
console.info(`插入坐标: (${targetInfo.coordinate.x}, ${targetInfo.coordinate.y})`);
// 可选择在此处让用户确认
});
// 4. 监听分享完成
controller.on('shareComplete', (result) => {
console.info(`分享完成: ${result.success ? '成功' : '失败'}`);
controller.cancelDetection();
});
// 5. 启动 NFC 检测
await controller.startNfcDetection(context);
}
3.2 用户确认环节
精准分享在检测到目标设备后,默认会在发送端弹出一个确认气泡,显示目标设备名称、应用名称和插入位置预览。用户确认后才会正式传输数据。这是防止误触碰的重要安全机制。
检测到目标设备
┌──────────────────────────────────┐
│ 📱 → 💻 │
│ 将发送到:我的 MateBook │
│ 目标应用:WPS Office │
│ 插入位置:文档第 3 页 │
│ │
│ [确认发送] [取消] │
└──────────────────────────────────┘
3.3 可选的 TargetFilter 配置
如果希望限制分享目标,可在创建控制器时传入过滤条件:
typescript
const filter: preciseShare.ShareTargetFilter = {
allowedBundles: ['com.wps.wpsoffice', 'com.huawei.penboard'],
minWindowWidth: 500
};
const controller = preciseShare.createPreciseShareController(data, filter);
四、开发者集成------接收端实现
4.1 注册精准分享接收处理器
接收端(如平板上的笔记应用)需要在 UIAbility 中注册 PreciseReceiveHandler:
typescript
import { preciseShare } from '@kit.ShareKit';
import { UIAbility, UIAbilityContext } from '@kit.AbilityKit';
export default class NoteAbility extends UIAbility {
private receiveHandler: preciseShare.PreciseReceiveHandler | null = null;
onCreate(): void {
// 注册精准分享处理器
this.receiveHandler = {
onReceive: async (context: UIAbilityContext, data: preciseShare.PreciseReceiveData) => {
// data.coordinate 包含插入坐标
const coord = data.coordinate;
for (const record of data.records) {
if (record.uri) {
// 在坐标位置插入图片/文件
await this.insertContentAtPosition(record.uri, coord);
} else if (record.content) {
// 在坐标位置插入文本
await this.insertTextAtPosition(record.content, coord);
}
}
return { code: 0, message: 'success' };
},
onCoordinate: async (context: UIAbilityContext, coordinate: preciseShare.InsertCoordinate) => {
// 可选:接收坐标信息用于预览
console.info(`收到插入坐标: (${coordinate.x}, ${coordinate.y})`);
}
};
// 将处理器注册到系统
preciseShare.registerReceiveHandler(this.context, this.receiveHandler);
}
onDestroy(): void {
// 注销处理器
if (this.receiveHandler) {
preciseShare.unregisterReceiveHandler(this.context);
this.receiveHandler = null;
}
}
private async insertContentAtPosition(uri: string, coord: preciseShare.InsertCoordinate | undefined): Promise<void> {
// 读取文件内容
const file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
const content = new Uint8Array(fileIo.statSync(file.fd).size);
fileIo.readSync(file.fd, content);
fileIo.closeSync(file);
// 根据坐标将内容插入到编辑器光标位置
if (coord) {
// 精确位置插入
NoteEditor.insertImageAt(content, coord.x, coord.y);
} else {
// 无坐标时追加到文档末尾
NoteEditor.appendImage(content);
}
}
}
4.2 onReceive 的回调参数详解
onReceive 回调是接收端的核心入口,它接收两个参数:
- context :
UIAbilityContext,可用于获取资源、访问文件系统等操作。 - data :
PreciseReceiveData,包含:
typescript
interface PreciseReceiveData {
records: PreciseShareRecord[]; // 分享的内容记录列表
sourceDeviceId: string; // 来源设备的分布式设备 ID
sourceDeviceName?: string; // 来源设备名称(如"我的 Pura 8")
coordinate?: InsertCoordinate; // 插入坐标(关键信息)
}
coordinate 字段的三种状态:
| 状态 | 条件 | 处理方式 |
|---|---|---|
undefined |
目标窗口不支持坐标定位 | 追加到文档末尾或默认位置 |
{ x, y } 有效坐标 |
NFC 准确识别了插入位置 | 直接定位到该坐标插入 |
零坐标 { 0, 0 } |
NFC 触碰点在窗口之外 | 提示用户重新触碰窗口区域 |
4.3 应用声明精准分享能力
接收端应用需要在 module.json5 中声明精准分享能力:
json
{
"module": {
"abilities": [
{
"name": "NoteAbility",
"preciseShareEnabled": true,
"preciseReceiveUtds": ["public.image", "public.text", "public.file"]
}
]
}
}
| 配置项 | 说明 |
|---|---|
preciseShareEnabled |
启用精准分享接收能力 |
preciseReceiveUtds |
声明可接收的数据类型列表,系统据此进行类型匹配 |
五、精准分享 vs. 通用分享------完整对比
5.1 能力对比
| 维度 | systemShare(通用分享) | preciseShare(精准分享) |
|---|---|---|
| 触发方式 | 用户点击分享按钮 | NFC 触碰设备 |
| 目标选择 | 系统分享面板手动选择 | NFC 自动识别设备+窗口+坐标 |
| 内容去向 | 发送到目标应用 | 插入到目标窗口的指定位置 |
| 坐标感知 | ❌ 不支持 | ✅ 支持像素级坐标 |
| 用户操作步骤 | 3-4 步(点击→选择→确认) | 1 步(触碰) |
| 数据流 | 应用→系统→目标应用 | 应用→系统→目标窗口 |
| UI 交互 | 全屏分享面板 | 轻量确认气泡 |
| 适用场景 | 通用内容分享 | 精准内容插入 |
| 跨设备支持 | 基于分布式软总线 | 基于 NFC + 分布式软总线 |
| API 版本 | API 9+ | API 26+(HarmonyOS 7) |
5.2 场景对比
通用分享(systemShare) → 适合"发给某人"
手机 ──→ 选择微信 ──→ 发送给好友 ──→ 好友自行处理
精准分享(preciseShare) → 适合"插到某处"
手机碰一下电脑 ──→ 图片直接插入到 WPS 文档光标位置
5.3 互补关系
两种分享方式并非替代关系,而是互补关系:
- systemShare 适合"社交分享"场景------不知道目标是谁、不知道目标用什么应用处理内容。
- preciseShare 适合"生产力衔接"场景------明确知道要把内容放到哪里,追求最短路径。
在"画伴梦工厂"中,两者可以共存:
typescript
// 用户可选择不同的分享方式
async function shareDrawing(context: UIAbilityContext, drawingUri: string): Promise<void> {
if (hasNfcCapability() && userWantsPreciseShare) {
// 精准分享:碰一碰插入到目标设备
await preciseShareImage(context, drawingUri);
} else {
// 通用分享:发送到社交应用
await systemShareVideo(context, drawingUri);
}
}
六、应用场景------跨设备素材插入
6.1 手机 → 电脑:涂鸦插入文档
场景:孩子用手机在"画伴梦工厂"中完成了一幅涂鸦,家长希望将这张涂鸦插入到电脑上的成长记录文档中。
操作流程:
- 在手机上打开涂鸦作品,选择"碰一碰分享"
- 将手机 NFC 区域触碰电脑屏幕上 WPS 文档中想要插入的位置
- 手机上弹出确认气泡,显示"将发送到:我的 MateBook - WPS Office"
- 点击确认,涂鸦图片直接插入到 WPS 文档中触碰位置所在的行
整个过程无需任何文件传输和手动插入步骤,从触碰完成到图片出现在文档中,耗时不超过 2 秒。
6.2 手机 → 平板:绘画素材跨设备引用
场景:孩子在平板上使用"画伴梦工厂"创作新的画作,想要引用手机上之前画过的一个角色素材。
操作流程:
- 手机上打开角色素材图片
- 将手机 NFC 触碰平板上画布的目标位置
- 素材图片直接插入到画布指定坐标处
- 孩子可以围绕插入的素材继续创作
这种"碰一下即用"的模式,极大降低了跨设备素材引用的摩擦成本。在传统模式下,用户需要经历"发送文件→接收文件→保存到相册→从相册导入"的繁琐流程,而精准分享将其简化为仅需一次触碰。
6.3 更多场景一览
| 发送端 | 接收端 | 插入内容 | 操作步骤 |
|---|---|---|---|
| 手机图库 | 平板备忘录 | 照片 | 碰一下 → 确认 → 插入 |
| 手机相册 | 电脑 PPT | 截图 | 碰一下 → 确认 → 插入 |
| 平板画布 | 手机便签 | 涂鸦截图 | 碰一下 → 确认 → 插入 |
| 手机文件管理器 | 平板 WPS | PDF 文件 | 碰一下 → 确认 → 插入为附件 |
七、在项目中的应用------跨设备绘画协作
7.1 素材跨设备精准插入
在"画伴梦工厂"中,精准分享可用于构建高效的跨设备绘画协作流程:
typescript
class CrossDeviceDrawingService {
static async shareDrawingToTarget(
context: UIAbilityContext,
drawingData: DrawingData,
targetDevice: string
): Promise<void> {
// 导出当前画布为图片
const imageUri = await exportDrawingToTempFile(drawingData);
// 构建精准分享数据
const shareData: preciseShare.PreciseShareData = {
records: [
{
utd: 'public.image',
uri: imageUri,
title: drawingData.title,
thumbnail: drawingData.thumbnail
},
{
utd: 'public.json',
content: JSON.stringify({
layers: drawingData.layers,
canvasSize: drawingData.canvasSize,
backgroundColor: drawingData.backgroundColor
}),
title: '图层数据'
}
],
shareMode: preciseShare.PreciseShareMode.MULTI_FILE
};
// 启动精准分享
const controller = preciseShare.createPreciseShareController(shareData);
controller.on('targetDetected', (info) => {
console.info(`目标检测: ${JSON.stringify(info)}`);
});
await controller.startNfcDetection(context);
}
}
这种实现允许一次触碰同时传输图片素材 和图层结构化数据,接收端应用可以根据结构化数据在画布上重建图层结构,而非仅仅插入一张静态图片。
7.2 接收端画布坐标映射
在接收端平板的"画伴梦工厂"应用中,需要对收到的坐标做进一步映射------将窗口坐标转换为画布坐标:
typescript
function mapToCanvasCoordinate(
windowCoord: { x: number, y: number },
canvasViewPort: { x: number, y: number, width: number, height: number },
canvasTotalSize: { width: number, height: number },
currentScale: number,
scrollOffset: { x: number, y: number }
): { x: number, y: number } {
// 判断触碰点是否在画布视口内
const relX = windowCoord.x - canvasViewPort.x;
const relY = windowCoord.y - canvasViewPort.y;
if (relX < 0 || relY < 0 ||
relX > canvasViewPort.width || relY > canvasViewPort.height) {
throw new Error('触碰点在画布区域外');
}
// 考虑缩放和滚动偏移,计算画布逻辑坐标
const canvasX = relX / currentScale + scrollOffset.x;
const canvasY = relY / currentScale + scrollOffset.y;
// 边界检查
return {
x: Math.max(0, Math.min(canvasX, canvasTotalSize.width)),
y: Math.max(0, Math.min(canvasY, canvasTotalSize.height))
};
}
这一坐标映射逻辑确保了:无论用户在画布的什么缩放级别、什么滚动位置触碰,素材都能被精确插入到用户期望的画布坐标处。
7.3 协作场景体验
手机(素材源) 平板(目标画布)
│ │
│ 打开历史涂鸦素材 │ 打开新画布,缩放到合适位置
│ │
│ 点击"碰一碰分享" │
│ │
│ ─── NFC 触碰 ───────────────────→ │
│ │
│ 确认气泡弹出 │ 收到素材 + 坐标
│ 用户点击确认 │ 坐标映射到画布
│ │ 素材插入到指定位置
│ ── "分享成功" ──────────────────→ │
│ │
│ │ 画布显示插入的素材
│ │ 可继续编辑、调整
八、隐私与安全
8.1 用户确认机制
精准分享在隐私设计上遵循**"每次分享都需用户确认"**的原则。整个流程中的确认点如下:
NFC 触碰检测
│
▼
系统识别目标设备+窗口+坐标
│
▼
发送端弹出确认气泡 ───→ 展示:目标设备、目标应用、插入位置预览
│ │
├── 用户点击"确认" ───→ 传输数据
│
└── 用户点击"取消" ───→ 流程终止,不传输数据
这意味着,即使手机意外触碰到了目标设备,只要用户不确认,系统绝不会传输任何数据。这一机制有效防止了误触碰导致的数据泄露。
8.2 数据传输安全
精准分享的数据传输沿用了 HarmonyOS 分布式软总线的安全通道:
- 端到端加密:数据在发送端加密,仅在接收端解密,中间节点无法读取内容
- 单次授权:每次触碰产生一个临时会话密钥,用完即销毁
- 设备可信链:仅同一华为账号下的信任设备可参与精准分享
8.3 隐私数据保护
| 场景 | 保护措施 |
|---|---|
| 坐标信息 | 仅透传触碰坐标,不记录屏幕内容 |
| 窗口信息 | 仅传递 bundleName 和 windowId,不传递窗口内具体数据 |
| 设备标识 | 使用分布式匿名设备 ID,非真实硬件标识 |
| 分享记录 | 系统不留存分享内容日志 |
8.4 开发者隐私责任
作为开发者,在实现 onReceive 回调时应注意:
- 最小数据原则 :仅处理
PreciseReceiveData中需要的数据字段 - 不持久化共享数据:除非用户明确保存,不应将分享内容自动写入持久化存储
- 来源透明:在 UI 上标注内容的来源设备,让用户感知数据流入
- 可撤销:提供"撤销插入"的入口,允许用户撤回刚才插入的内容
九、多设备生态价值
9.1 从"文件传输"到"能力协同"
精准分享代表着鸿蒙多设备协同的一次范式跃迁。它不再将跨设备交互理解为"文件传输",而是理解为**"能力协同"**:
文件传输时代:
设备 A ──→ 传输文件 ──→ 设备 B ──→ 手动打开/插入
能力协同时代(精准分享):
设备 A ──→ 碰一下 ──→ 设备 B ──→ 内容直达目的地
这种转变的核心价值在于:用户不需要学习"跨设备的操作流程",只需要延续同一设备上"复制粘贴"的直觉------碰一碰就是将内容从一处搬到另一处的最自然方式。
9.2 在"画伴梦工厂"中的生态定位
在"画伴梦工厂"的多设备使用场景中,精准分享可以成为连接不同设备的桥梁:
┌─────────────────────────────────────────────────────┐
│ 家庭创作生态 │
│ │
│ 手机(素材采集) │
│ ├── 拍照/相册导入素材 │
│ └── 碰一碰 → 发送到平板画布 │
│ │
│ 平板(核心创作) │
│ ├── Canvas 涂鸦 + 3D 模型渲染 │
│ ├── 接收手机素材(碰一碰) │
│ └── 碰一碰 → 发送作品到电脑排版 │
│ │
│ 电脑(排版输出) │
│ ├── WPS 文档排版 │
│ ├── 接收平板作品(碰一碰) │
│ └── 最终输出打印/分享 │
└─────────────────────────────────────────────────────┘
在这个生态中,精准分享扮演了零摩擦的素材传输通道角色------用户在不同设备间切换时,不再需要思考"怎么把文件传过去",只需碰一碰即可。
9.3 与其他鸿蒙 7 新特性的协同
精准分享可以与系列中其他鸿蒙 7 新特性协同,创造更丰富的体验:
| 配合特性 | 协同效果 |
|---|---|
| 分布式软总线 2.0(7.15) | 精准分享依赖软总线 2.0 的低延迟(8ms)和多设备协同(16 设备)能力 |
| 标准悬浮窗(7.10) | 接收端以悬浮窗形式展示接收的素材预览,用户拖拽到目标位置 |
| 闪控球(7.11) | 发送端通过闪控球快速启动精准分享,减少操作步骤 |
| Core File Kit 沙箱共享(7.16) | 精准分享接收的内容直接进入应用沙箱,无需额外的文件导入步骤 |
十、开发注意事项与最佳实践
10.1 NFC 硬件检测
并非所有设备都配备 NFC 硬件,启动精准分享前应进行能力检测:
typescript
function hasNfcCapability(): boolean {
return canIUse('SystemCapability.Communication.NFC');
}
10.2 设备配对要求
精准分享要求发送端和接收端满足以下条件:
- 登录同一华为账号
- 设备已开启蓝牙和 Wi-Fi(用于分布式软总线通信)
- 设备 NFC 功能已开启
- 目标应用已声明
preciseShareEnabled
10.3 错误处理
由于精准分享涉及硬件(NFC)、网络(分布式软总线)、软件(窗口管理)多个层次,错误处理尤为重要:
typescript
async function startPreciseWithRetry(
context: UIAbilityContext,
data: preciseShare.PreciseShareData,
maxRetries: number = 3
): Promise<void> {
let lastError: Error | null = null;
for (let i = 0; i < maxRetries; i++) {
try {
const controller = preciseShare.createPreciseShareController(data);
await controller.startNfcDetection(context);
return; // 成功
} catch (error) {
lastError = error as Error;
// 等待 1 秒后重试
await new Promise(r => setTimeout(r, 1000));
}
}
// 所有重试均失败,降级到通用分享
console.error(`精准分享失败,降级到通用分享: ${lastError?.message}`);
await fallbackToSystemShare(context, data);
}
10.4 最佳实践清单
- 始终提供 fallback:当 NFC 检测失败或设备不支持时,自动降级到通用分享
- 确认气泡内容清晰:在确认气泡中展示目标设备名称、应用图标和内容预览
- 坐标边界处理:接收端在插入内容前,验证坐标是否在有效范围内
- 反馈及时:分享过程中提供进度反馈,成功或失败都应有明确提示
- 内容适配:根据接收端窗口尺寸调整插入内容的大小,避免超出窗口边界
- 测试覆盖:在不同设备组合(手机→平板、手机→电脑)上测试坐标映射精度
总结
碰一碰精准分享是 HarmonyOS 7 在跨设备协同领域的一次重要创新。它将 NFC 触碰与分布式窗口管理深度结合,创造了一种"碰一下,内容直达目的地"的全新交互范式。
| 知识点 | 说明 |
|---|---|
| 技术原理 | NFC 触碰实现设备识别、窗口识别、坐标识别的三重精准定位 |
| 坐标映射 | 触碰物理坐标 → 屏幕坐标 → 窗口坐标 → 应用内坐标(含滚动和缩放补偿) |
| Share Kit 升级 | API 26 新增 preciseShare 子模块,提供 PreciseShareController、PreciseReceiveHandler 等接口 |
| 发送端集成 | createPreciseShareController → startNfcDetection → 确认气泡 → 传输 |
| 接收端集成 | 注册 PreciseReceiveHandler → onReceive 处理坐标和内容 → 插入到指定位置 |
| 与 systemShare 对比 | 通用分享适合"发给某人"(3-4 步操作),精准分享适合"插到某处"(1 步操作) |
| 隐私安全 | 每次分享需用户确认、端到端加密、坐标不记录屏幕内容、数据用完即销毁 |
| 项目应用 | 素材跨设备精准插入、画布坐标映射、一次触碰传输图片+图层数据 |
| 生态价值 | 从"文件传输"到"能力协同",零摩擦跨设备素材流转 |
精准分享让我们看到,跨设备协同的终极形态不应该让用户感知到"设备"的存在------用户只需要知道"我要把内容放到这里",剩下的交给系统去完成。碰一碰,就是最自然的"放到这里"。
参考源码
本文内容基于 HarmonyOS 7(API 26)Share Kit 开发文档:
@kit.ShareKit---preciseShare精准分享模块@kit.AbilityKit---UIAbility生命周期与窗口管理@kit.CoreFileKit---fileIo文件读写操作
相关系列文章:
- 第 4.4 篇:跨设备分享------systemShare 集成(通用分享对比基础)
- 第 7.15 篇:分布式软总线 2.0------多设备协同新范式(精准分享的底层通信基础)