HarmonyOS7 传感器开发:加速度计做个摇一摇,原来这么简单

📅 发布时间:2026/7/23 22:45:20
HarmonyOS7 传感器开发:加速度计做个摇一摇,原来这么简单 文章目录前言传感器能做什么权限声明加速度计接入摇一摇实现完整代码算法讲解采样率与功耗其他传感器速览写在最后前言摇一摇这个功能最早是微信搞出来的结果成了移动端的经典交互。在 HarmonyOS7 上实现摇一摇比我想象的简单多了——加速度计数据就三个值判断逻辑十几行代码回调里加个震动就完事。但传感器开发有不少细节权限怎么申、采样率怎么选、功耗怎么控。这篇从加速度计接入到摇一摇完整实现顺便把其他传感器也扫一遍。传感器能做什么HarmonyOS7 支持的传感器不少常见的这些传感器数据能干啥加速度计x/y/z 三轴加速度摇一摇、计步、屏幕旋转陀螺仪x/y/z 三轴角速度姿态检测、VR 头控磁力计x/y/z 三轴磁场指南针、金属检测接近光距离值通话时熄屏环境光光照强度自动亮度气压计大气压值海拔估算、天气计步器步数运动统计心率BPM健康监测每个传感器的接入方式都一样on订阅 → 回调拿数据 →off取消订阅。套路统一学会一个就会所有。权限声明加速度计需要权限module.json5里加上{requestPermissions:[{name:ohos.permission.ACCELEROMETER}]}这个权限不需要动态申请声明了就行。但心率传感器那类敏感数据需要ohos.permission.HEALTH_DATA那个要动态授权。加速度计接入核心就三步导入模块、订阅数据、取消订阅。import{sensor}fromkit.SensorServiceKitimport{BusinessError}fromkit.BasicServicesKitStateaccelX:number0StateaccelY:number0StateaccelZ:number0privatesubscribed:booleanfalsesubscribeAccelerometer(){try{sensor.on(sensor.SensorId.ACCELEROMETER,(data:sensor.AccelerometerResponse){this.accelXdata.xthis.accelYdata.ythis.accelZdata.z},{interval:200000000})// 采样间隔单位纳秒this.subscribedtrue}catch(error){leteerrorasBusinessErrorconsole.error(订阅失败:${e.code},${e.message})}}unsubscribeAccelerometer(){try{sensor.off(sensor.SensorId.ACCELEROMETER)this.subscribedfalse}catch(error){leteerrorasBusinessErrorconsole.error(取消订阅失败:${e.code})}}关键讲解sensor.SensorId.ACCELEROMETER传感器类型标识加速度计固定用这个data.x / data.y / data.z三轴加速度值单位 m/s²。手机静止平放时z 轴约等于 9.8重力x/y 接近 0{ interval: 200000000 }采样间隔单位是纳秒。200000000ns 200ms也就是每秒采样 5 次。这个值后面详细讲on和off必须成对出现页面销毁时一定记得 off不然后台一直吃电摇一摇实现加速度计接好了摇一摇的判断逻辑很直接——三轴加速度的绝对值之和超过阈值就是摇了。完整代码import{sensor}fromkit.SensorServiceKitimport{vibration}fromkit.VibrationEffectKitimport{BusinessError}fromkit.BasicServicesKitEntryComponentstruct ShakePage{StateshakeCount:number0StateisShaking:booleanfalseprivatelastShakeTime:number0privateSHAKE_THRESHOLD:number18// 加速度阈值privateSHAKE_INTERVAL:number500// 两次摇动最小间隔(ms)privateACCEL_INTERVAL:number50000000// 50ms采样间隔aboutToAppear(){this.startShakeDetection()}aboutToDisappear(){this.stopShakeDetection()}startShakeDetection(){try{sensor.on(sensor.SensorId.ACCELEROMETER,(data:sensor.AccelerometerResponse){constaccelerationMath.abs(data.x)Math.abs(data.y)Math.abs(data.z)constnowDate.now()if(accelerationthis.SHAKE_THRESHOLD!this.isShaking){if(now-this.lastShakeTimethis.SHAKE_INTERVAL){this.isShakingtruethis.lastShakeTimenowthis.onShakeDetected()// 300ms后重置状态避免一次摇动多次触发setTimeout((){this.isShakingfalse},300)}}},{interval:this.ACCEL_INTERVAL})}catch(error){leteerrorasBusinessErrorconsole.error(启动检测失败:${e.code})}}stopShakeDetection(){try{sensor.off(sensor.SensorId.ACCELEROMETER)}catch(error){// ignore}}onShakeDetected(){this.shakeCount// 震动反馈try{vibration.vibrate(vibration.VibrateType.VIBRATOR_LIGHT)}catch(e){// 没有震动模块就算了}}build(){Column({space:20}){Text(摇一摇计数器).fontSize(28).fontWeight(FontWeight.Bold)Text(${this.shakeCount}).fontSize(72).fontColor(#FF6D00).fontWeight(FontWeight.Bold)Button(重置).onClick((){this.shakeCount0})Text(用力摇晃手机试试).fontSize(14).fontColor(#999999)}.width(100%).height(100%).justifyContent(FlexAlign.Center)}}算法讲解核心判断就这一行constaccelerationMath.abs(data.x)Math.abs(data.y)Math.abs(data.z)三轴加速度取绝对值求和。静止时这个值约 9.8纯重力使劲摇的时候能到 25。阈值设 18是个经验值——正常走路大概 12-15不会误触稍微用点力摇就能到 18。两个防抖机制缺一不可SHAKE_INTERVAL 500ms两次触发至少间隔 500ms防止快速连续触发isShaking状态锁 setTimeout(300ms)一次摇动只算一次300ms 内不再响应没有防抖的话一次摇动会触发 5-10 次回调因为采样间隔 50ms计数器直接飞。采样率与功耗采样间隔怎么选这事儿得权衡间隔采样率精度功耗适用场景10000000ns (10ms)100Hz高高游戏、VR50000000ns (50ms)20Hz中中摇一摇、手势识别200000000ns (200ms)5Hz低低屏幕旋转、基础检测1000000000ns (1s)1Hz很低很低后台监控摇一摇用 50ms20Hz刚刚好——采样够密不会漏摇功耗也不会炸。如果你做的是计步器那种长时间运行的建议 200ms 甚至更低不然电池扛不住。真心建议不用的时候一定 off。我见过一个 App 后台跑着传感器没关4 小时掉电 20%。用户骂的你听不见。其他传感器速览加速度计学会了其他传感器套路一模一样换下SensorId就行陀螺仪sensor.SensorId.GYROSCOPE回调里data.x/y/z是角速度磁力计sensor.SensorId.MAGNETIC_FIELD做指南针配合GeomagneticField算偏角接近光sensor.SensorId.PROXIMITY通话时检测脸靠近就熄屏data.distance环境光sensor.SensorId.AMBIENT_LIGHTdata.intensity是勒克斯值计步器sensor.SensorId.PEDOMETERdata.steps直接给你步数不用自己算心率sensor.SensorId.HEART_RATE需要额外权限穿戴设备才支持每种传感器的on/off用法完全一致唯一区别是回调数据的字段名不同。官方文档里有每个传感器的 Response 类型定义查一下就行。写在最后传感器开发真没那么难——on订阅、回调拿数据、off释放三步走天下。摇一摇的实现核心就是加速度阈值判断 防抖十几行代码搞定。但功耗控制和资源释放这些细节才是区分能用和好用的关键——不用就关、采样率别贪高、页面销毁一定 off。下次如果你做计步器、指南针或者体感游戏回来翻这篇就行套路都一样。Camera 那篇如果还没看建议搭配着看传感器 相机组合能做不少有趣的东西。