引言
HarmonyOS 7 的全场景碰一碰 · 精准分享是一个让人眼前一亮的特性------手机轻触电脑或平板的屏幕,就能识别目标窗口和触碰坐标,把图片等素材精准插入到指定位置。
以前要靠"文件传输助手"中转,现在碰一下就搞定。
一、能力概述
#mermaid-svg-xG8j2EXdUt1Q0hFm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xG8j2EXdUt1Q0hFm .error-icon{fill:#552222;}#mermaid-svg-xG8j2EXdUt1Q0hFm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xG8j2EXdUt1Q0hFm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .marker.cross{stroke:#333333;}#mermaid-svg-xG8j2EXdUt1Q0hFm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xG8j2EXdUt1Q0hFm p{margin:0;}#mermaid-svg-xG8j2EXdUt1Q0hFm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster-label text{fill:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster-label span{color:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster-label span p{background-color:transparent;}#mermaid-svg-xG8j2EXdUt1Q0hFm .label text,#mermaid-svg-xG8j2EXdUt1Q0hFm span{fill:#333;color:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .node rect,#mermaid-svg-xG8j2EXdUt1Q0hFm .node circle,#mermaid-svg-xG8j2EXdUt1Q0hFm .node ellipse,#mermaid-svg-xG8j2EXdUt1Q0hFm .node polygon,#mermaid-svg-xG8j2EXdUt1Q0hFm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .rough-node .label text,#mermaid-svg-xG8j2EXdUt1Q0hFm .node .label text,#mermaid-svg-xG8j2EXdUt1Q0hFm .image-shape .label,#mermaid-svg-xG8j2EXdUt1Q0hFm .icon-shape .label{text-anchor:middle;}#mermaid-svg-xG8j2EXdUt1Q0hFm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .rough-node .label,#mermaid-svg-xG8j2EXdUt1Q0hFm .node .label,#mermaid-svg-xG8j2EXdUt1Q0hFm .image-shape .label,#mermaid-svg-xG8j2EXdUt1Q0hFm .icon-shape .label{text-align:center;}#mermaid-svg-xG8j2EXdUt1Q0hFm .node.clickable{cursor:pointer;}#mermaid-svg-xG8j2EXdUt1Q0hFm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .arrowheadPath{fill:#333333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xG8j2EXdUt1Q0hFm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xG8j2EXdUt1Q0hFm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xG8j2EXdUt1Q0hFm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster text{fill:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm .cluster span{color:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xG8j2EXdUt1Q0hFm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xG8j2EXdUt1Q0hFm rect.text{fill:none;stroke-width:0;}#mermaid-svg-xG8j2EXdUt1Q0hFm .icon-shape,#mermaid-svg-xG8j2EXdUt1Q0hFm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xG8j2EXdUt1Q0hFm .icon-shape p,#mermaid-svg-xG8j2EXdUt1Q0hFm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xG8j2EXdUt1Q0hFm .icon-shape .label rect,#mermaid-svg-xG8j2EXdUt1Q0hFm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xG8j2EXdUt1Q0hFm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xG8j2EXdUt1Q0hFm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xG8j2EXdUt1Q0hFm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 手机触碰电脑屏幕
识别触碰坐标
定位目标窗口
确定窗口内插入位置
传输素材并插入
核心能力:
- 触碰识别:识别手机触碰电脑/平板的物理位置
- 窗口定位:获取该位置下的目标窗口(浏览器、笔记、文档等)
- 坐标映射:将物理坐标映射到窗口内的逻辑坐标
- 精准插入:将素材插入到指定位置
二、使用场景
场景1:写文章插图片
正在电脑上写文档,手机拍了一张照片------碰一下电脑屏幕,图片直接插入到光标位置。
场景2:设计协同
设计师在平板上画了张图,碰一下设计稿,图片自动插入到触碰位置。
场景3:会议记录
手机拍的白板照片,碰一下会议纪要文档,图片插入对应位置。
三、开发接入
3.1 声明权限
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
},
{
"name": "ohos.permission.NEARBY_DEVICE"
}
]
}
}
3.2 接收碰一碰事件
typescript
import { BusinessError } from '@kit.BasicServicesKit';
import { tap } from '@kit.DistributedServiceKit';
// 注册碰一碰事件监听
tap.on('tapEvent', (event: tap.TapEvent) => {
console.log('收到碰一碰事件');
console.log('设备ID:', event.deviceId);
console.log('触碰坐标:', event.x, event.y);
// 获取目标窗口信息
const windowInfo = event.targetWindow;
console.log('目标窗口:', windowInfo.windowName);
console.log('窗口位置:', windowInfo.rect);
// 获取传输的数据
const data = event.data;
if (data.type === 'image') {
// 处理图片素材
handleImageInsertion(data.uri, event.x, event.y);
}
});
function handleImageInsertion(imageUri: string, x: number, y: number) {
console.log(`将图片 ${imageUri} 插入到 (${x}, ${y}) 位置`);
// 实际插入逻辑取决于目标应用
}
3.3 发送碰一碰(手机端)
typescript
// 手机端发送数据
import { tap } from '@kit.DistributedServiceKit';
async function shareImageByTap(imagePath: string) {
try {
await tap.share({
type: 'image',
uri: imagePath,
description: '分享图片'
});
console.log('碰一碰分享成功');
} catch (e) {
console.error('分享失败:', (e as BusinessError).message);
}
}
四、多形态服务窗口
HarmonyOS 7 还新增了多形态服务窗口,与碰一碰联动使用效果更佳。
4.1 窗口类型
| 窗口类型 | 说明 | 使用场景 |
|---|---|---|
| 悬浮窗 | 常驻显示,可拖动 | 视频浮窗播放 |
| 闪控窗 | 悬浮状态栏,侧边暂存 | 计时器、音乐控制 |
| 分屏窗 | 应用分屏显示 | 多任务并行 |
4.2 创建悬浮窗
typescript
import { window } from '@kit.ArkUI';
async function createFloatingWindow() {
const ctx = getContext(this);
// 创建悬浮窗
const floatWin = await window.createWindow(ctx, {
type: window.WindowType.TYPE_FLOAT, // 悬浮窗类型
width: 400,
height: 300
});
// 设置悬浮窗内容
floatWin.setUIContent('pages/FloatContent');
// 显示悬浮窗
await floatWin.show();
}
五、多窗互动卡片
互动卡片也是鸿蒙7的新能力------摇一摇手机触发卡片效果。
typescript
// 卡片侧:监听摇一摇事件
import { formManager } from '@kit.FormKit';
// 在卡片FormAbility中
onFormEvent(formId: string, event: string) {
if (event === 'shake') {
// 摇一摇触发:卡片静态→动态
this.updateForm(formId, {
isAnimating: true,
animationType: 'parallax' // 前景元素出框效果
});
// 3秒后恢复静态
setTimeout(() => {
this.updateForm(formId, { isAnimating: false });
}, 3000);
}
}
六、闪控窗:常驻悬浮状态
typescript
// 创建闪控窗
import { window } from '@kit.ArkUI';
async function createFlashWindow() {
const flashWin = await window.createWindow(getContext(this), {
type: window.WindowType.TYPE_FLOAT,
width: 200,
height: 64,
isFlashWindow: true // 闪控窗模式
});
flashWin.setUIContent('pages/FlashControl');
await flashWin.show();
// 闪控窗特性:可拖动、侧边暂存、与闪控球一键切换
flashWin.on('dragEvent', (x, y) => {
// 拖到侧边时自动暂存
if (x < 20) {
flashWin.dockToSide('left');
}
});
}
七、最佳实践
✅ 碰一碰适配建议
- 注册多类型数据:同时支持 image/text/file 类型
- 坐标转换:触碰物理坐标 → 窗口内逻辑坐标,需要考虑缩放比例
- 用户确认:重要操作前加确认对话框,防止误碰
⚠️ 注意事项
- 只支持近距离:手机与设备需要在物理触碰范围内
- 权限敏感:需要用户授权分布式数据同步权限
- 窗口识别:只有支持的应用窗口才会被识别为目标
总结
#mermaid-svg-abh41QvUFLGm37RS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-abh41QvUFLGm37RS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-abh41QvUFLGm37RS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-abh41QvUFLGm37RS .error-icon{fill:#552222;}#mermaid-svg-abh41QvUFLGm37RS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-abh41QvUFLGm37RS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-abh41QvUFLGm37RS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-abh41QvUFLGm37RS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-abh41QvUFLGm37RS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-abh41QvUFLGm37RS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-abh41QvUFLGm37RS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-abh41QvUFLGm37RS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-abh41QvUFLGm37RS .marker.cross{stroke:#333333;}#mermaid-svg-abh41QvUFLGm37RS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-abh41QvUFLGm37RS p{margin:0;}#mermaid-svg-abh41QvUFLGm37RS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-abh41QvUFLGm37RS .cluster-label text{fill:#333;}#mermaid-svg-abh41QvUFLGm37RS .cluster-label span{color:#333;}#mermaid-svg-abh41QvUFLGm37RS .cluster-label span p{background-color:transparent;}#mermaid-svg-abh41QvUFLGm37RS .label text,#mermaid-svg-abh41QvUFLGm37RS span{fill:#333;color:#333;}#mermaid-svg-abh41QvUFLGm37RS .node rect,#mermaid-svg-abh41QvUFLGm37RS .node circle,#mermaid-svg-abh41QvUFLGm37RS .node ellipse,#mermaid-svg-abh41QvUFLGm37RS .node polygon,#mermaid-svg-abh41QvUFLGm37RS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-abh41QvUFLGm37RS .rough-node .label text,#mermaid-svg-abh41QvUFLGm37RS .node .label text,#mermaid-svg-abh41QvUFLGm37RS .image-shape .label,#mermaid-svg-abh41QvUFLGm37RS .icon-shape .label{text-anchor:middle;}#mermaid-svg-abh41QvUFLGm37RS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-abh41QvUFLGm37RS .rough-node .label,#mermaid-svg-abh41QvUFLGm37RS .node .label,#mermaid-svg-abh41QvUFLGm37RS .image-shape .label,#mermaid-svg-abh41QvUFLGm37RS .icon-shape .label{text-align:center;}#mermaid-svg-abh41QvUFLGm37RS .node.clickable{cursor:pointer;}#mermaid-svg-abh41QvUFLGm37RS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-abh41QvUFLGm37RS .arrowheadPath{fill:#333333;}#mermaid-svg-abh41QvUFLGm37RS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-abh41QvUFLGm37RS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-abh41QvUFLGm37RS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-abh41QvUFLGm37RS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-abh41QvUFLGm37RS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-abh41QvUFLGm37RS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-abh41QvUFLGm37RS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-abh41QvUFLGm37RS .cluster text{fill:#333;}#mermaid-svg-abh41QvUFLGm37RS .cluster span{color:#333;}#mermaid-svg-abh41QvUFLGm37RS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-abh41QvUFLGm37RS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-abh41QvUFLGm37RS rect.text{fill:none;stroke-width:0;}#mermaid-svg-abh41QvUFLGm37RS .icon-shape,#mermaid-svg-abh41QvUFLGm37RS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-abh41QvUFLGm37RS .icon-shape p,#mermaid-svg-abh41QvUFLGm37RS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-abh41QvUFLGm37RS .icon-shape .label rect,#mermaid-svg-abh41QvUFLGm37RS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-abh41QvUFLGm37RS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-abh41QvUFLGm37RS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-abh41QvUFLGm37RS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 手机触碰
tap.on监听事件
获取坐标+窗口+数据
精准插入目标位置
闪控窗/悬浮窗
提供持续交互
碰一碰 + 闪控窗 + 互动卡片,三者构成了鸿蒙7全场景协同的新体验。碰一碰解决"传入"的问题,闪控窗解决"展示"的问题,互动卡片解决"触达"的问题------一套完整的跨设备交互链路。