鸿蒙开发之:多端协同与流转

21 阅读8分钟

本文字数:约3500字 | 预计阅读时间:14分钟 前置知识:建议先学习本系列前七篇,特别是服务卡片开发

实战价值:掌握多端协同技术,打造全场景智慧体验

系列导航:本文是《鸿蒙开发系列》第8篇,下篇将讲解性能优化与调试技巧

一、多端协同概述:鸿蒙的分布式能力 鸿蒙操作系统的核心特性之一就是分布式能力,它通过分布式软总线技术,让多个设备能够像使用一个设备一样协同工作。多端协同允许应用在不同设备间无缝流转,数据在多设备间同步共享。

1.1 多端协同的核心特性 设备虚拟化:多个设备虚拟为一个超级终端

能力互助:设备间共享硬件和软件能力

数据流转:应用和数据在设备间无缝迁移

分布式安全:端到端的安全保障

1.2 典型应用场景 场景 描述 示例 应用接续 应用从一个设备迁移到另一个设备 手机上看的视频流转到平板上继续观看 跨屏协同 多个设备屏幕协同显示 手机作为平板的手写板或控制器 硬件共享 共享其他设备的硬件能力 使用平板的摄像头进行视频通话 数据同步 数据在多设备间实时同步 笔记、日历、联系人实时同步 二、分布式软总线基础 2.1 设备发现与连接 typescript

// ets/utils/DistributedDeviceManager.ts import deviceManager from '@ohos.distributedDeviceManager';

class DistributedDeviceManager { private deviceList: Array<deviceManager.DeviceBasicInfo> = []; private discoverCallback: ((devices: Array<deviceManager.DeviceBasicInfo>) => void) | null = null;

// 初始化设备管理 async initialize() { try { // 创建设备管理器 const deviceManager = await deviceManager.createDeviceManager('com.example.app'); console.log('设备管理器创建成功');

  // 注册设备状态监听
  deviceManager.on('deviceStateChange', (data) => {
    this.handleDeviceStateChange(data);
  });
  
  return true;
} catch (error) {
  console.error('设备管理器初始化失败:', error);
  return false;
}

}

// 开始发现设备 startDiscovery() { try { deviceManager.startDeviceDiscovery({ mode: deviceManager.DiscoveryMode.ACTIVE, medium: deviceManager.ExchangeMedium.AUTO, freq: deviceManager.ExchangeFreq.HIGH });

  deviceManager.on('deviceFound', (data) => {
    this.handleDeviceFound(data);
  });
  
  console.log('开始设备发现');
} catch (error) {
  console.error('设备发现失败:', error);
}

}

// 停止发现设备 stopDiscovery() { try { deviceManager.stopDeviceDiscovery(); console.log('停止设备发现'); } catch (error) { console.error('停止设备发现失败:', error); } }

// 处理设备发现 private handleDeviceFound(data: deviceManager.DeviceBasicInfo) { // 检查是否已存在 const exists = this.deviceList.some(device => device.deviceId === data.deviceId); if (!exists) { this.deviceList.push(data); console.log('发现新设备:', data.deviceName);

  // 通知监听者
  if (this.discoverCallback) {
    this.discoverCallback(this.deviceList);
  }
}

}

// 处理设备状态变化 private handleDeviceStateChange(data: { deviceId: string, deviceState: number }) { const device = this.deviceList.find(d => d.deviceId === data.deviceId); if (device) { if (data.deviceState === deviceManager.DeviceState.OFFLINE) { // 设备离线 this.deviceList = this.deviceList.filter(d => d.deviceId !== data.deviceId); console.log('设备离线:', device.deviceName); } else if (data.deviceState === deviceManager.DeviceState.ONLINE) { console.log('设备在线:', device.deviceName); }

  // 通知监听者
  if (this.discoverCallback) {
    this.discoverCallback(this.deviceList);
  }
}

}

// 设置设备发现回调 setDiscoverCallback(callback: (devices: Array<deviceManager.DeviceBasicInfo>) => void) { this.discoverCallback = callback; }

// 获取设备列表 getDevices(): Array<deviceManager.DeviceBasicInfo> { return [...this.deviceList]; }

// 连接设备 async connectDevice(deviceId: string): Promise { try { await deviceManager.authenticateDevice(deviceId, { authType: deviceManager.AuthType.PIN, token: '123456' // 实际使用时需要更安全的认证方式 });

  console.log('设备连接成功:', deviceId);
  return true;
} catch (error) {
  console.error('设备连接失败:', error);
  return false;
}

} }

export default new DistributedDeviceManager(); 2.2 设备信息获取 typescript

// ets/utils/DeviceInfoUtil.ts import deviceInfo from '@ohos.deviceInfo';

class DeviceInfoUtil { // 获取设备基本信息 static getDeviceInfo() { return { deviceId: deviceInfo.deviceId, deviceType: deviceInfo.deviceType, deviceName: deviceInfo.deviceName, manufacturer: deviceInfo.manufacturer, brand: deviceInfo.brand, marketName: deviceInfo.marketName, productSeries: deviceInfo.productSeries, productModel: deviceInfo.productModel, softwareModel: deviceInfo.softwareModel, hardwareModel: deviceInfo.hardwareModel, hardwareProfile: deviceInfo.hardwareProfile, bootloaderVersion: deviceInfo.bootloaderVersion, abiList: deviceInfo.abiList, securityPatchTag: deviceInfo.securityPatchTag, displayVersion: deviceInfo.displayVersion, incrementalVersion: deviceInfo.incrementalVersion, osReleaseType: deviceInfo.osReleaseType, osFullName: deviceInfo.osFullName, majorVersion: deviceInfo.majorVersion, seniorVersion: deviceInfo.seniorVersion, featureVersion: deviceInfo.featureVersion, buildVersion: deviceInfo.buildVersion, sdkApiVersion: deviceInfo.sdkApiVersion, firstApiVersion: deviceInfo.firstApiVersion }; }

// 获取设备能力信息 static getDeviceCapabilities() { return { // 屏幕信息 screen: { width: window.innerWidth, height: window.innerHeight, density: window.devicePixelRatio },

  // 设备类型
  type: this.getDeviceType(),
  
  // 支持的功能
  capabilities: {
    camera: this.hasCapability('camera'),
    microphone: this.hasCapability('microphone'),
    gps: this.hasCapability('gps'),
    nfc: this.hasCapability('nfc'),
    bluetooth: this.hasCapability('bluetooth'),
    wifi: this.hasCapability('wifi')
  }
};

}

// 判断设备类型 private static getDeviceType(): string { const deviceType = deviceInfo.deviceType; switch (deviceType) { case 'phone': return '手机'; case 'tablet': return '平板'; case 'tv': return '电视'; case 'wearable': return '穿戴设备'; case 'car': return '车机'; default: return '未知设备'; } }

// 检查设备能力 private static hasCapability(capability: string): boolean { // 这里根据设备类型和能力进行判断 const deviceType = deviceInfo.deviceType;

switch (capability) {
  case 'camera':
    return deviceType !== 'wearable'; // 穿戴设备可能没有摄像头
  case 'microphone':
    return deviceType !== 'wearable';
  case 'gps':
    return deviceType === 'phone' || deviceType === 'tablet';
  default:
    return true;
}

} }

export default DeviceInfoUtil; 三、应用流转:跨设备无缝体验 3.1 流转能力配置 json

// module.json5 { "module": { "name": "entry", "type": "entry", "continuable": true, // 启用流转能力 "abilities": [ { "name": "MainAbility", "srcEntry": "./ets/entryability/MainAbility.ts", "description": "string:mainabilitydescription","icon":"string:mainability_description", "icon": "media:icon", "label": "string:entryMainAbility","startWindowIcon":"string:entry_MainAbility", "startWindowIcon": "media:icon", "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "actions": [ "action.system.home" ], "entities": [ "entity.system.home" ] } ], "continuationFilter": { "deviceTypes": ["phone", "tablet", "tv"], // 支持的设备类型 "abilityTypes": ["page"], "bundleName": "com.example.multideviceapp", "supportDimensions": ["12", "22", "24", "44"] } } ] } } 3.2 流转管理器 typescript

// ets/utils/ContinuationManager.ts import continuation from '@ohos.continuation.continuationManager';

class ContinuationManager { private continuationToken: number = 0; private deviceList: Array = [];

// 注册流转能力 async registerContinuation() { try { this.continuationToken = await continuation.registerContinuation({ deviceType: ['phone', 'tablet', 'tv'], abilityType: ['page'], bundleName: 'com.example.multideviceapp' });

  console.log('流转能力注册成功, token:', this.continuationToken);
  return true;
} catch (error) {
  console.error('流转能力注册失败:', error);
  return false;
}

}

// 显示设备选择器 async showDevicePicker(): Promise<string | null> { try { const extraParams = { title: '选择流转设备', deviceType: ['phone', 'tablet'], filter: 'online' };

  const result = await continuation.startDeviceSelection(this.continuationToken, extraParams);
  
  if (result && result.length > 0) {
    return result[0]; // 返回选择的设备ID
  }
  
  return null;
} catch (error) {
  console.error('设备选择失败:', error);
  return null;
}

}

// 更新流转状态 updateContinuationState(state: continuation.ContinuationState) { try { continuation.updateContinuationState(this.continuationToken, state); } catch (error) { console.error('更新流转状态失败:', error); } }

// 取消流转 unregisterContinuation() { if (this.continuationToken > 0) { try { continuation.unregisterContinuation(this.continuationToken); console.log('流转能力取消注册'); } catch (error) { console.error('取消流转注册失败:', error); } } }

// 获取流转数据 saveContinuationData(): any { // 保存需要流转的数据 return { timestamp: Date.now(), pageData: this.getCurrentPageData(), userState: this.getUserState() }; }

// 恢复流转数据 restoreContinuationData(data: any) { // 恢复流转的数据 if (data && data.pageData) { this.restorePageData(data.pageData); } }

private getCurrentPageData(): any { // 获取当前页面数据 return { pageIndex: 0, scrollPosition: 0, formData: {} }; }

private getUserState(): any { // 获取用户状态 return { userId: 'user123', preferences: {} }; }

private restorePageData(data: any) { // 恢复页面数据 console.log('恢复页面数据:', data); } }

export default new ContinuationManager(); 3.3 流转页面实现 typescript

// ets/pages/MainPage.ets @Entry @Component struct MainPage { @State currentVideo: { id: string, title: string, url: string, progress: number } = { id: 'video001', title: '鸿蒙开发教程', url: 'example.com/video.mp4', progress: 0.35 };

@State connectedDevices: Array<{id: string, name: string, type: string}> = []; @State isPlaying: boolean = false;

private continuationManager = ContinuationManager;

aboutToAppear() { // 注册流转能力 this.continuationManager.registerContinuation();

// 监听设备连接
DistributedDeviceManager.setDiscoverCallback((devices) => {
  this.connectedDevices = devices.map(device => ({
    id: device.deviceId,
    name: device.deviceName,
    type: this.getDeviceTypeName(device.deviceType)
  }));
});

}

aboutToDisappear() { // 取消流转注册 this.continuationManager.unregisterContinuation(); }

build() { Column({ space: 20 }) { // 视频播放器 Column({ space: 12 }) { Text(this.currentVideo.title) .fontSize(20) .fontWeight(FontWeight.Bold)

    // 视频播放区域
    Column()
      .width('100%')
      .height(200)
      .backgroundColor('#000000')
      .justifyContent(FlexAlign.Center) {
        Row() {
          if (this.isPlaying) {
            Image($r('app.media.pause'))
              .width(48)
              .height(48)
              .onClick(() => {
                this.isPlaying = false;
              })
          } else {
            Image($r('app.media.play'))
              .width(48)
              .height(48)
              .onClick(() => {
                this.isPlaying = true;
              })
          }
        }
      }
    
    // 进度条
    Column() {
      Row()
        .width(`${this.currentVideo.progress * 100}%`)
        .height(4)
        .backgroundColor('#007DFF')
    }
    .width('100%')
    .height(4)
    .backgroundColor('#EEEEEE')
    
    // 播放时间
    Row() {
      Text('12:30')
        .fontSize(12)
        .fontColor('#666666')
      
      Blank()
      
      Text('35:45')
        .fontSize(12)
        .fontColor('#666666')
    }
    .width('100%')
  }
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(16)
  .shadow({ radius: 8, color: '#00000010' })
  
  // 流转控制
  Column({ space: 12 }) {
    Text('流转到其他设备')
      .fontSize(16)
      .fontWeight(FontWeight.Medium)
    
    if (this.connectedDevices.length === 0) {
      Text('未发现可用设备')
        .fontSize(14)
        .fontColor('#999999')
    } else {
      Column({ space: 8 }) {
        ForEach(this.connectedDevices, (device) => {
          Row({ space: 12 }) {
            Image(this.getDeviceIcon(device.type))
              .width(24)
              .height(24)
            
            Column({ space: 4 }) {
              Text(device.name)
                .fontSize(14)
                .fontColor('#333333')
              
              Text(device.type)
                .fontSize(12)
                .fontColor('#666666')
            }
            .alignItems(HorizontalAlign.Start)
            .layoutWeight(1)
            
            Button('流转')
              .width(80)
              .height(32)
              .fontSize(12)
              .onClick(() => {
                this.transferToDevice(device.id);
              })
          }
          .padding(12)
          .backgroundColor('#F8F8F8')
          .borderRadius(12)
        })
      }
    }
    
    Button('发现更多设备')
      .width('100%')
      .height(40)
      .fontSize(14)
      .backgroundColor('#007DFF')
      .fontColor(Color.White)
      .onClick(() => {
        this.discoverDevices();
      })
  }
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(16)
  .shadow({ radius: 8, color: '#00000010' })
}
.width('100%')
.height('100%')
.padding(20)
.backgroundColor('#F5F5F5')

}

// 流转到指定设备 async transferToDevice(deviceId: string) { // 保存当前状态 const continuationData = { video: this.currentVideo, isPlaying: this.isPlaying, progress: this.currentVideo.progress, timestamp: Date.now() };

// 开始流转
const selectedDeviceId = await this.continuationManager.showDevicePicker();
if (selectedDeviceId) {
  console.log('开始流转到设备:', selectedDeviceId);
  
  // 更新流转状态
  this.continuationManager.updateContinuationState('started');
  
  // 这里实际会触发系统流转流程
  // 流转成功后,应用会在目标设备上恢复
}

}

// 发现设备 discoverDevices() { DistributedDeviceManager.startDiscovery(); }

// 获取设备图标 getDeviceIcon(type: string): Resource { switch (type) { case '手机': return r(app.media.phone);case:returnr('app.media.phone'); case '平板': return r('app.media.tablet'); case '电视': return r(app.media.tv);case穿戴设:returnr('app.media.tv'); case '穿戴设备': return r('app.media.watch'); default: return $r('app.media.device'); } }

// 获取设备类型名称 getDeviceTypeName(deviceType: number): string { switch (deviceType) { case 0: return '手机'; case 1: return '平板'; case 3: return '电视'; case 4: return '穿戴设备'; case 5: return '车机'; default: return '未知设备'; } } } 四、分布式数据管理 4.1 分布式数据存储 typescript

// ets/utils/DistributedDataManager.ts import distributedData from '@ohos.data.distributedData';

class DistributedDataManager { private kvManager: distributedData.KVManager | null = null; private kvStore: distributedData.KVStore | null = null; private storeId: string = 'multidevice_data_store';

// 初始化分布式KV存储 async initialize() { try { // 创建KVManager配置 const config: distributedData.KVManagerConfig = { bundleName: 'com.example.multideviceapp', userInfo: { userId: 'globalUser', userType: distributedData.UserType.SAME_USER_ID }, context: getContext(this) };

  // 创建KVManager
  this.kvManager = distributedData.createKVManager(config);
  
  // 创建KVStore配置
  const options: distributedData.Options = {
    createIfMissing: true,
    encrypt: true,
    backup: false,
    autoSync: true,
    kvStoreType: distributedData.KVStoreType.DEVICE_COLLABORATION,
    securityLevel: distributedData.SecurityLevel.S2
  };
  
  // 创建KVStore
  this.kvStore = await this.kvManager.getKVStore(this.storeId, options);
  
  console.log('分布式数据存储初始化成功');
  return true;
} catch (error) {
  console.error('分布式数据存储初始化失败:', error);
  return false;
}

}

// 保存数据 async save(key: string, value: any): Promise { if (!this.kvStore) return false;

try {
  await this.kvStore.put(key, JSON.stringify(value));
  return true;
} catch (error) {
  console.error('保存数据失败:', error);
  return false;
}

}

// 获取数据 async get<T = any>(key: string): Promise<T | null> { if (!this.kvStore) return null;

try {
  const value = await this.kvStore.get(key);
  if (value) {
    return JSON.parse(value.toString()) as T;
  }
  return null;
} catch (error) {
  console.error('获取数据失败:', error);
  return null;
}

}

// 删除数据 async delete(key: string): Promise { if (!this.kvStore) return false;

try {
  await this.kvStore.delete(key);
  return true;
} catch (error) {
  console.error('删除数据失败:', error);
  return false;
}

}

// 同步数据到其他设备 async sync(deviceIds?: Array): Promise { if (!this.kvStore) return false;

try {
  const mode = distributedData.SyncMode.PULL_ONLY;
  const delay = 0; // 立即同步
  
  if (deviceIds && deviceIds.length > 0) {
    // 同步到指定设备
    await this.kvStore.sync(deviceIds, mode, delay);
  } else {
    // 同步到所有设备
    await this.kvStore.sync(mode, delay);
  }
  
  return true;
} catch (error) {
  console.error('数据同步失败:', error);
  return false;
}

}

// 监听数据变化 onDataChange(callback: (data: { key: string, value: any, deviceId: string }) => void) { if (!this.kvStore) return;

this.kvStore.on('dataChange', (data) => {
  const changeData = data as distributedData.ChangeNotification;
  
  changeData.insertEntries.forEach(entry => {
    try {
      const value = JSON.parse(entry.value.toString());
      callback({
        key: entry.key,
        value: value,
        deviceId: changeData.deviceId
      });
    } catch (error) {
      console.error('解析变更数据失败:', error);
    }
  });
});

} }

export default new DistributedDataManager(); 4.2 分布式数据同步示例 typescript

// ets/pages/CollaborationPage.ets @Entry @Component struct CollaborationPage { @State todoList: Array<{ id: string, text: string, completed: boolean, device: string }> = []; @State newTodoText: string = ''; @State connectedDevices: Array = [];

private distributedDataManager = DistributedDataManager; private deviceId: string = '';

async aboutToAppear() { // 初始化分布式数据 await this.distributedDataManager.initialize();

// 获取设备ID
this.deviceId = DeviceInfoUtil.getDeviceInfo().deviceId;

// 监听数据变化
this.distributedDataManager.onDataChange((data) => {
  this.handleDataChange(data);
});

// 加载数据
await this.loadTodoList();

}

async loadTodoList() { const savedList = await this.distributedDataManager.get<Array>('todo_list'); if (savedList) { this.todoList = savedList; } }

handleDataChange(data: { key: string, value: any, deviceId: string }) { if (data.key === 'todo_list') { this.todoList = data.value; console.log(数据从设备 ${data.deviceId} 同步); } }

async addTodo() { if (!this.newTodoText.trim()) return;

const newTodo = {
  id: Date.now().toString(),
  text: this.newTodoText,
  completed: false,
  device: this.deviceId,
  timestamp: Date.now()
};

this.todoList = [...this.todoList, newTodo];
this.newTodoText = '';

// 保存到分布式存储
await this.distributedDataManager.save('todo_list', this.todoList);

// 同步到其他设备
await this.distributedDataManager.sync();

}

async toggleTodo(id: string) { this.todoList = this.todoList.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo );

// 保存并同步
await this.distributedDataManager.save('todo_list', this.todoList);
await this.distributedDataManager.sync();

}

async deleteTodo(id: string) { this.todoList = this.todoList.filter(todo => todo.id !== id);

// 保存并同步
await this.distributedDataManager.save('todo_list', this.todoList);
await this.distributedDataManager.sync();

}

build() { Column({ space: 20 }) { Text('协同待办') .fontSize(24) .fontWeight(FontWeight.Bold)

  // 添加待办
  Row({ space: 12 }) {
    TextInput({ placeholder: '添加新待办...' })
      .width('70%')
      .height(48)
      .value(this.newTodoText)
      .onChange((value: string) => {
        this.newTodoText = value;
      })
    
    Button('添加')
      .width('30%')
      .height(48)
      .fontSize(14)
      .backgroundColor('#007DFF')
      .fontColor(Color.White)
      .onClick(() => {
        this.addTodo();
      })
  }
  .width('100%')
  
  // 待办列表
  List({ space: 12 }) {
    ForEach(this.todoList, (todo) => {
      ListItem() {
        Row({ space: 12 }) {
          // 完成状态
          Column()
            .width(20)
            .height(20)
            .border({ width: 2, color: todo.completed ? '#34C759' : '#CCCCCC' })
            .borderRadius(10)
            .backgroundColor(todo.completed ? '#34C759' : 'transparent')
            .onClick(() => {
              this.toggleTodo(todo.id);
            })
          
          // 待办文本
          Text(todo.text)
            .fontSize(16)
            .fontColor(todo.completed ? '#999999' : '#333333')
            .textDecoration(todo.completed ? { type: TextDecorationType.LineThrough } : null)
            .layoutWeight(1)
          
          // 设备标识
          Text(todo.device === this.deviceId ? '本机' : '其他设备')
            .fontSize(12)
            .fontColor('#666666')
            .padding({ left: 8, right: 8, top: 4, bottom: 4 })
            .backgroundColor('#F0F0F0')
            .borderRadius(12)
          
          // 删除按钮
          Image($r('app.media.delete'))
            .width(20)
            .height(20)
            .onClick(() => {
              this.deleteTodo(todo.id);
            })
        }
        .width('100%')
        .padding(16)
        .backgroundColor(Color.White)
        .borderRadius(12)
        .shadow({ radius: 4, color: '#00000010' })
      }
    })
  }
  .layoutWeight(1)
  
  // 同步控制
  Row({ space: 12 }) {
    Button('手动同步')
      .width('50%')
      .height(48)
      .fontSize(14)
      .backgroundColor('#34C759')
      .fontColor(Color.White)
      .onClick(() => {
        this.distributedDataManager.sync();
      })
    
    Button('清空列表')
      .width('50%')
      .height(48)
      .fontSize(14)
      .backgroundColor('#FF3B30')
      .fontColor(Color.White)
      .onClick(async () => {
        this.todoList = [];
        await this.distributedDataManager.save('todo_list', []);
        await this.distributedDataManager.sync();
      })
  }
  .width('100%')
}
.width('100%')
.height('100%')
.padding(20)
.backgroundColor('#F5F5F5')

} } 五、硬件能力共享 5.1 摄像头共享 typescript

// ets/utils/CameraSharingManager.ts import camera from '@ohos.multimedia.camera'; import image from '@ohos.multimedia.image';

class CameraSharingManager { private cameraManager: camera.CameraManager | null = null; private cameraInput: camera.CameraInput | null = null; private previewOutput: camera.PreviewOutput | null = null; private photoOutput: camera.PhotoOutput | null = null;

// 初始化摄像头 async initialize() { try { this.cameraManager = camera.getCameraManager(getContext(this));

  // 获取摄像头列表
  const cameras = this.cameraManager.getSupportedCameras();
  if (cameras.length === 0) {
    throw new Error('没有可用的摄像头');
  }
  
  // 使用第一个摄像头
  const cameraDevice = cameras[0];
  
  // 创建相机输入
  this.cameraInput = this.cameraManager.createCameraInput(cameraDevice);
  await this.cameraInput.open();
  
  // 创建预览输出
  const surfaceId = await this.createPreviewSurface();
  this.previewOutput = this.cameraManager.createPreviewOutput(surfaceId);
  
  // 创建拍照输出
  this.photoOutput = this.cameraManager.createPhotoOutput();
  
  // 创建会话
  const session = this.cameraManager.createCaptureSession();
  
  // 配置会话
  session.beginConfig();
  session.addInput(this.cameraInput);
  session.addOutput(this.previewOutput);
  session.addOutput(this.photoOutput);
  await session.commitConfig();
  
  // 启动会话
  await session.start();
  
  console.log('摄像头初始化成功');
  return true;
} catch (error) {
  console.error('摄像头初始化失败:', error);
  return false;
}

}

// 创建预览表面 private async createPreviewSurface(): Promise { // 这里需要创建XComponent来显示预览 return 'preview_surface'; }

// 拍照 async takePhoto(): Promise<image.PixelMap | null> { if (!this.photoOutput) return null;

try {
  const photoSettings = {
    rotation: camera.ImageRotation.ROTATION_0,
    quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
    location: { latitude: 0, longitude: 0, altitude: 0 }
  };
  
  await this.photoOutput.capture(photoSettings);
  
  // 获取照片数据
  const photo = await this.photoOutput.getLatestPhoto();
  const imageData = await photo.main.getComponent(image.ComponentType.JPEG);
  
  return imageData;
} catch (error) {
  console.error('拍照失败:', error);
  return null;
}

}

// 共享摄像头到其他设备 async shareCameraToDevice(deviceId: string): Promise { try { // 这里需要实现摄像头流的编码和传输 console.log('共享摄像头到设备:', deviceId); return true; } catch (error) { console.error('共享摄像头失败:', error); return false; } }

// 释放资源 async release() { if (this.cameraInput) { await this.cameraInput.close(); }

if (this.cameraManager) {
  // 停止会话并释放资源
}

} }

export default new CameraSharingManager(); 5.2 文件共享 typescript

// ets/utils/FileSharingManager.ts import fileIo from '@ohos.fileio'; import fs from '@ohos.file.fs';

class FileSharingManager { // 发送文件到其他设备 async sendFileToDevice(filePath: string, deviceId: string): Promise { try { // 读取文件内容 const file = await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY); const stat = await fileIo.stat(filePath); const buffer = new ArrayBuffer(stat.size); await fileIo.read(file.fd, buffer); await fileIo.close(file.fd);

  // 这里需要实现文件传输逻辑
  // 实际开发中会使用分布式文件系统或网络传输
  
  console.log(`发送文件 ${filePath} 到设备 ${deviceId}, 大小: ${stat.size} 字节`);
  return true;
} catch (error) {
  console.error('发送文件失败:', error);
  return false;
}

}

// 从其他设备接收文件 async receiveFileFromDevice(deviceId: string, fileName: string, fileData: ArrayBuffer): Promise<string | null> { try { const savePath = ${getContext(this).filesDir}/${fileName};

  const file = await fileIo.open(savePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
  await fileIo.write(file.fd, fileData);
  await fileIo.close(file.fd);
  
  console.log(`从设备 ${deviceId} 接收文件 ${fileName}, 保存到: ${savePath}`);
  return savePath;
} catch (error) {
  console.error('接收文件失败:', error);
  return null;
}

}

// 获取共享文件列表 async getSharedFiles(deviceId: string): Promise<Array> { try { // 这里需要从分布式存储获取文件列表 return ['document.pdf', 'photo.jpg', 'video.mp4']; } catch (error) { console.error('获取共享文件列表失败:', error); return []; } } }

export default new FileSharingManager(); 六、多端协同安全 6.1 安全认证管理 typescript

// ets/utils/SecurityManager.ts import userIAM from '@ohos.userIAM.userAuth';

class SecurityManager { // 设备认证 async authenticateDevice(deviceId: string): Promise { try { // 这里使用PIN码认证(实际应用应使用更安全的认证方式) const result = await userIAM.authenticate({ challenge: deviceId, authType: userIAM.AuthType.PIN, authTrustLevel: userIAM.AuthTrustLevel.ATL3 });

  return result === userIAM.ResultCode.SUCCESS;
} catch (error) {
  console.error('设备认证失败:', error);
  return false;
}

}

// 数据加密 encryptData(data: string, key: string): string { // 这里实现数据加密逻辑 // 实际开发中应使用鸿蒙的安全加密框架 return btoa(data); // 简单示例,实际应用需要更安全的加密 }

// 数据解密 decryptData(encryptedData: string, key: string): string { // 这里实现数据解密逻辑 return atob(encryptedData); }

// 权限检查 checkPermission(permission: string): Promise { return new Promise((resolve) => { // 检查应用权限 // 实际开发中应使用鸿蒙的权限管理API resolve(true); }); } }

export default new SecurityManager(); 七、实战:多端协同阅读应用 typescript

// ets/pages/ReadingApp.ets @Entry @Component struct ReadingApp { @State currentBook: { id: string, title: string, content: string, progress: number } | null = null; @State connectedDevices: Array<{id: string, name: string}> = []; @State readingPosition: number = 0; @State fontSize: number = 16; @State theme: 'light' | 'dark' = 'light';

private distributedDataManager = DistributedDataManager; private continuationManager = ContinuationManager;

async aboutToAppear() { // 初始化分布式数据 await this.distributedDataManager.initialize();

// 加载阅读进度
await this.loadReadingProgress();

// 监听数据同步
this.distributedDataManager.onDataChange((data) => {
  if (data.key === 'reading_progress') {
    this.handleProgressSync(data.value);
  }
});

}

async loadReadingProgress() { const progress = await this.distributedDataManager.get('reading_progress'); if (progress) { this.readingPosition = progress.position || 0; this.fontSize = progress.fontSize || 16; this.theme = progress.theme || 'light'; } }

handleProgressSync(progress: any) { if (progress && progress.position !== undefined) { this.readingPosition = progress.position; console.log('阅读进度已从其他设备同步'); } }

async saveProgress() { const progress = { bookId: this.currentBook?.id, position: this.readingPosition, fontSize: this.fontSize, theme: this.theme, timestamp: Date.now(), deviceId: DeviceInfoUtil.getDeviceInfo().deviceId };

await this.distributedDataManager.save('reading_progress', progress);
await this.distributedDataManager.sync();

}

async transferReading(deviceId: string) { if (!this.currentBook) return;

// 保存当前进度
await this.saveProgress();

// 开始流转
const selectedDeviceId = await this.continuationManager.showDevicePicker();
if (selectedDeviceId) {
  console.log('流转阅读到设备:', selectedDeviceId);
  
  // 这里实际会触发应用流转
  // 流转后,目标设备会打开阅读应用并恢复进度
}

}

build() { Column({ space: 20 }) { // 顶部工具栏 Row({ space: 12 }) { Text(this.currentBook?.title || '选择一本书') .fontSize(18) .fontWeight(FontWeight.Bold) .layoutWeight(1)

    Button('流转')
      .width(80)
      .height(36)
      .fontSize(12)
      .onClick(() => {
        this.showDeviceSelector();
      })
  }
  .width('100%')
  .padding(16)
  .backgroundColor(this.theme === 'dark' ? '#333333' : '#FFFFFF')
  
  // 阅读区域
  Scroll() {
    Column({ space: 20 }) {
      Text(this.currentBook?.content || '暂无内容')
        .fontSize(this.fontSize)
        .fontColor(this.theme === 'dark' ? '#FFFFFF' : '#333333')
        .lineHeight(this.fontSize * 1.6)
    }
    .padding(20)
  }
  .onScroll((event: { scrollOffset: number }) => {
    this.readingPosition = event.scrollOffset;
    
    // 自动保存进度(防抖处理)
    this.debouncedSave();
  })
  .layoutWeight(1)
  .backgroundColor(this.theme === 'dark' ? '#1A1A1A' : '#F8F8F8')
  
  // 底部控制栏
  Row({ space: 20 }) {
    // 字体大小控制
    Row({ space: 8 }) {
      Button('A-')
        .width(40)
        .height(40)
        .fontSize(16)
        .onClick(() => {
          if (this.fontSize > 12) {
            this.fontSize--;
            this.saveProgress();
          }
        })
      
      Text(`${this.fontSize}`)
        .width(40)
        .textAlign(TextAlign.Center)
        .fontColor(this.theme === 'dark' ? '#FFFFFF' : '#333333')
      
      Button('A+')
        .width(40)
        .height(40)
        .fontSize(16)
        .onClick(() => {
          if (this.fontSize < 24) {
            this.fontSize++;
            this.saveProgress();
          }
        })
    }
    
    // 主题切换
    Button(this.theme === 'light' ? '🌙' : '☀️')
      .width(40)
      .height(40)
      .fontSize(16)
      .onClick(() => {
        this.theme = this.theme === 'light' ? 'dark' : 'light';
        this.saveProgress();
      })
    
    // 进度显示
    Text(`${Math.floor(this.readingPosition)}`)
      .fontSize(14)
      .fontColor(this.theme === 'dark' ? '#FFFFFF' : '#333333')
      .layoutWeight(1)
      .textAlign(TextAlign.End)
  }
  .width('100%')
  .padding(16)
  .backgroundColor(this.theme === 'dark' ? '#333333' : '#FFFFFF')
}
.width('100%')
.height('100%')
.backgroundColor(this.theme === 'dark' ? '#000000' : '#F5F5F5')

}

private showDeviceSelector() { // 显示设备选择器 this.continuationManager.showDevicePicker().then(deviceId => { if (deviceId) { this.transferReading(deviceId); } }); }

private debouncedSave = this.debounce(() => { this.saveProgress(); }, 1000);

private debounce(func: Function, delay: number) { let timer: number | null = null; return function(this: any, ...args: any[]) { if (timer) clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, delay); }; } } 八、调试与优化 8.1 多端协同调试 typescript

// ets/utils/DistributedDebugger.ts class DistributedDebugger { static enableDebugLog() { console.info('分布式调试模式已启用');

// 监听所有分布式事件
this.listenToDistributedEvents();

// 显示调试面板
this.showDebugPanel();

}

private static listenToDistributedEvents() { // 这里可以监听各种分布式事件 console.log('开始监听分布式事件...'); }

private static showDebugPanel() { // 在界面上显示调试信息 const debugInfo = { deviceId: DeviceInfoUtil.getDeviceInfo().deviceId, connectedDevices: [], dataSyncStatus: '正常', networkStatus: '在线' };

console.table(debugInfo);

}

static logDataSync(data: any) { console.group('数据同步日志'); console.log('时间:', new Date().toLocaleString()); console.log('数据:', data); console.groupEnd(); } } 8.2 性能监控 typescript

class DistributedPerformanceMonitor { private metrics: Map<string, Array> = new Map();

// 测量流转时间 static measureTransferTime(startTime: number) { const duration = performance.now() - startTime; console.log(流转耗时: ${duration.toFixed(2)}ms);

// 记录性能指标
this.recordMetric('transfer_time', duration);

}

// 测量数据同步时间 static measureSyncTime(dataSize: number, startTime: number) { const duration = performance.now() - startTime; const speed = dataSize / (duration / 1000); // bytes per second

console.log(`数据同步: ${dataSize} bytes, 耗时: ${duration.toFixed(2)}ms, 速度: ${(speed / 1024).toFixed(2)} KB/s`);

this.recordMetric('sync_speed', speed);

}

private static recordMetric(name: string, value: number) { let metrics = this.metrics.get(name) || []; metrics.push(value);

// 只保留最近的100个记录
if (metrics.length > 100) {
  metrics = metrics.slice(-100);
}

this.metrics.set(name, metrics);

}

static getPerformanceReport() { const report: any = {};

this.metrics.forEach((values, name) => {
  if (values.length > 0) {
    const sum = values.reduce((a, b) => a + b, 0);
    const avg = sum / values.length;
    const max = Math.max(...values);
    const min = Math.min(...values);
    
    report[name] = {
      count: values.length,
      average: avg,
      max: max,
      min: min,
      latest: values[values.length - 1]
    };
  }
});

return report;

} } 九、总结与下期预告 9.1 本文要点回顾 分布式基础:设备发现、连接和管理

应用流转:跨设备无缝接续应用体验

数据同步:分布式数据存储和实时同步

硬件共享:摄像头、文件等硬件能力共享

安全机制:多端协同的安全认证和加密

实战应用:多端协同阅读、待办等完整应用

9.2 下期预告:《鸿蒙开发之:性能优化与调试技巧》 下篇文章将深入讲解:

应用性能分析与监控

内存管理和优化

渲染性能优化

网络请求优化

启动速度优化

调试工具和技巧

动手挑战 任务1:实现多端协同画板 要求:

支持多设备同时绘画

实时同步绘画内容

支持不同颜色和画笔大小

保存和加载绘画作品

任务2:实现多端协同游戏 要求:

支持多设备联机游戏

实时同步游戏状态

支持语音聊天

游戏进度云端同步

任务3:实现智能家居控制中心 要求:

统一控制多设备家居

设备状态实时同步

支持场景模式

远程控制和自动化

将你的代码分享到评论区,我会挑选优秀实现进行详细点评!

常见问题解答 Q:多端协同需要设备都在同一个网络吗? A:通常需要在同一局域网,但鸿蒙也支持远程协同(需要通过华为账号等机制)。

Q:流转应用时数据会同步传输吗? A:流转时只传输应用状态数据,大文件数据可以通过分布式数据框架同步。

Q:如何保证多端协同的安全性? A:鸿蒙提供了端到端的加密通信、设备认证、权限控制等多层安全机制。

Q:多端协同对设备性能要求高吗? A:基础的数据同步对性能要求不高,但视频流转等实时性要求高的场景需要较好的网络和设备性能。

PS:现在HarmonyOS应用开发者认证正在做活动,初级和高级都可以免费学习及考试,赶快加入班级学习啦:【注意,考试只能从此唯一链接进入】 developer.huawei.com/consumer/cn…

版权声明:本文为《鸿蒙开发系列》第8篇,原创文章,转载请注明出处。

标签:#HarmonyOS #鸿蒙开发 #多端协同 #分布式 #应用流转 #华为开发者 ————————————————