当前位置: 首页 > news >正文

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}from'@kit.SensorServiceKit'import{BusinessError}from'@kit.BasicServicesKit'@StateaccelX:number=0@StateaccelY:number=0@StateaccelZ:number=0privatesubscribed:boolean=falsesubscribeAccelerometer(){try{sensor.on(sensor.SensorId.ACCELEROMETER,(data:sensor.AccelerometerResponse)=>{this.accelX=data.xthis.accelY=data.ythis.accelZ=data.z},{interval:200000000})// 采样间隔,单位纳秒this.subscribed=true}catch(error){lete=errorasBusinessErrorconsole.error(`订阅失败:${e.code},${e.message}`)}}unsubscribeAccelerometer(){try{sensor.off(sensor.SensorId.ACCELEROMETER)this.subscribed=false}catch(error){lete=errorasBusinessErrorconsole.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 次。这个值后面详细讲
  • onoff必须成对出现,页面销毁时一定记得 off,不然后台一直吃电

摇一摇实现

加速度计接好了,摇一摇的判断逻辑很直接——三轴加速度的绝对值之和超过阈值,就是"摇了"

完整代码

import{sensor}from'@kit.SensorServiceKit'import{vibration}from'@kit.VibrationEffectKit'import{BusinessError}from'@kit.BasicServicesKit'@Entry@Componentstruct ShakePage{@StateshakeCount:number=0@StateisShaking:boolean=falseprivatelastShakeTime:number=0privateSHAKE_THRESHOLD:number=18// 加速度阈值privateSHAKE_INTERVAL:number=500// 两次摇动最小间隔(ms)privateACCEL_INTERVAL:number=50000000// 50ms采样间隔aboutToAppear(){this.startShakeDetection()}aboutToDisappear(){this.stopShakeDetection()}startShakeDetection(){try{sensor.on(sensor.SensorId.ACCELEROMETER,(data:sensor.AccelerometerResponse)=>{constacceleration=Math.abs(data.x)+Math.abs(data.y)+Math.abs(data.z)constnow=Date.now()if(acceleration>this.SHAKE_THRESHOLD&&!this.isShaking){if(now-this.lastShakeTime>this.SHAKE_INTERVAL){this.isShaking=truethis.lastShakeTime=nowthis.onShakeDetected()// 300ms后重置状态,避免一次摇动多次触发setTimeout(()=>{this.isShaking=false},300)}}},{interval:this.ACCEL_INTERVAL})}catch(error){lete=errorasBusinessErrorconsole.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.shakeCount=0})Text('用力摇晃手机试试').fontSize(14).fontColor('#999999')}.width('100%').height('100%').justifyContent(FlexAlign.Center)}}

算法讲解

核心判断就这一行:

constacceleration=Math.abs(data.x)+Math.abs(data.y)+Math.abs(data.z)

三轴加速度取绝对值求和。静止时这个值约 9.8(纯重力),使劲摇的时候能到 25+。阈值设 18是个经验值——正常走路大概 12-15,不会误触;稍微用点力摇就能到 18。

两个防抖机制缺一不可:

  1. SHAKE_INTERVAL = 500ms:两次触发至少间隔 500ms,防止快速连续触发
  2. isShaking状态锁 +setTimeout(300ms):一次摇动只算一次,300ms 内不再响应

没有防抖的话,一次摇动会触发 5-10 次回调(因为采样间隔 50ms),计数器直接飞。

采样率与功耗

采样间隔怎么选?这事儿得权衡:

间隔采样率精度功耗适用场景
10000000ns (10ms)100Hz游戏、VR
50000000ns (50ms)20Hz摇一摇、手势识别
200000000ns (200ms)5Hz屏幕旋转、基础检测
1000000000ns (1s)1Hz很低很低后台监控

摇一摇用 50ms(20Hz)刚刚好——采样够密不会漏摇,功耗也不会炸。如果你做的是计步器那种长时间运行的,建议 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 那篇如果还没看,建议搭配着看,传感器 + 相机组合能做不少有趣的东西。

http://www.jsqmd.com/news/1250568/

相关文章:

  • 2026 年 7 月新发布:常熟有实力的无机纤维喷涂工程公司电话实力厂家推荐,揭秘:高强度无机纤维喷涂的秘密工厂电话曝光-佑辰隔音保温 - 鉴选官
  • WordPress国际化多语言建站插件:解决Hreflang标签的3个报错
  • 小程序自动部署埋点
  • AI 驱动的 Rust 代码生成:从接口描述自动生成样板代码的边界探索
  • 企业级NAS建设方案
  • 2026十大生产制造ERP:警惕出货量误导,基于MES集成度与工单闭环逻辑重排
  • 椰林海鲜码头企业新愿景是什么?:怀信坚守本心 - 17728181569
  • 陕西正规美容培训学校:行业标准解析与选型指南 - 商业大观
  • 基于人脸识别的无人值守自习室预约系统设计与实现
  • Kimi K3 实测:2.8T 参数、100 万上下文,我让它做了网页、PPT 和 3D 游戏
  • 阿里云服务器配置 LLM 推理服务教程
  • 具身智能重构高墙透明治理:视频孪生+无感空间感知,打造司法监所全域穿透防线
  • 汽车四轮称重系统十大品牌前十榜单揭晓,浙江润鑫质量稳定品质靠谱厂家值得信赖 - 品牌速递
  • 2026防腐压力传感器前十榜单公示,广东犸力登上权威行业排行榜 - 品牌速递
  • Node.js三方库鸿蒙 PC 移植:鸿蒙PC开发者面对面 · 线下课件PPT分享
  • OpenHarmony 小鸿 AI 开发实战 02:从板级源码读懂 WS63、CI1302、ST7789 与外部 Flash
  • HarmonyOS7 嵌套滚动:Scroll + List 嵌套滚动的正确姿势
  • 因算力紧缺,月之暗面Kimi宣布暂停C端新用户订阅;ASML回应向全球员工发2万欧元股权激励;Qwen3.8-Max预览版上线 | 极客头条
  • 2026深圳盐田搬家公司深度测评全攻略|资质合规口碑靠谱+街坊实测口碑过硬+避坑指南 - 厚道搬家
  • 边贸黄金“避坑战”实勘:2026凭祥正规回收老牌三强全维度深度拆解 - 华金汇黄金回收
  • Unlayer:可嵌入产品的内容创作平台,数天上线赋能多场景创作!
  • 七大算法完整总结:冒泡 / 插入 / 选择 / 快排 / 归并 / 堆排 + 二分查找
  • 2026年北京周边宠物训练学校权威排行揭晓
  • 豆包视频去水印方法怎么用?2026个人收藏向实用教程 - 免费软件工具方法教程
  • 【关注可白嫖源码】--课程设计--毕业设计--springboot体育馆运营管理平台[编号:project75681](案件分析)
  • LaCo: Large Language Model Pruning via Layer Collapse 解读
  • Kimi K3横空出世!中国AI模型仅用几周便反超美国,市场震动,闭源模型岌岌可危!
  • 2026图片去水印用什么工具?手机与电脑免费去水印方法合集 - 免费软件工具方法教程
  • 不要像写Java一样写Go
  • 谁还在硬啃组态屏?我直接喂饭