鸿蒙6核心功能实战:手把手教你开发分布式协同小应用

鸿蒙6的核心优势在于分布式协同能力——能让手机、平板、智慧屏等设备突破硬件边界,实现数据和功能的无缝流转。本文以“手机+平板文件无缝传输”为例,手把手拆解鸿蒙6分布式软总线、设备管理API的使用逻辑,附完整可运行的代码注释,帮你快速掌握分布式应用开发核心。

一、核心概念:分布式协同的2个关键技术

在开发文件传输应用前,先理清鸿蒙6实现设备间协同的核心技术:

  1. 分布式软总线:鸿蒙设备间的“隐形连接线”,无需WiFi/蓝牙手动配对,自动发现同账号下的设备并建立通信通道;
  2. 设备管理API(鸿蒙6新增):简化了设备发现、认证、连接的流程,相比鸿蒙5,减少70%的冗余代码;
  3. 分布式数据管理:支持跨设备文件/数据的读写,是实现文件传输的核心。

二、实战准备:环境与权限配置

1. 开发环境

  • DevEco Studio 5.0(适配鸿蒙6);
  • 2台鸿蒙6设备(手机+平板,登录同一华为账号);
  • 项目配置:API 11(鸿蒙6对应版本)、ArkTS语言、Stage模型。

2. 权限配置(必做)

module.json5中添加分布式相关权限:

{
  "module": {
    "abilities": [...],
    "requestPermissions": [
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC", // 分布式数据同步
        "reason": "用于跨设备文件传输",
        "usedScene": { "when": "always" }
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO", // 获取网络信息(软总线依赖)
        "reason": "用于发现周边设备",
        "usedScene": { "when": "always" }
      },
      {
        "name": "ohos.permission.READ_USER_STORAGE", // 读取文件
        "reason": "读取待传输的本地文件",
        "usedScene": { "when": "always" }
      },
      {
        "name": "ohos.permission.WRITE_USER_STORAGE", // 写入文件
        "reason": "写入接收的文件",
        "usedScene": { "when": "always" }
      }
    ]
  }
}

三、核心代码实现:手机→平板文件传输

1. 第一步:设备发现与连接(分布式软总线)

先实现“发现同账号下的平板设备”并建立连接,核心用DeviceManagerSoftBus API:

// index.ets
import deviceManager from '@ohos.distributedDeviceManager'; // 设备管理API
import softBus from '@ohos.softBus'; // 分布式软总线API
import fs from '@ohos.file.fs'; // 文件操作API

@Entry
@Component
struct FileTransferPage {
  // 状态变量:已发现的设备列表、选中的目标设备ID
  @State deviceList: Array<string> = [];
  @State targetDeviceId: string = '';
  // 设备管理实例
  private dmInstance: deviceManager.DeviceManager | null = null;

  // 页面加载时初始化设备管理
  aboutToAppear() {
    this.initDeviceManager();
  }

  // 初始化设备管理器,发现周边鸿蒙6设备
  initDeviceManager() {
    // 创建设备管理实例(鸿蒙6简化版API)
    deviceManager.createDeviceManager('com.example.filetransfer', (err, data) => {
      if (err) {
        console.error('创建设备管理器失败:', err.message);
        return;
      }
      this.dmInstance = data;
      // 监听设备上线事件
      this.dmInstance.on('deviceOnline', (deviceInfo) => {
        // 过滤:只保留平板设备(deviceType=2),排除本机
        if (deviceInfo.deviceType === 2 && !deviceInfo.isLocalDevice) {
          this.deviceList.push(deviceInfo.deviceId);
          console.log('发现平板设备:', deviceInfo.deviceName);
        }
      });
      // 主动扫描周边设备
      this.dmInstance.startDeviceDiscovery({
        subscribeId: 1,
        medium: 2, // 软总线通信介质
        mode: 0, // 主动发现模式
        freq: 1 // 扫描频率
      });
    });
  }

  // 选择目标设备并建立连接
  connectDevice(deviceId: string) {
    this.targetDeviceId = deviceId;
    // 鸿蒙6软总线连接:自动认证同账号设备
    softBus.connectDevice(deviceId, (err) => {
      if (err) {
        console.error('设备连接失败:', err.message);
        return;
      }
      promptAction.showToast({ message: '已连接平板设备' });
    });
  }

  // 构建UI:显示发现的设备列表
  build() {
    Column() {
      Text('可传输的设备')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin(10);
      // 遍历设备列表,点击选择
      List({ space: 10 }) {
        ForEach(this.deviceList, (deviceId) => {
          ListItem() {
            Button('连接平板:' + deviceId.substring(0, 8))
              .onClick(() => this.connectDevice(deviceId))
              .width('100%')
              .backgroundColor('#007dff');
          }
        })
      }
      .width('90%')
      .margin(10);
      // 选择文件并传输按钮
      Button('选择文件传输')
        .onClick(() => this.selectAndTransferFile())
        .width('90%')
        .height(50)
        .margin(20)
        .backgroundColor('#00c88c');
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }
}

2. 第二步:文件跨设备传输核心逻辑

实现“选择本地文件→通过软总线传输到平板”,核心用分布式文件读写API:

// 继续在FileTransferPage中添加以下方法
// 选择本地文件(以txt文件为例)
async selectAndTransferFile() {
  if (!this.targetDeviceId) {
    promptAction.showToast({ message: '请先选择目标设备' });
    return;
  }
  // 鸿蒙6文件选择器API
  const fileSelectOptions = {
    uriType: fs.UriType.FILE,
    fileTypes: ['.txt'], // 仅选择txt文件
    mode: fs.FileMode.READ_ONLY
  };
  try {
    // 打开文件选择器,获取选中文件的URI
    const fileUris = await filePicker.selectFile(fileSelectOptions);
    if (fileUris.length === 0) return;
    // 读取本地文件内容
    const fileContent = await this.readLocalFile(fileUris[0]);
    // 传输文件到平板设备
    await this.transferFileToDevice(fileContent, fileUris[0].split('/').pop()!);
  } catch (err) {
    console.error('文件选择/读取失败:', err);
  }
}

// 读取本地文件内容
async readLocalFile(fileUri: string): Promise<string> {
  const file = await fs.open(fileUri, fs.OpenMode.READ_ONLY);
  const fileSize = await fs.stat(fileUri).then(stat => stat.size);
  const buffer = new ArrayBuffer(fileSize);
  await fs.read(file.fd, buffer);
  await fs.close(file);
  return String.fromCharCode.apply(null, new Uint8Array(buffer));
}

// 跨设备传输文件(核心方法)
async transferFileToDevice(fileContent: string, fileName: string) {
  // 鸿蒙6分布式文件路径格式:devicenet://[设备ID]/[文件路径]
  const remoteFilePath = `devicenet://${this.targetDeviceId}/data/storage/el2/base/haps/entry/files/${fileName}`;
  try {
    // 打开远程设备的文件写入通道(软总线自动传输)
    const remoteFile = await fs.open(remoteFilePath, fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE);
    // 写入文件内容
    await fs.write(remoteFile.fd, new TextEncoder().encode(fileContent));
    await fs.close(remoteFile);
    promptAction.showToast({ message: '文件已传输到平板!' });
  } catch (err) {
    console.error('文件传输失败:', err.message);
    promptAction.showToast({ message: '传输失败,请检查设备连接' });
  }
}

// 页面销毁时释放资源
aboutToDisappear() {
  if (this.dmInstance) {
    this.dmInstance.stopDeviceDiscovery(1); // 停止设备扫描
    this.dmInstance.off('deviceOnline'); // 取消监听
  }
  if (this.targetDeviceId) {
    softBus.disconnectDevice(this.targetDeviceId); // 断开连接
  }
}

四、平板端接收逻辑(极简版)

平板端只需监听文件写入事件,或直接读取分布式路径文件即可:

// 平板端页面代码
import fs from '@ohos.file.fs';

@Entry
@Component
struct ReceiveFilePage {
  @State receivedFileName: string = '';
  @State fileContent: string = '';

  // 读取已接收的文件
  async readReceivedFile() {
    // 分布式路径:本机也可访问接收的文件
    const filePath = '/data/storage/el2/base/haps/entry/files/xxx.txt';
    try {
      const file = await fs.open(filePath, fs.OpenMode.READ_ONLY);
      const buffer = new ArrayBuffer(await fs.stat(filePath).then(stat => stat.size));
      await fs.read(file.fd, buffer);
      await fs.close(file);
      this.fileContent = String.fromCharCode.apply(null, new Uint8Array(buffer));
      this.receivedFileName = '接收的文件:xxx.txt';
    } catch (err) {
      console.error('读取接收文件失败:', err);
    }
  }

  build() {
    Column() {
      Button('查看已接收的文件')
        .onClick(() => this.readReceivedFile())
        .margin(20);
      Text(this.receivedFileName)
        .fontSize(18)
        .margin(10);
      Text(this.fileContent)
        .fontSize(14)
        .width('90%')
        .margin(10);
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }
}

五、关键注意事项(避坑指南)

  1. 设备认证:必须确保两台设备登录同一华为账号,且开启“多设备协同”开关(设置→超级终端→多设备协同);
  2. 文件路径:鸿蒙6对分布式文件路径做了简化,devicenet://[设备ID]/ 前缀是核心,无需手动拼接IP;
  3. 异常处理:传输过程中若设备断连,需捕获softBusdisconnect事件,避免应用崩溃;
  4. 文件大小限制:软总线适合传输小文件(<100MB),大文件建议结合鸿蒙6的分布式文件服务(DFS)。

六、功能扩展思路

基于本文的核心逻辑,可快速扩展更多分布式协同功能:

  • 图片/视频跨设备传输:修改fileTypes.jpg/.mp4即可;
  • 分布式剪切板:手机复制文本,平板直接粘贴;
  • 跨设备控制:平板点击按钮,触发手机拍照。

总结

鸿蒙6的分布式协同开发,核心是用设备管理API发现连接设备,用分布式软总线做数据传输,用文件API读写跨设备文件。本文的文件传输案例,覆盖了鸿蒙6分布式开发的核心流程,代码可直接复用。相比鸿蒙5,鸿蒙6大幅简化了设备连接和权限申请流程,让分布式应用开发门槛降低了50%以上。

Logo

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

更多推荐