学 ArkUI 传感器(专题二):从加速度计到指南针,玩转硬件能力

发布时间:2026/6/14 22:07:59
学 ArkUI 传感器(专题二):从加速度计到指南针,玩转硬件能力 零基础学 ArkUI 传感器专题二从加速度计到指南针玩转硬件能力博主说你的手机里藏着十几个传感器——加速度计、陀螺仪、地磁、光线、距离、气压……在 ArkUI 中调用它们只需要几行代码今天这篇专题带你一次摸透 HarmonyOS 的传感器全家桶并实战做一个「水平仪」和「电子罗盘」。 传感器能做什么传感器检测什么应用场景加速度计ACCELEROMETER三轴加速度计步器、摇一摇、屏幕旋转陀螺仪GYROSCOPE角速度VR 头显、体感游戏地磁MAGNETIC_FIELD磁场强度电子罗盘、指南针环境光AMBIENT_LIGHT光照强度 lux自动亮度调节距离PROXIMITY物体靠近通话熄屏气压BAROMETER大气压力海拔测量心率HEART_RATE心跳健康监测⚙️ 运行环境要求项目要求设备要求真机模拟器不支持传感器DevEco Studio5.0.3.800HarmonyOS SDKAPI 12核心 APIohos.sensor️ 4 个实战案例 案例 1加速度计 — 做一个「摇一摇」检测importsensorfromohos.sensor;EntryComponentstruct ShakeDetector{StateshakeCount:number0;StatelastShakeTime:number0;StateisShaking:booleanfalse;aboutToAppear(){this.startListening();}startListening(){sensor.on(sensor.SensorType.ACCELEROMETER,(data){// 计算三轴加速度的矢量和constxdata.x;constydata.y;constzdata.z;constmagnitudeMath.sqrt(x*xy*yz*z);// 加速度 15 m/s² 视为一次摇动重力 ≈ 9.8if(magnitude15){constnowDate.now();if(now-this.lastShakeTime500){// 500ms 内只算一次this.lastShakeTimenow;this.shakeCount;this.isShakingtrue;// 300ms 后取消摇动状态setTimeout((){this.isShakingfalse;},300);}}});}build(){Column(){Text(this.isShaking? 正在摇动: 摇动手机).fontSize(24).fontWeight(FontWeight.Bold).fontColor(this.isShaking?#FF3B30:#333)Text(已摇动${this.shakeCount}次).fontSize(16).fontColor(#888).margin({top:12})Button(重置计数).margin({top:20}).backgroundColor(#E5E5EA).fontColor(#333).onClick((){this.shakeCount0;})}.width(100%).height(200).justifyContent(FlexAlign.Center)}}核心 API 说明// 订阅传感器数据持续监听sensor.on(SensorType.ACCELEROMETER,callback);// 取消订阅sensor.off(SensorType.ACCELEROMETER,callback);// 单次读取sensor.once(SensorType.ACCELEROMETER,(data){});真机运行用力摇动手机屏幕显示摇动次数。 案例 2陀螺仪 — 体感控制的旋转方块importsensorfromohos.sensor;EntryComponentstruct GyroCube{StaterotateX:number0;StaterotateY:number0;StaterotateZ:number0;aboutToAppear(){sensor.on(sensor.SensorType.GYROSCOPE,(data){// 积分角速度得到角度this.rotateXdata.x*0.1;this.rotateYdata.y*0.1;this.rotateZdata.z*0.1;});}build(){Column(){Column(){Text(3D).fontSize(32).fontColor(#fff).fontWeight(FontWeight.Bold)}.width(120).height(120).backgroundColor(#007AFF).borderRadius(16).rotate({x:1,angle:this.rotateX}).rotate({y:1,angle:this.rotateY})Text(转动手机控制方块旋转).fontSize(14).fontColor(#999).margin({top:20})}.width(100%).height(300).justifyContent(FlexAlign.Center)}} 案例 3地磁传感器 — 电子指南针importsensorfromohos.sensor;EntryComponentstruct Compass{Stateheading:number0;// 0~360 度aboutToAppear(){sensor.on(sensor.SensorType.MAGNETIC_FIELD,(data){// 根据地磁三轴数据计算方位角constheadingMath.atan2(data.y,data.x)*180/Math.PI;this.heading(heading360)%360;// 转为 0~360});}getDirection(degree:number):string{if(degree22.5||degree337.5)return北 ↑;if(degree67.5)return东北 ↗;if(degree112.5)return东 →;if(degree157.5)return东南 ↘;if(degree202.5)return南 ↓;if(degree247.5)return西南 ↙;if(degree292.5)return西 ←;return西北 ↖;}build(){Column(){// 指南针表盘Circle().width(200).height(200).fill(#F0F4FF).stroke(#007AFF).strokeWidth(3)Text(N).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#FF3B30).position({x:100,y:10})// 指针Column().width(4).height(80).backgroundColor(#FF3B30).borderRadius(2).rotate({angle:this.heading})// 度数显示Text(${Math.round(this.heading)}°).fontSize(36).fontWeight(FontWeight.Bold).fontColor(#333).margin({top:20})Text(this.getDirection(this.heading)).fontSize(18).fontColor(#007AFF).margin({top:8})}.width(100%).height(400).justifyContent(FlexAlign.Center)}} 案例 4综合实战 — 水平仪 App结合加速度计和陀螺仪做一个气泡水平仪。importsensorfromohos.sensor;EntryComponentstruct BubbleLevel{StatebubbleX:number0;StatebubbleY:number0;StateisLevel:booleantrue;aboutToAppear(){sensor.on(sensor.SensorType.ACCELEROMETER,(data){// 手机平放时重力在 Z 轴 9.8X/Y ≈ 0// X/Y 偏离 0 说明手机倾斜constthreshold0.5;this.bubbleXMath.max(-40,Math.min(40,-data.x*8));this.bubbleYMath.max(-40,Math.min(40,data.y*8));this.isLevelMath.abs(data.x)thresholdMath.abs(data.y)threshold;});}build(){Column(){Text(this.isLevel?✅ 水平:❌ 倾斜).fontSize(32).fontWeight(FontWeight.Bold).fontColor(this.isLevel?#34C759:#FF3B30)// 水平仪容器Stack(){// 外圈Circle().width(200).height(200).fill(#F0F4FF).stroke(#007AFF).strokeWidth(2)// 十字线Divider().vertical(true).height(180).color(#E0E0E0)Divider().width(180).color(#E0E0E0)// 气泡Circle().width(24).height(24).fill(#007AFF).opacity(0.7).translate({x:this.bubbleX,y:this.bubbleY})}.width(220).height(220).margin({top:20})Text(偏移: X${this.bubbleX.toFixed(1)}Y${this.bubbleY.toFixed(1)}).fontSize(14).fontColor(#999).margin({top:16})}.width(100%).height(400).justifyContent(FlexAlign.Center)}} 传感器数据对比表传感器回调频率数据维度坐标系ACCELEROMETER50~200Hzx, y, z (m/s²)设备坐标系GYROSCOPE50~200Hzx, y, z (rad/s)设备坐标系MAGNETIC_FIELD10~50Hzx, y, z (μT)设备坐标系AMBIENT_LIGHT1~10Hzintensity (lux)单值PROXIMITY1~5Hzdistance (cm)单值⚠️ 避坑指南坑原因正确做法模拟器传感器没数据模拟器没有硬件必须用真机调试传感器不触发回调忘了sensor.on()订阅在aboutToAppear中订阅数据跳变太大原始传感器噪声大用滑动平均滤波取最近 5 次均值陀螺仪角度飘移积分累积误差用地磁 加速度计做互补滤波耗电快传感器回调频率太高不需要高频率时用sensor.once()后台不工作传感器在后台被暂停申请后台任务权限 最佳实践滤波处理原始传感器噪声大用低通滤波或滑动平均频率控制不需要高频率时用setInterval节流回调真机调试传感器开发必须真机模拟器不支持性能优化aboutToDisappear中取消订阅防止内存泄漏权限申明部分传感器心率等需要health权限传感器融合结合加速度 陀螺仪 地磁得到更准确的姿态 扩展挑战计步器用加速度计检测步行步态峰值检测算法手势识别用陀螺仪识别「画圈」「挥动」等手势AR 水平仪结合相机预览 水平仪做装修辅助工具磁力计标定用「画 8 字」方法校准地磁传感器官方文档HarmonyOS 应用开发文档开发者社区华为开发者论坛欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net/

月新闻