[关闭]
@RitcheeQinG 2020-04-26T03:20:42.000000Z 字数 2178 阅读 1261

Android 计步传感器入门

Android


计步模块标准实现

参考

Google官方文档

Android计步模块优化(今日步数)

Android实现简易计步器功能,隔天步数清零,查看历史运动纪录

可以看到,安卓手机提供了两种方法统计步数:

加速度传感器 步测器传感器 计步传感器
使用场景 API 19以下或手机不支持计步传感器 API19及以上 API19及以上
名称 Sensor.TYPE_ACCELEROMETER Sensor.TYPE_STEP_DETECTOR Sensor.TYPE_STEP_COUNTER
使用方式 注册传感器 + 回调 注册传感器 + 回调 注册传感器 + 回调
回调参数 未经过计算的原始数据 未统计的实时步数数据 统计过的步数数据
数据保存 手机不保存,实时获取 手机不保存,实时获取 手机保存,仅在关机时清零
权限申请 不需要申请权限 API29以上 ACTIVITY_RECOGNITION API29以上 ACTIVITY_RECOGNITION

可见三种传感器各有各的问题:

加速度传感器的数据手机不负责保存,所以需要APP进行进程保活来持续进行统计。步测器传感器同理。

计步传感器的数据手机会保存,但是这个数据每天不会自动清零,且关机会清零,所以需要APP自己负责保存和判断。

以及由于安卓的生态可能导致的各种各样的奇怪问题:目前已知部分华为手机可能不开放步测器传感器及计步传感器;小米手机和华为手机因为省电等原因可能导致其中数据不准;部分机型可能出现传感器数据临时回落,过后恢复的情况。

计步传感器:

安卓官方对计步传感器的定义(需要翻墙):

Reporting-mode: On-change

getDefaultSensor(SENSOR_TYPE_STEP_COUNTER) returns a non-wakeup sensor

A step counter reports the number of steps taken by the user since the last reboot while activited.

The measurement is reported as a uint64_t in sensors_event_t.step_counter and is reset to zero only on a system reboot.

The timestamp of the event is set to the time when the last step for that event was taken.

翻译一下:

1.报告模式为 On-change。

On-change表示传感器事件仅在测量值有变化时才会产生,传感器在HAL层被激活时也会触发一个事件,可以设置 sampling_period_ns 来控制事件产生的时间间隔。举例:假设一分钟内一步没走,那么步数传感器不会产生任何事件。假设一分钟内在走路,那么传感器会以设定的时间为间隔(比如10秒)产生事件。

2.getDefaultSensor() 方法返回一个非唤醒传感器

非唤醒传感器指传感器不会阻止SoC进入挂起状态,且不会唤醒SoC来报告数据。可以理解为如果应用没在运行,它不会主动唤醒应用,而是会保持运行,然后把事件都存在FIFO里面,如果FIFO存不下了,那么较旧的事件就会丢失。

3.计步传感器报告自上次手机重启后,传感器激活后获取到的步数。

4.测量值以int的形式返回,并且在系统重启时被重置为0

5.事件的时间戳是最后一次测量到步数时的时间

代码实现:

核心逻辑如下:

  1. public void startStepCount() {
  2. SensorManager sensorManager = getSystemService("sensor");
  3. Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  4. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && null != countSensor) {
  5. // 计步传感器实现
  6. sensorManager.rigisterListener(new SensorEventListener() {
  7. /**
  8. * 传感器有新事件时,不论值是否有变化,哪怕仅有时间变化也可能触发
  9. */
  10. @Override
  11. public void onSensorChanged(SensorEvent event) {
  12. if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
  13. int stepCount = (int)event.values[0];
  14. ...
  15. }
  16. ...
  17. }
  18. /**
  19. * 注册的传感器精度有变化时
  20. */
  21. @Override
  22. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  23. ...
  24. }
  25. }, countSensor, 0)
  26. } else {
  27. ... // 加速度传感器实现
  28. }
  29. }

测试:

我下载了一个Github上面的开源项目用于测试。

控制变量:二者代码完全相同,区别仅在于我修改了APP ID和计步进程ID

测试方法:摇手机,打断点,查看计步传感器的回调数值

结果:

回调中的步数约9000+,且随着我摇手机一直在增长。

不同APP名和不同计步进程回调获得的步数一致,可以确定这个步数是应用无关的,任何应用调用回调获得的都应该是这个值。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注