前言

在万物互联的时代,设备间的无缝协同已成为用户体验的核心。鸿蒙操作系统作为面向全场景的分布式操作系统,其碰一碰分享功能正是这一理念的典型体现——两台设备轻轻一碰,图片、链接、文件便能瞬间完成跨端传输,无需加好友、无需扫码、无需等待配对。

本文将从技术原理、环境准备、开发流程、源码解析、卡片设计、进阶技巧到常见问题,全方位讲解鸿蒙碰一碰分享的开发实践,帮助开发者快速掌握这一能力的集成与应用。

第一章 技术原理

1.1 什么是碰一碰分享

碰一碰分享是华为分享基于 Share Kit 推出的跨端分享能力,支持用户通过设备轻触发起跨端分享,可实现图片传输、Wi-Fi共享、链接分享等功能。开发者只需调用系统 API 传入所需参数拉起对应分享卡片模板即可,无需对 UI 进行设计。

1.2 核心技术架构

碰一碰分享基于以下核心技术:

1. Share Kit(分享服务)

Share Kit 为应用提供文本、图片、视频等内容跨应用、跨端分享能力。应用把需要分享的内容和预览样式配置给 Share Kit,Share Kit 根据不同的场景构建分享面板或预览界面。

2. 近场通信(NFC)

NFC 凭借超低功耗、高安全性和触碰即连的特性,在设备发现和快速握手场景中扮演关键角色。两台设备轻触时,NFC 完成"握手"和通道建立。

3. 分布式软总线

近场快传服务基于分布式软总线,可实现近距离 100MB/s+ 的传输速度。

1.3 运行机制

碰一碰分享的核心业务流程可概括为四步:

  1. 注册:应用在可分享的页面注册碰一碰事件(knockShare

  2. 触发:用户将手机与对端设备轻碰,系统发现设备后触发回调

  3. 发送:应用在回调中构造分享数据并发送

  4. 清理:离开可分享页面时解除事件注册

Share Kit 的处理机制如下:

  • 任意一端设备不支持碰一碰能力时,轻碰无任何响应

  • 宿主应用无法获得分享结果,Share Kit 会通过系统通知消息告知用户对端接收或拒绝

1.4 设备间的信任与安全

从 HarmonyOS NEXT 5.0.0.123 SP16 开始,碰一碰分享在发送端和接收端都会展示对方的身份信息:

  • 如果对端已登录华为账号,展示对方的账号昵称和头像

  • 如果对端未登录华为账号,则展示设备信息

第二章 开发准备

2.1 环境要求

在开始开发之前,需要确保满足以下环境要求:

项目 要求
设备类型 当前仅支持手机碰手机
系统版本 双端需 HarmonyOS NEXT 5.0.0.102 SP6 及以上版本
开发环境 DevEco Studio NEXT Beta1 及以上版本
API 版本 API 12 及以上

2.2 触发条件

手机应用发起碰一碰分享时,需要满足以下条件:

  • 双端设备处于亮屏、解锁状态

  • 双端设备均已开启华为分享服务(系统默认开启)

  • 如果用户已手动关闭华为分享服务开关,轻碰事件触发时会收到系统通知提示开启

2.3 能力检测

在运行时检测设备是否支持碰一碰分享能力:

typescript

if (canIUse('SystemCapability.Collaboration.HarmonyShare')) {
  // 支持碰一碰分享的能力
  // 可以注册碰一碰监听事件
} else {
  // 设备不支持碰一碰分享,可降级到其他分享方式
}

2.4 权限配置

在 module.json5 配置文件中声明必要的权限:

json

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": ["phone", "tablet"],
    "requestedPermissions": [
      {
        "name": "ohos.permission.NFC_TAG",
        "reason": "$string:permission_nfc_tag_reason",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.NFC_P2P",
        "reason": "$string:permission_nfc_p2p_reason",
        "usedScene": {
          "when": "$string:permission_nfc_p2p_when"
        }
      },
      {
        "name": "ohos.permission.READ_MEDIA",
        "reason": "$string:permission_read_media_reason"
      }
    ]
  }
}

2.5 App Linking 配置(可选但推荐)

碰一碰分享要实现直达应用,应用需接入 App Linking 以确保端到端完整的体验。

在 AppGallery Connect 中配置

  1. 登录 AppGallery Connect

  2. 点击"开发与服务"

  3. 创建 App Linking 链接

  4. 配置深度链接地址和备用网址

配置应用路由:在 module.json5 中声明 URI 路由:

json

{
  "module": {
    "abilities": [{
      "name": "EntryAbility",
      "skills": [{
        "actions": ["action.system.home"],
        "entities": ["entity.system.home"],
        "uris": [{
          "scheme": "https",
          "host": "yourdomain.com",
          "path": "/video"
        }]
      }]
    }]
  }
}

第三章 开发流程详解

3.1 整体流程概览

text

┌─────────────────────────────────────────────────────────────────────┐
│                        碰一碰分享开发流程                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    │
│  │ 1.导入   │───▶│ 2.判断   │───▶│ 3.注册   │───▶│ 4.实现   │    │
│  │ 模块     │    │ 能力     │    │ 监听     │    │ 回调     │    │
│  └──────────┘    └──────────┘    └──────────┘    └──────────┘    │
│                                                          │         │
│                                                          ▼         │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    │
│  │ 7.取消   │◀───│ 6.发送   │◀───│ 5.构造   │◀───│          │    │
│  │ 监听     │    │ 分享     │    │ 分享数据 │    │          │    │
│  └──────────┘    └──────────┘    └──────────┘    └──────────┘    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3.2 步骤一:导入相关模块

在开发过程中,首先需要导入以下模块:

typescript

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

各模块的作用:

  • @kit.ArkData:提供统一数据类型(UTD)定义

  • @kit.ShareKit:提供系统分享和碰一碰分享的 API

  • @kit.CoreFileKit:提供文件 URI 处理能力

3.3 步骤二:定义碰一碰分享事件回调

当碰一碰事件触发时,系统会调用回调函数,开发者在此构造分享数据并发送:

typescript

/**
 * 碰一碰触发回调
 * @param sharableTarget 分享目标对象
 */
private immersiveCallback(sharableTarget: harmonyShare.SharableTarget) {
  // 获取上下文
  const contextFaker: Context = getContext(this);
  
  // 构造图片文件路径(示例:从沙盒目录读取)
  let filePath = contextFaker.filesDir + '/exampleKnock1.jpg';
  
  // 构造分享数据
  let shareData: systemShare.SharedData = new systemShare.SharedData({
    // 数据类型:超链接
    utd: utd.UniformDataType.HYPERLINK,
    // 分享内容:可以是链接、文本等
    content: 'https://sharekitdemo.drcn.agconnect.link/ZB3p',
    // 预览图:用于生成分享卡片
    thumbnailUri: fileUri.getUriFromPath(filePath),
    // 卡片标题
    title: '碰一碰分享卡片标题',
    // 卡片描述
    description: '碰一碰分享卡片描述'
  });
  
  // 发起碰一碰分享
  sharableTarget.share(shareData);
}

关键注意事项

收到碰一碰分享事件回调后,需尽快调用 sharableTarget.share() 方法发起分享,超过3秒可能会失败

3.4 步骤三:注册碰一碰分享监听事件

当进入可分享页面时,使用 harmonyShare.on() 方法注册碰一碰监听事件:

typescript

/**
 * 注册碰一碰分享监听事件
 */
private immersiveListening() {
  harmonyShare.on('knockShare', this.immersiveCallback);
}

3.5 步骤四:取消碰一碰分享监听事件

当离开可分享页面(包括应用退至后台等场景)时,使用 harmonyShare.off() 方法取消碰一碰监听事件:

typescript

/**
 * 取消碰一碰分享监听事件
 */
private immersiveDisablingListening() {
  harmonyShare.off('knockShare', this.immersiveCallback);
}

3.6 步骤五:生命周期管理

在页面的生命周期中正确管理监听事件的注册和取消:

typescript

// 页面显示时注册监听
onPageShow(): void {
  this.immersiveListening();
}

// 页面隐藏时取消监听(包括应用退至后台)
onPageHide(): void {
  this.immersiveDisablingListening();
}

// 组件销毁时确保取消监听
aboutToDisappear(): void {
  this.immersiveDisablingListening();
}

重要提醒:离开可分享页面时必须取消监听,避免与其他应用产生碰一碰数据传输冲突。

第四章 完整源码解析

4.1 完整示例代码

以下是一个完整的碰一碰分享实现示例:

typescript

// VideoPlay.ets - 视频播放页面(包含碰一碰分享功能)

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

@Entry
@Component
struct VideoPlayPage {
  @State videoTitle: string = '精彩视频';
  @State videoDescription: string = '分享这个视频给朋友';
  @State shareLink: string = '';
  
  // 视频数据
  private videoData: VideoData = new VideoData();
  
  aboutToAppear(): void {
    // 页面加载时获取视频数据
    this.videoData = router.getParams() as VideoData;
    if (this.videoData) {
      this.videoTitle = this.videoData.title;
      this.videoDescription = this.videoData.description;
      this.shareLink = this.videoData.shareUrl;
    }
  }
  
  onPageShow(): void {
    // 页面显示时注册碰一碰监听
    this.immersiveListening();
  }
  
  onPageHide(): void {
    // 页面隐藏时取消碰一碰监听
    this.immersiveDisablingListening();
  }
  
  aboutToDisappear(): void {
    // 组件销毁时确保取消监听
    this.immersiveDisablingListening();
  }
  
  /**
   * 碰一碰触发回调
   */
  private immersiveCallback = (sharableTarget: harmonyShare.SharableTarget): void => {
    try {
      const context = getContext(this);
      
      // 获取视频封面图路径
      let thumbnailPath = context.filesDir + '/thumbnail_' + this.videoData.id + '.jpg';
      
      // 构造分享数据
      let shareData: systemShare.SharedData = new systemShare.SharedData({
        utd: utd.UniformDataType.HYPERLINK,
        content: this.shareLink,  // App Linking 链接
        thumbnailUri: fileUri.getUriFromPath(thumbnailPath),
        title: this.videoTitle,
        description: this.videoDescription
      });
      
      // 发起分享
      sharableTarget.share(shareData);
      
      console.info('碰一碰分享已发起');
    } catch (error) {
      console.error('碰一碰分享失败:', error);
    }
  };
  
  /**
   * 注册碰一碰分享监听事件
   */
  private immersiveListening(): void {
    try {
      // 先检测设备是否支持
      if (!canIUse('SystemCapability.Collaboration.HarmonyShare')) {
        console.warn('当前设备不支持碰一碰分享');
        return;
      }
      harmonyShare.on('knockShare', this.immersiveCallback);
      console.info('碰一碰监听已注册');
    } catch (error) {
      console.error('注册碰一碰监听失败:', error);
    }
  }
  
  /**
   * 取消碰一碰分享监听事件
   */
  private immersiveDisablingListening(): void {
    try {
      harmonyShare.off('knockShare', this.immersiveCallback);
      console.info('碰一碰监听已取消');
    } catch (error) {
      console.error('取消碰一碰监听失败:', error);
    }
  }
  
  build() {
    Column() {
      // 视频播放器
      Video({
        src: this.videoData.videoUrl,
        controller: new VideoController()
      })
        .width('100%')
        .height('60%')
        .autoPlay(false)
      
      // 视频信息
      Column() {
        Text(this.videoTitle)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .margin({ top: 16 })
        
        Text(this.videoDescription)
          .fontSize(14)
          .fontColor(Color.Gray)
          .margin({ top: 8 })
        
        Text('📱 碰一碰即可分享此视频')
          .fontSize(12)
          .fontColor(Color.Blue)
          .margin({ top: 16 })
          .padding(8)
          .borderRadius(8)
          .backgroundColor('#F0F8FF')
      }
      .width('100%')
      .padding(16)
      .alignItems(HorizontalAlign.Center)
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
  }
}

4.2 分享控制类(KnockController)

将碰一碰分享逻辑抽取为独立控制类,便于复用:

typescript

// KnockController.ets - 碰一碰分享控制类

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

export class KnockController {
  private context: Context;
  private callback: ((sharableTarget: harmonyShare.SharableTarget) => void) | null = null;
  private isListening: boolean = false;
  
  constructor(context: Context) {
    this.context = context;
  }
  
  /**
   * 配置分享数据并注册监听
   */
  public setupShare(config: ShareConfig): void {
    // 检测设备支持
    if (!this.isSupported()) {
      console.warn('设备不支持碰一碰分享');
      return;
    }
    
    // 构建回调
    this.callback = (sharableTarget: harmonyShare.SharableTarget): void => {
      const shareData = this.buildShareData(config);
      if (shareData) {
        sharableTarget.share(shareData);
      }
    };
    
    // 注册监听
    this.register();
  }
  
  /**
   * 判断设备是否支持碰一碰
   */
  public isSupported(): boolean {
    return canIUse('SystemCapability.Collaboration.HarmonyShare');
  }
  
  /**
   * 构建分享数据
   */
  private buildShareData(config: ShareConfig): systemShare.SharedData | null {
    try {
      let data: Record<string, Object> = {
        utd: config.utd || utd.UniformDataType.HYPERLINK,
        content: config.content
      };
      
      // 可选字段
      if (config.thumbnailPath) {
        data.thumbnailUri = fileUri.getUriFromPath(config.thumbnailPath);
      }
      if (config.title) {
        data.title = config.title;
      }
      if (config.description) {
        data.description = config.description;
      }
      
      return new systemShare.SharedData(data);
    } catch (error) {
      console.error('构建分享数据失败:', error);
      return null;
    }
  }
  
  /**
   * 注册监听
   */
  public register(): void {
    if (this.isListening || !this.callback) {
      return;
    }
    try {
      harmonyShare.on('knockShare', this.callback);
      this.isListening = true;
      console.info('碰一碰监听已注册');
    } catch (error) {
      console.error('注册碰一碰监听失败:', error);
    }
  }
  
  /**
   * 取消监听
   */
  public unregister(): void {
    if (!this.isListening || !this.callback) {
      return;
    }
    try {
      harmonyShare.off('knockShare', this.callback);
      this.isListening = false;
      console.info('碰一碰监听已取消');
    } catch (error) {
      console.error('取消碰一碰监听失败:', error);
    }
  }
  
  /**
   * 销毁控制类
   */
  public destroy(): void {
    this.unregister();
    this.callback = null;
  }
}

/**
 * 分享配置接口
 */
export interface ShareConfig {
  content: string;           // 分享内容(链接、文本等)
  utd?: string;             // 数据类型(可选)
  thumbnailPath?: string;   // 预览图路径(可选)
  title?: string;           // 卡片标题(可选)
  description?: string;     // 卡片描述(可选)
}

4.3 使用控制类

在页面中使用 KnockController

typescript

// 在页面中
@State knockController: KnockController = new KnockController(getContext(this));

aboutToAppear(): void {
  // 配置分享
  this.knockController.setupShare({
    content: 'https://yourdomain.com/video/123',
    title: '精彩视频分享',
    description: '快来一起看这个视频吧!',
    thumbnailPath: this.getThumbnailPath()
  });
}

onPageShow(): void {
  this.knockController.register();
}

onPageHide(): void {
  this.knockController.unregister();
}

aboutToDisappear(): void {
  this.knockController.destroy();
}

第五章 分享卡片设计

碰一碰触发后,对端设备会收到一张分享卡片。卡片的样式直接影响用户是否愿意接收,因此卡片设计至关重要。

5.1 三种卡片模板

Share Kit 根据传入的字段组合,自动匹配不同的卡片模板:

卡片模板 触发条件 适用场景 布局特点
纯图片布局 仅传 thumbnailUri 分享文件、图片 只有预览图,无标题和描述
沉浸式大卡布局 传 title + description + thumbnailUri,预览图宽高比 < 1:1 分享链接类内容(竖图) 预览图铺满,标题2行,描述1行
白卡上下布局 传 title + description + thumbnailUri,预览图宽高比 > 1:1 分享链接类内容(横图) 预览图在上方,标题和描述在下方

5.2 卡片设计要点

纯图片布局

  • 构造分享数据时只传 thumbnailUri 字段

  • 预览图支持最小宽高比 1:4,超出部分将被裁剪

沉浸式大卡布局

  • 需同时传入 titledescriptionthumbnailUri 三个字段

  • 预览图宽高比小于 1:1(竖图)

  • 标题最多显示 2 行,约 20 个中文字符

  • 描述仅显示 1 行,超出部分用省略号代替

白卡上下布局

  • 触发条件与沉浸式大卡相同

  • 区别在于预览图宽高比大于 1:1(横图)

  • 预览图只显示在卡片上方,不会铺满整张卡片

5.3 卡片模板代码示例

typescript

// 1. 纯图片布局(只传预览图)
let imageShareData = new systemShare.SharedData({
  utd: utd.UniformDataType.IMAGE,
  thumbnailUri: fileUri.getUriFromPath('/path/to/image.jpg')
  // 不传 title 和 description
});

// 2. 沉浸式大卡布局(竖图 + 标题 + 描述)
let immersiveShareData = new systemShare.SharedData({
  utd: utd.UniformDataType.HYPERLINK,
  content: 'https://example.com/article',
  thumbnailUri: fileUri.getUriFromPath('/path/to/vertical.jpg'),
  title: '这是一篇值得分享的文章标题',
  description: '文章简介,会让读者快速了解内容'
});

// 3. 白卡上下布局(横图 + 标题 + 描述)
let whiteCardShareData = new systemShare.SharedData({
  utd: utd.UniformDataType.HYPERLINK,
  content: 'https://example.com/article',
  thumbnailUri: fileUri.getUriFromPath('/path/to/horizontal.jpg'),
  title: '文章标题',
  description: '文章简介'
});

第六章 进阶技巧

6.1 App Linking + 碰一碰:实现应用直达

碰一碰分享配合 App Linking 可以实现"一碰即传、一步直达"的体验。

实现原理

  1. 在 AppGallery Connect 中创建 App Linking 链接

  2. 分享内容使用 App Linking 链接

  3. 目标设备接收链接后,自动拉起对应应用并跳转到指定页面

代码示例

typescript

// 使用 App Linking 链接作为分享内容
let appLinkingUrl = 'https://yourdomain.app.link/video/12345';

let shareData = new systemShare.SharedData({
  utd: utd.UniformDataType.HYPERLINK,
  content: appLinkingUrl,  // App Linking 链接
  thumbnailUri: thumbnailUri,
  title: '视频标题',
  description: '点击观看精彩视频'
});

6.2 分享图片到对方相册

分享图片时,目标设备可以直接接收并保存至相册:

typescript

private shareImage(sharableTarget: harmonyShare.SharableTarget, imagePath: string): void {
  const context = getContext(this);
  let uri = fileUri.getUriFromPath(imagePath);
  
  let shareData = new systemShare.SharedData({
    utd: utd.UniformDataType.IMAGE,
    thumbnailUri: uri,
    // 图片类型只需传 previewUri,无需 title 和 description
  });
  
  sharableTarget.share(shareData);
}

6.3 分享自定义数据(Base64 字节流)

对于自定义数据格式,可以将数据打包为 Base64 字符串进行分享:

typescript

private shareCustomData(sharableTarget: harmonyShare.SharableTarget, data: object): void {
  // 将对象转为 JSON 字符串,再转为 Base64
  const jsonStr = JSON.stringify(data);
  const base64Data = this.stringToBase64(jsonStr);
  
  // 使用自定义协议
  const customUrl = `aeroplan://share?data=${base64Data}`;
  
  let shareData = new systemShare.SharedData({
    utd: utd.UniformDataType.HYPERLINK,
    content: customUrl,
    title: '自定义数据分享',
    description: '包含自定义格式的数据'
  });
  
  sharableTarget.share(shareData);
}

private stringToBase64(str: string): string {
  // Base64 编码实现
  return Buffer.from(str, 'utf-8').toString('base64');
}

6.4 手机与 PC/2in1 碰一碰

从 HarmonyOS 26.0.0 版本开始,手机与 PC/2in1、手机与 Tablet 设备可以触发轻碰事件。

在 PC/2in1 或 Tablet 设备侧,可以从回调事件中获取轻碰的位置坐标信息:

typescript

// PC/2in1 设备侧接收碰一碰
private pcImmersiveCallback(sharableTarget: harmonyShare.SharableTarget, 
                            eventInfo: harmonyShare.KnockEventInfo): void {
  // 获取轻碰位置(基于屏幕左上角为初始点的坐标)
  const knockX = eventInfo.knockX;
  const knockY = eventInfo.knockY;
  
  // 根据轻碰位置执行不同的业务逻辑
  // 例如:向文档指定位置插入图片
  if (knockX < 100 && knockY < 100) {
    // 左上角区域:插入图片到文档开头
  } else {
    // 其他区域:插入图片到当前位置
  }
  
  // 构造分享数据并发送
  // ...
}

6.5 性能优化建议

1. 预览图延迟更新

对于内容频繁变化的场景(如滑动切换图片),可以先注册监听,在回调中动态获取当前内容:

typescript

private immersiveCallback = (sharableTarget: harmonyShare.SharableTarget): void => {
  // 在回调中获取当前显示的内容
  const currentItem = this.getCurrentDisplayItem();
  const thumbnailPath = currentItem.getThumbnailPath();
  
  let shareData = new systemShare.SharedData({
    utd: utd.UniformDataType.IMAGE,
    thumbnailUri: fileUri.getUriFromPath(thumbnailPath)
  });
  
  sharableTarget.share(shareData);
};

2. 避免在回调中执行耗时操作

收到回调后需在 3 秒内完成分享,因此应在回调中避免执行耗时操作。

3. 合理管理监听生命周期

确保在页面不可见时取消监听,避免资源浪费和冲突。

第七章 常见问题与异常处理

7.1 设备支持问题

问题:轻碰后无任何响应

原因

  • 任意一端设备不支持碰一碰能力

  • 设备未亮屏或未解锁

  • 华为分享服务未开启

解决方案

typescript

// 1. 检测设备支持
if (!canIUse('SystemCapability.Collaboration.HarmonyShare')) {
  // 降级到其他分享方式
  this.fallbackToSystemShare();
  return;
}

// 2. 引导用户开启华为分享
// 系统会在用户轻碰时自动提示开启,应用无需额外处理

7.2 分享超时问题

问题:碰一碰后分享失败

原因:收到回调后未在 3 秒内调用 sharableTarget.share()

解决方案

  • 提前准备好分享数据

  • 在回调中只做最轻量的操作

  • 避免在回调中进行网络请求或大量计算

typescript

// 好的做法:提前准备好数据
private preparedShareData: systemShare.SharedData | null = null;

private immersiveCallback = (sharableTarget: harmonyShare.SharableTarget): void => {
  if (this.preparedShareData) {
    sharableTarget.share(this.preparedShareData);
  }
};

// 在页面加载时预构建分享数据
aboutToAppear(): void {
  this.preparedShareData = this.buildShareData();
}

7.3 折叠屏适配问题

折叠屏手机在展开状态下与电脑碰一碰分享时,可能会提示"请将手机折叠后再去轻触"。

解决方案:提示用户将手机折叠后再进行碰一碰分享。

7.4 联系人分享限制

HarmonyOS 5/6 版本仅支持分享联系人列表中的联系人,不支持分享陌生联系人。

7.5 双向分享冲突

双向碰一碰分享时,对方发送的卡片会藏在当前手机分享卡片下面。需要先将当前卡片上划发送或下划取消,才能看到对方的分享卡片。

7.6 错误码处理

对于不支持碰一碰的场景(错误码 801 等),应安静处理,避免页面反复出现无意义提示。

typescript

try {
  harmonyShare.on('knockShare', this.immersiveCallback);
} catch (error) {
  // 静默处理不支持的情况
  if (error.code === 801) {
    // 不支持碰一碰,静默降级
    console.info('设备不支持碰一碰,使用其他分享方式');
  } else {
    console.error('注册碰一碰监听失败:', error);
  }
}

7.7 常见问题速查表

问题 可能原因 解决方案
轻碰无响应 设备不支持/未亮屏/华为分享未开启 检测能力、引导用户
分享失败 回调后超过3秒未发送 提前准备数据
卡片不显示 数据格式错误 检查 UTD 类型和字段
应用无法拉起 App Linking 配置错误 检查链接和路由配置
折叠屏提示 展开状态下不支持 提示用户折叠手机

第八章 官方资源与示例

8.1 官方示例代码

华为官方提供了多个示例工程,可直接参考:

1. Share Kit SampleCode

地址:https://gitee.com/harmonyos_samples/share-kit_-sample-code_-clientdemo_-arkts

包含系统分享接入模式、文本/图片等分享示例、碰一碰分享示例及卡片模板。

2. KnockShare 示例

地址:https://gitee.com/harmonyos_samples/knock-share

利用 Share Kit 与 App Linking 的结合,实现了快速跨设备分享视频并直接进入应用内视频播放页面的功能。

8.2 Codelabs 教程

HarmonyOS Codelabs 提供了"实现华为分享功能"的互动教程,介绍如何使用 Share Kit 实现分享能力,包含如何接入系统分享和碰一碰分享。

8.3 官方文档

结语

本文从技术原理、环境准备、开发流程、源码实现、卡片设计到进阶技巧,全方位讲解了鸿蒙碰一碰分享的开发实践。通过接入 Share Kit 的碰一碰能力,开发者可以为应用带来"一碰即传"的极致用户体验。

总结关键要点:

  1. 环境准备:确保设备系统版本、开发工具满足要求

  2. 能力检测:使用 canIUse 在运行时判断设备支持

  3. 生命周期管理:进入可分享页面时注册监听,离开时取消监听

  4. 快速响应:收到回调后需在 3 秒内完成分享

  5. 卡片设计:根据数据类型选择合适的卡片模板

  6. 应用直达:配合 App Linking 实现一步直达

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐