@RitcheeQinG
2020-04-26T03:20:42.000000Z
字数 2178
阅读 1261
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 sensorA 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.事件的时间戳是最后一次测量到步数时的时间
核心逻辑如下:
public void startStepCount() {
SensorManager sensorManager = getSystemService("sensor");
Sensor countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && null != countSensor) {
// 计步传感器实现
sensorManager.rigisterListener(new SensorEventListener() {
/**
* 传感器有新事件时,不论值是否有变化,哪怕仅有时间变化也可能触发
*/
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
int stepCount = (int)event.values[0];
...
}
...
}
/**
* 注册的传感器精度有变化时
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
...
}
}, countSensor, 0)
} else {
... // 加速度传感器实现
}
}
我下载了一个Github上面的开源项目用于测试。
控制变量:二者代码完全相同,区别仅在于我修改了APP ID和计步进程ID
测试方法:摇手机,打断点,查看计步传感器的回调数值
结果:
回调中的步数约9000+,且随着我摇手机一直在增长。
不同APP名和不同计步进程回调获得的步数一致,可以确定这个步数是应用无关的,任何应用调用回调获得的都应该是这个值。