HarmonyOS 7 碰一碰实战:手机轻触电脑,精准插入图片到指定位置

引言

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全场景协同的新体验。碰一碰解决"传入"的问题,闪控窗解决"展示"的问题,互动卡片解决"触达"的问题------一套完整的跨设备交互链路。

相关推荐
黑臂麒麟39 分钟前
Harmony鸿蒙实战应用5:随手账本——搜索筛选与分类统计
华为·app·arkts·鸿蒙
2501_9197490343 分钟前
华为鸿蒙免费自拍对比APP—小羊自拍
华为·harmonyos·鸿蒙
贾伟康44 分钟前
【时光清单|02】HarmonyOS ArkTS 习惯打卡实战:处理连续天数、补签和日期切换
harmonyos·arkts·数据持久化·日期处理·习惯打卡
大锅盖13 小时前
围绕夜航深蓝与霓虹青的跨境画卷构建 HarmonyOS ArkUI 出境旅行向导平台
华为·harmonyos
jike_202612 小时前
iPhone采访录音同时拍现场照片的APP:图片音频同步记录实测
笔记·智能手机·音视频·语音识别
骐骥112 小时前
学习:使用postMessage()建立应用侧与前端页面的数据通道
harmonyos·鸿蒙·jsbridge·postmessage·数据通道
代码方舟18 小时前
零信任架构实战:基于天远手机携号转网V即时版构建自动化营销风控网关
人工智能·智能手机·架构·自动化
HwJack2018 小时前
鸿蒙开发ArkData 全景与选型决策:三种存储到底用哪个
华为·harmonyos
czhm5719 小时前
基于 HarmonyOS ArkTS API 24,工具函数抽离业务计算逻辑,状态颜色判断解耦组件代码
harmonyos·arkts