【HarmonyOS 5】鸿蒙分布式协同应用开发详解

【HarmonyOS 5】鸿蒙分布式协同应用开发详解

一、前言

为什么需要分布式协同应用? 首先是因为当今社会,围绕电子产品生态,人们迫切希望,周边的电子设备可以协同操作。例如手机,手表,电视机,汽车,甚至是各种家电产品。 从2015年到如今,手机和pc等老牌电子产品的设备数趋于稳定,其他IoT设备稳步增长。可见人均所拥有的的电子产品的个数,在迅速增加。

IoT 设备(Internet of Things Device) 是指具备联网能力、可与其他设备或系统进行数据交互的物理设备,是构成物联网(IoT)的核心单元。这类设备通过传感器、通信模块等组件,实现对物理世界的感知、数据传输及智能响应。

设备连接步骤繁琐,设备之间能力无法聚合,设备之间的数据无法连通,协同能力低效。

因为以上业务场景的需要,应用开发的需求,也从单一的设备应用开发思路。转变为了多设备协同应用开发。华为提出"1+8+N"以手机为主,围绕建立超级虚拟终端。

二、如何建立分布式操作系统

市面操作系统调研 1、市面上的操作系统,目前只有华为提出了分布式操作系统。 2、像苹果的操作系统,手机平板和电脑也是两套。 3、安卓只有移动端操作系统。没有涉及电脑。 4、微软的电脑操作系统,多年来才集成了安卓虚拟机。

分布式操作系统的特点 1、设备间的操作系统一致 2、拥有统一的交互语言 3、完整的生态

HarmonyOS超级终端能力基座: 1、分布式任务调度 2、分布式数据管理 3、分布式软总线 4、分布式设备虚拟化

HarmonyOS系统架构 HarmonyOS是在OpenHarmony的基础上演进的操作系统。系 统架构是一致,从下面OH的操作系统架构图。我们就可以发现鸿蒙操作分布式是如何实现: HarmonyOS ArkUI框架 通过统一的ArkUI框架,实现在多种设备上,实现相同的UI实现。降低开发者的成本。实现一套代码多端实现。

三、分布式协同应用开发步骤拆解:

1. 权限配置与申请

module.json5配置

json 复制代码
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC",
        "reason": "$string:permission_rationale",
        "usedScene": {
          "abilities": ["MainAbility"],
          "when": "inuse"
        }
      }
    ]
  }
}

动态权限申请代码

typescript 复制代码
import promptAction from '@ohos.promptAction';
import { abilityAccessCtrl, common } from '@kit.AbilityKit';

@Entry
@Component
struct DistributedDemo {

  aboutToAppear() {
    this.requestPermission();
  }

  // 用户申请权限
  private async reqPermissionsFromUser(): Promise<number[]> {
    let context = getContext() as common.UIAbilityContext;
    let atManager = abilityAccessCtrl.createAtManager();
    let grantStatus = await atManager.requestPermissionsFromUser(context, ["ohos.permission.DISTRIBUTED_DATASYNC"]);
    return grantStatus.authResults;
  }

  private async requestPermission() {
    let grantStatus = await this.reqPermissionsFromUser();
    for (let i = 0; i < grantStatus.length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
        this.initDeviceManager();
      }else{
        promptAction.showToast({ message: '请授予权限以使用分布式功能', duration: 2000 });
      }
    }
  }
}

2. 设备发现与组网

设备管理核心类

typescript 复制代码
import { distributedDeviceManager, BusinessError } from '@ohos.distributedDeviceManager';
import promptAction from '@ohos.promptAction';

class DeviceManager {
  private dmInstance: distributedDeviceManager.DeviceManager | null = null;
  @State discoveredDevices: Array<distributedDeviceManager.DeviceBasicInfo> = [];
  
  // 创建设备管理实例并注册回调
  initDeviceManager() {
    try {
      this.dmInstance = distributedDeviceManager.createDeviceManager('com.example.distributedDemo');
      
      // 注册设备发现回调
      this.dmInstance.on('discoverSuccess', (data) => {
        console.info(`发现设备: ${JSON.stringify(data)}`);
        this.discoveredDevices.push(data);
        // 更新UI显示设备列表
        this.updateDeviceList();
      });
      
      this.dmInstance.on('discoverFailure', (error) => {
        console.error(`设备发现失败: ${error.code}, ${error.message}`);
        promptAction.showToast({
          message: '设备发现失败,请检查网络或蓝牙',
          duration: 2000
        });
      });
      
      // 注册设备状态变化回调(上下线监听)
      this.dmInstance.on('deviceStateChange', (data) => {
        const action = data.action === 1 ? '上线' : '下线';
        console.info(`设备 ${data.device.deviceName} ${action}`);
        promptAction.showToast({
          message: `${data.device.deviceName} 已${action}`,
          duration: 1500
        });
      });
    } catch (error) {
      console.error(`创建设备管理器失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    }
  }
  
  // 开始发现周边设备
  startDiscovering() {
    if (!this.dmInstance) return;
    
    const discoverParam: Record<string, number> = {
      'discoverTargetType': 1  // 发现所有类型设备
    };
    
    const filterOptions: Record<string, number> = {
      'availableStatus': 0,     // 发现可用设备
      'discoverDistance': 0,    // 不限制距离
      'authenticationStatus': 0, // 发现未认证设备
      'authorizationType': 0    // 不限制授权类型
    };
    
    try {
      this.dmInstance.startDiscovering(discoverParam, filterOptions);
      console.info('开始发现设备...');
      promptAction.showToast({
        message: '正在搜索周边设备',
        duration: 2000
      });
    } catch (error) {
      console.error(`设备发现接口调用失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    }
  }
}

3. 设备绑定与连接

设备绑定逻辑

typescript 复制代码
// 在DeviceManager类中添加绑定方法
bindDevice(deviceId: string) {
  if (!this.dmInstance) return;
  
  const bindParam: Record<string, string | number> = {
    'bindType': 1,                // 绑定类型(1: PIN码认证)
    'targetPkgName': 'com.example.targetDevice', // 目标设备包名
    'appName': '智能家居设备',
    'appOperation': '绑定操作',
    'customDescription': '分布式组网绑定'
  };
  
  this.dmInstance.bindTarget(deviceId, bindParam, (error, data) => {
    if (error) {
      console.error(`设备绑定失败: ${error.code}, ${error.message}`);
      promptAction.showToast({
        message: '设备绑定失败,请重试',
        duration: 2000
      });
      return;
    }
    
    console.info(`设备绑定成功: ${data.deviceId}`);
    promptAction.showToast({
      message: '设备绑定成功',
      duration: 2000
    });
  });
}

4. 设备信息查询与状态监听

查询可信设备列表

typescript 复制代码
// 在DeviceManager类中添加查询方法
getTrustedDevices() {
  if (!this.dmInstance) return [];
  
  try {
    const deviceList = this.dmInstance.getAvailableDeviceListSync();
    console.info(`查询到 ${deviceList.length} 个可信设备`);
    return deviceList;
  } catch (error) {
    console.error(`查询设备列表失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    return [];
  }
}

5. 分布式数据交互示例

基于设备连接的数据传输

typescript 复制代码
import { distributedDataManager } from '@ohos.distributedDataManager';

class DataInteraction {
  private context: UIContext;
  private deviceId: string; // 目标设备ID
  
  constructor(context: UIContext, deviceId: string) {
    this.context = context;
    this.deviceId = deviceId;
  }
  
  // 向目标设备发送控制指令(如开灯)
  sendControlCommand(command: string) {
    const dataObject = {
      command: command,
      timestamp: new Date().getTime()
    };
    
    distributedDataManager.putData(
      this.context,
      'smartHomeControl', // 数据空间名称
      JSON.stringify(dataObject),
      { targetDeviceId: this.deviceId }
    ).then(() => {
      console.info(`指令发送成功: ${command}`);
    }).catch((error) => {
      console.error(`指令发送失败: ${error}`);
    });
  }
  
  // 订阅目标设备状态数据
  subscribeDeviceStatus() {
    distributedDataManager.subscribe(
      this.context,
      'smartHomeStatus', // 数据空间名称
      { targetDeviceId: this.deviceId },
      (data) => {
        console.info(`收到设备状态更新: ${data}`);
        // 解析数据并更新本地UI
        const status = JSON.parse(data);
        this.updateDeviceStatusUI(status);
      }
    ).then(() => {
      console.info('设备状态订阅成功');
    }).catch((error) => {
      console.error(`订阅失败: ${error}`);
    });
  }
}

完整DEMO流程代码

本DEMO实现智能家居设备的分布式组网,模拟智能灯泡、空调等设备的发现、绑定、连接及数据交互过程,基于HarmonyOS的Distributed Service Kit能力开发。至少2台HarmonyOS设备(如手机、平板),连接同一局域网或开启蓝牙 。

  1. 分布式组网流程

    • 设备发现:通过Wi-Fi/蓝牙扫描周边设备,支持按类型、距离筛选
    • 设备绑定:通过PIN码等方式建立可信连接,确保数据交互安全
    • 状态监听:实时感知设备上下线,动态更新组网拓扑
  2. 数据交互能力

    • 设备控制:向目标设备发送指令(如开关灯、调节温度)
    • 状态同步:订阅设备数据变化,实时更新本地界面显示
  3. 安全机制

    • 权限控制:必须申请分布式数据同步权限
    • 可信认证:绑定流程确保设备身份可信
typescript 复制代码
import promptAction from '@ohos.promptAction';
import { abilityAccessCtrl, common } from '@kit.AbilityKit';
import { distributedDeviceManager } from '@kit.DistributedServiceKit';
import { BusinessError } from '@kit.BasicServicesKit';

class Data {
  device: distributedDeviceManager.DeviceBasicInfo = {
    deviceId: '',
    deviceName: '',
    deviceType: '',
    networkId: ''
  };
}

class ErrorData {
  reason: number = 0;
}

@Entry
@Component
struct DistributedPage {

  private dmInstance: distributedDeviceManager.DeviceManager | null = null;
  @State discoveredDevices: Array<distributedDeviceManager.DeviceBasicInfo> = [];
  @State trustedDevices: Array<distributedDeviceManager.DeviceBasicInfo> = [];

  aboutToAppear() {
    this.requestPermission();
  }

  // 用户申请权限
  private async reqPermissionsFromUser(): Promise<number[]> {
    let context = getContext() as common.UIAbilityContext;
    let atManager = abilityAccessCtrl.createAtManager();
    let grantStatus = await atManager.requestPermissionsFromUser(context, ["ohos.permission.DISTRIBUTED_DATASYNC"]);
    return grantStatus.authResults;
  }

  private async requestPermission() {
    let grantStatus = await this.reqPermissionsFromUser();
    for (let i = 0; i < grantStatus.length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
        this.initDeviceManager();
      }else{
        promptAction.showToast({ message: '请授予权限以使用分布式功能', duration: 2000 });
      }
    }
  }


  // 初始化设备管理器
  initDeviceManager() {
    try {
      this.dmInstance = distributedDeviceManager.createDeviceManager('com.example.distributedDemo');

      // 注册设备发现回调
      this.dmInstance.on('discoverSuccess', (data: Data) => {
        this.discoveredDevices.push(data?.device);
      });

      this.dmInstance.on('discoverFailure', (error: ErrorData) => {
        console.error(`发现失败: ${error.reason}`);
        promptAction.showToast({ message: '设备发现失败', duration: 2000 });
      });

      // 注册设备状态变化回调
      this.dmInstance.on('deviceStateChange', (data) => {
        const action = data.action === 1 ? '上线' : '下线';
        promptAction.showToast({ message: `${data.device.deviceName} ${action}`, duration: 1500 });
        this.queryTrustedDevices();
      });

      // 开始发现设备
      this.startDiscovering();
    } catch (error) {
      console.error(`创建设备管理器失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    }
  }

  // 开始发现设备
  startDiscovering() {
    const discoverParam: Record<string, number> = { 'discoverTargetType': 1 };
    const filterOptions: Record<string, number> = { 'availableStatus': 0 };

    try {
      this.dmInstance?.startDiscovering(discoverParam, filterOptions);
      promptAction.showToast({ message: '正在搜索设备...', duration: 2000 });
    } catch (error) {
      console.error(`发现接口调用失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    }
  }

  // 绑定设备
  bindDevice(deviceId: string) {
    const bindParam: Record<string, string | number> = {
      'bindType': 1,
      'targetPkgName': 'com.example.device',
      'appName': '智能家居',
      'appOperation': '绑定',
      'customDescription': '分布式组网'
    };

    this.dmInstance?.bindTarget(deviceId, bindParam, (error, data) => {
      if (error) {
        console.error(`绑定失败: ${error.code}, ${error.message}`);
        promptAction.showToast({ message: '绑定失败,请重试', duration: 2000 });
        return;
      }

      promptAction.showToast({ message: '设备绑定成功', duration: 2000 });
      this.queryTrustedDevices();
    });
  }

  // 查询可信设备
  queryTrustedDevices() {
    try {
      this.trustedDevices = this.dmInstance?.getAvailableDeviceListSync() ?? [];
    } catch (error) {
      console.error(`查询失败: ${(error as BusinessError).code}, ${(error as BusinessError).message}`);
    }
  }


  // 数据交互示例:向目标设备发送指令
  sendDataToDevice(deviceId: string) {
    // 实际项目中可集成distributedDataManager或remoteService等接口
    promptAction.showToast({ message: `向 ${deviceId} 发送控制指令`, duration: 1500 });
    console.info(`模拟向设备 ${deviceId} 发送数据`);
  }

  build() {
    Column() {
      Text('分布式设备管理DEMO').fontSize(24).fontWeight(FontWeight.Bold).margin({ top: 20 });

      // 操作按钮
      Row() {
        Button('开始发现设备').onClick(() => this.startDiscovering())
        Button('查询可信设备').onClick(() => this.queryTrustedDevices())
      }.margin({ top: 20, bottom: 10 })

      // 发现的设备列表
      Text('发现的设备:').fontSize(18).margin({ top: 10, bottom: 5 })
      List({ space: 5 }) {
        ForEach(this.discoveredDevices, (device: distributedDeviceManager.DeviceBasicInfo) => {
          ListItem() {
            Row() {
              Text(device.deviceName).fontSize(16)
              Text(device.deviceId.substr(0, 8) + '...').fontSize(14).margin({ left: 10 })
              Button('绑定').onClick(() => this.bindDevice(device.deviceId))
                .margin({ left: 'auto' }).width(80)
            }.padding(10).backgroundColor('#F0F0F0')
          }
        })
      }

      // 可信设备列表
      Text('可信设备:').fontSize(18).margin({ top: 20, bottom: 5 })
      List({ space: 5 }) {
        ForEach(this.trustedDevices, (device: distributedDeviceManager.DeviceBasicInfo) => {
          ListItem() {
            Row() {
              Text(device.deviceName).fontSize(16)
              Text(device.deviceId.substr(0, 8) + '...').fontSize(14).margin({ left: 10 })
              Button('控制').onClick(() => this.sendDataToDevice(device.deviceId))
                .margin({ left: 'auto' }).width(80)
            }.padding(10).backgroundColor('#E0F0FF')
          }
        })
      }
    }.padding(20).width('100%')
  }
}

记得配置分布式同步权限

javascript 复制代码
 "requestPermissions": [
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC",
        "reason": "$string:app_name",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when":"inuse"
        }
      }
    ]
相关推荐
君莫笑1111110 小时前
从零到一教你在鸿蒙中上架应用--全流程保姆级
harmonyos
二流小码农11 小时前
鸿蒙开发:资讯项目实战之项目初始化搭建
android·ios·harmonyos
HarmonyOS_SDK12 小时前
如何在应用中实现地图关键字搜索和标记聚合功能?
harmonyos
别说我什么都不会13 小时前
【OpenHarmony】图形图像加载:LargeImage
harmonyos
Aisanyi16 小时前
【鸿蒙开发】PC实现开局沉浸式全屏
前端·华为·harmonyos
我睡醒再说18 小时前
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
harmonyos
我睡醒再说18 小时前
ArkUI-X跨平台开发能力解析:优势与限制场景
harmonyos
我睡醒再说18 小时前
纯血Harmony NETX 5小游戏实践:趣味三消游戏(附源文件)
harmonyos
我睡醒再说19 小时前
HarmonyOS NETX 5ArkUI-X打造数字猜谜游戏:(附源文件)
harmonyos