尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Flutter 与 OpenHarmony 深度集成:实现跨设备传感器数据协同监测系统

Flutter 与 OpenHarmony 深度集成:实现跨设备传感器数据协同监测系统
📅 发布时间:2026/7/22 10:28:14

引言

在万物互联时代,单一设备的感知能力已无法满足复杂场景需求。例如:

  • 健康监护:手表采集心率,手机分析趋势,平板展示报告;
  • 智能家居:温湿度传感器部署在客厅、卧室、阳台,由中央设备统一调控空调与加湿器;
  • 工业巡检:多个手持终端同步采集振动、光照、噪声数据,实时上传至边缘服务器。

OpenHarmony 的分布式硬件虚拟化(Distributed Hardware Virtualization)能力,允许应用调用远程设备的传感器,如同本地硬件一般。而 Flutter 凭借其跨平台 UI 优势,可构建统一的交互界面。

本文将带你从零搭建一个“分布式环境监测系统”,实现:

  • 手机作为主控端;
  • 平板/智能手表作为传感节点;
  • 实时采集温度、光照、加速度数据;
  • 通过软总线聚合、可视化,并触发告警。

一、技术原理:分布式硬件如何工作?

OpenHarmony 通过DeviceManager + HardwareResourceManager提供分布式硬件访问能力:

+------------------+ +------------------+ | 主控设备 | | 传感节点 | | (Phone, Flutter) |<----->| (Tablet, Watch) | +--------+---------+ DSoftBus +--------+---------+ | | [Hardware ResourceManager] [Local Sensor] | | +--------> 虚拟化 <--------+ 远程传感器

关键流程:

  1. 主控设备发现可信传感节点;
  2. 申请使用其传感器权限;
  3. 系统在主控端创建虚拟传感器实例;
  4. 应用通过标准 API 读取数据,底层自动通过软总线透传。

✅ 优势:无需关心数据来源,代码逻辑与本地传感器一致。


二、整体架构设计

MethodChannel
DSoftBus
Flutter UI
SensorManagerPlugin
HardwareResourceManager
Remote Device: Sensor
Local Sensor Fallback
Chart / Alert UI

模块说明:

  • SensorManagerPlugin:封装原生传感器调用;
  • HardwareResourceManager:OpenHarmony 提供的分布式硬件管理器;
  • 远程/本地双模式:若节点离线,自动降级为本地采集;
  • 实时图表:使用fl_chart展示多设备数据流。

三、原生侧:分布式传感器封装(ArkTS)

1. 权限与配置

// module.json5{"module":{"requestPermissions":[{"name":"ohos.permission.DISTRIBUTED_DATASYNC"},{"name":"ohos.permission.GET_SENSORS_INFO"},{"name":"ohos.permission.ACCELEROMETER"},{"name":"ohos.permission.LIGHT"},{"name":"ohos.permission.TEMPERATURE"}]}}

2. 创建DistributedSensorManager.ets

// services/DistributedSensorManager.etsimportsensorfrom'@ohos.sensor';importdeviceManagerfrom'@ohos.distributedHardware.deviceManager';import{Callback}from'@ohos.base';typeSensorData={deviceId:string;type:'temperature'|'light'|'accelerometer';value:any;timestamp:number;};classDistributedSensorManager{privatelocalSensors:Record<string,any>={};privateremoteSubscribers:Record<string,Callback<void>>={};privateonDataCallback:((data:SensorData)=>void)|null=null;// 初始化本地传感器initLocalSensors():void{try{this.localSensors['temperature']=sensor.createTemperatureSensor();this.localSensors['light']=sensor.createLightSensor();this.localSensors['accelerometer']=sensor.createAccelerometer();}catch(err){console.error('[Sensor] Failed to create local sensors:',err);}}// 订阅本地传感器subscribeLocal(type:string,interval:number=2000):boolean{constsensorObj=this.localSensors[type];if(!sensorObj)returnfalse;sensorObj.on(interval,(data)=>{if(this.onDataCallback){this.onDataCallback({deviceId:'local',type:typeasany,value:data,timestamp:Date.now()});}});returntrue;}// 发现并订阅远程设备传感器asyncsubscribeRemote(deviceId:string,sensorType:string):Promise<boolean>{try{// 获取远程硬件资源管理器consthardwareManager=awaitdeviceManager.createHardwareResourceManager(deviceId);// 创建虚拟传感器(关键!)constremoteSensor=awaithardwareManager.createSensor(sensorType);// 订阅数据constcallback=(data:any)=>{if(this.onDataCallback){this.onDataCallback({deviceId:deviceId,type:sensorTypeasany,value:data,timestamp:Date.now()});}};remoteSensor.on(2000,callback);this.remoteSubscribers[`${deviceId}_${sensorType}`]=callback;console.info(`[Sensor] Subscribed to${sensorType}on${deviceId}`);returntrue;}catch(err){console.error(`[Sensor] Failed to subscribe remote${sensorType}:`,err);returnfalse;}}// 停止所有订阅unsubscribeAll():void{Object.values(this.localSensors).forEach(s=>s?.off());Object.values(this.remoteSubscribers).forEach(cb=>cb?.());this.remoteSubscribers={};}setDataCallback(callback:(data:SensorData)=>void):void{this.onDataCallback=callback;}}constsensorManager=newDistributedSensorManager();exportdefaultsensorManager;

3. 暴露给 Flutter(插件层)

// plugins/SensorPlugin.etsimportsensorManagerfrom'../services/DistributedSensorManager';import{MethodChannel,EventChannel}from'@flutter/engine';constMETHOD_CHANNEL='com.example.flutter/sensor/method';constEVENT_CHANNEL='com.example.flutter/sensor/event';exportclassSensorPlugin{privateeventSink:any=null;init(){sensorManager.initLocalSensors();sensorManager.setDataCallback((data)=>{if(this.eventSink){this.eventSink.success(data);}});constmethodChannel=newMethodChannel(METHOD_CHANNEL);methodChannel.setMethodCallHandler(this.handleMethod.bind(this));consteventChannel=newEventChannel(EVENT_CHANNEL);eventChannel.setStreamHandler({onListen:(_,sink)=>this.eventSink=sink,onCancel:()=>this.eventSink=null});}privateasynchandleMethod(call:any):Promise<any>{switch(call.method){case'subscribeLocal':constsuccess=sensorManager.subscribeLocal(call.arguments['type']);return{success};case'subscribeRemote':const{deviceId,sensorType}=call.arguments;constremoteSuccess=awaitsensorManager.subscribeRemote(deviceId,sensorType);return{success:remoteSuccess};case'unsubscribeAll':sensorManager.unsubscribeAll();return{success:true};}thrownewError('Unknown method');}}

在EntryAbility.ets中初始化:

newSensorPlugin().init();

四、Flutter 侧:数据接收与可视化

1. 定义数据模型

// lib/models/sensor_data.dartclassSensorData{finalString deviceId;finalString type;// 'temperature', 'light', 'accelerometer'finaldynamicvalue;finalint timestamp;SensorData({requiredthis.deviceId,requiredthis.type,requiredthis.value,requiredthis.timestamp,});factorySensorData.fromJson(Map<dynamic,dynamic>json){returnSensorData(deviceId:json['deviceId']asString,type:json['type']asString,value:json['value'],timestamp:json['timestamp']asint,);}}

2. 封装服务

// lib/services/sensor_service.dartimport'package:flutter/services.dart';import'../models/sensor_data.dart';classSensorService{staticconst_method=MethodChannel('com.example.flutter/sensor/method');staticconst_event=EventChannel('com.example.flutter/sensor/event');staticFuture<void>subscribeLocal(String type)async{await_method.invokeMethod('subscribeLocal',{'type':type});}staticFuture<void>subscribeRemote(String deviceId,String sensorType)async{await_method.invokeMethod('subscribeRemote',{'deviceId':deviceId,'sensorType':sensorType,});}staticFuture<void>unsubscribeAll()async{await_method.invokeMethod('unsubscribeAll');}staticStream<SensorData>onData()async*{awaitfor(finaleventin_event.receiveBroadcastStream()){yieldSensorData.fromJson(eventasMap);}}}

3. 使用 Riverpod 管理多设备数据流

// lib/providers/sensor_provider.dartimport'package:flutter_riverpod/flutter_riverpod.dart';import'../services/sensor_service.dart';import'../models/sensor_data.dart';finalsensorDataProvider=StateNotifierProvider<SensorDataManager,Map<String,List<SensorData>>>((ref){returnSensorDataManager();});classSensorDataManagerextendsStateNotifier<Map<String,List<SensorData>>>{late StreamSubscription _subscription;SensorDataManager():super({}){_subscription=SensorService.onData().listen((data){finaldeviceId=data.deviceId;finallist=state.putIfAbsent(deviceId,()=>[]);// 保留最近 100 条if(list.length>=100)list.removeAt(0);list.add(data);state={...state};});}Future<void>startMonitoring(List<String>remoteDevices)async{// 订阅本地awaitSensorService.subscribeLocal('temperature');awaitSensorService.subscribeLocal('light');awaitSensorService.subscribeLocal('accelerometer');// 订阅远程for(finaldeviceIdinremoteDevices){awaitSensorService.subscribeRemote(deviceId,'temperature');awaitSensorService.subscribeRemote(deviceId,'light');}}@overridevoiddispose(){_subscription.cancel();SensorService.unsubscribeAll();super.dispose();}}

4. 构建实时图表界面

// lib/screens/monitor_screen.dartimport'package:fl_chart/fl_chart.dart';classMonitorScreenextendsConsumerWidget{@overrideWidgetbuild(BuildContext context,WidgetRef ref){finalallData=ref.watch(sensorDataProvider);returnScaffold(appBar:AppBar(title:Text('分布式环境监测')),body:ListView(children:[_buildChart(allData,'temperature','温度 (°C)'),_buildChart(allData,'light','光照 (lux)'),],),);}Widget_buildChart(Map<String,List<SensorData>>dataMap,String type,String title){finallines=<LineChartBarData>[];int colorIndex=0;finalcolors=[Colors.blue,Colors.green,Colors.red,Colors.purple];dataMap.forEach((deviceId,dataList){finalfiltered=dataList.where((d)=>d.type==type).toList();if(filtered.isEmpty)return;finalpoints=filtered.asMap().entries.map((entry){finalindex=entry.key.toDouble();finalvalue=_extractValue(entry.value.value,type);returnFlSpot(index,value);}).toList();lines.add(LineChartBarData(spots:points,color:colors[colorIndex%colors.length],barWidth:2,isCurved:true,dotData:FlDotData(show:false),));colorIndex++;});returnContainer(height:200,margin:EdgeInsets.all(16),child:LineChart(LineChartData(lineBarsData:lines,titlesData:FlTitlesData(bottomTitles:AxisTitles(side:left,showTitles:false),leftTitles:AxisTitles(side:left,title:TextTitle(text:title)),),gridData:FlGridData(show:true),),),);}double_extractValue(dynamicvalue,String type){if(type=='temperature'){return(valueasMap?)?['temperature']?.toDouble()??0.0;}elseif(type=='light'){return(valueasMap?)?['lightIntensity']?.toDouble()??0.0;}return0.0;}}

五、关键问题与解决方案

问题解决方案
远程设备无对应传感器调用前先查询设备能力(deviceManager.getCapability)
软总线断开导致数据丢失原生侧监听连接状态,自动重连或降级本地
高频数据导致 UI 卡顿Dart 侧使用debounce或采样(如每秒最多1条)
多设备数据时间不同步使用timestamp字段对齐,而非本地时间

六、测试场景

  1. 手机 + 平板均安装应用;
  2. 手机启动监测,自动发现平板;
  3. 平板提供温度/光照数据,手机本地提供加速度;
  4. 遮挡平板光线,观察图表实时下降;
  5. 断开平板 Wi-Fi,系统自动切换为仅显示手机数据。

七、总结

本文实现了Flutter 应用调用 OpenHarmony 分布式传感器的完整链路,展示了:

  • 如何通过HardwareResourceManager虚拟化远程硬件;
  • 如何设计本地/远程双模兼容的健壮架构;
  • 如何在 Flutter 中高效渲染多源实时数据流。

这不仅适用于环境监测,还可扩展至:

  • 远程医疗:调用家属手表的心率数据;
  • 智慧农业:聚合田间多个土壤湿度传感器;
  • AR 协同:多设备共享空间定位信息。

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

相关新闻

  • DETR模型融合终极指南:3步打造高稳健性目标检测系统
  • 纯电动汽车Simulink仿真模型建模详细步骤。 通过文档的形式,跟着文档一步一步操作,既可以...
  • B样条曲线拟合能量约束方法介绍

最新新闻

  • C++内存对齐:从硬件原理到极致性能优化实战
  • 四大AI自动化工具对比:OpenClaw、Dify、Coze与n8n
  • 空调‌TFT彩色液晶屏模组显示方案设计
  • 白云2026正规代理记账公司怎么选?本地人推荐五家本土头部机构深度解析 - 品牌优企推荐
  • OBD_Test_ToolKit — 车载 UDS / OBD-II 渗透测试工具箱:12 阶段覆盖 + 自动判定 HTML 报告(Web UI + TSMaster)
  • 重磅|2026浪琴**售后网点新址公布最新专线同步开通 - 浪琴中国服务中心

日新闻

  • AI云原生实战05-金融AI上云最难的不是技术,是“不出事“——TCE银行风控架构拆解
  • 2026年GEOSEO优化公司选型深度测评:五大硬核标准严选,这六家重塑搜索增长新格局 - 品牌前沿专家
  • **核验!2026年7月卡地亚香港**售后网点地址及服务电话公告 - 卡地亚服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号