转自:http://blog.csdn.net/morrowindxie/article/details/53885942
最近各平台都推出行走计步相关的活动,无奈博主的烂手机只有Accelerometer,Light sensor,Proximity sensor,无法记录行走。于是翻查源码,模拟了一个。
要模拟计步器,必须修改android源码,我动到的在\frameworks\native\servises\sensorservice\ 这个目录下。其中SensorService.cpp的onFirstRef()是注册虚拟传感器的代码点。这里我参考了Gravitity sensor、Orientation sensor等的这类虚拟sensor的添加方法。因为这样实现比较简单,不然就要去hardware那一层添加,麻烦度暴增。
而且因为我手机里连gyroscope也没有,所以只好想办法用Light sensor做了替换,以免条件判断不成立。如果你的手机已经有陀螺仪了,就不用替换Light相关的部分了。
- void SensorService::onFirstRef()
- {
- ALOGD("nuSensorService starting...");
- SensorDevice& dev(SensorDevice::getInstance());
- if (dev.initCheck() == NO_ERROR) {
- sensor_t const* list;
- ssize_t count = dev.getSensorList(&list);
- if (count > 0) {
- ssize_t orientationIndex = -1;
- bool hasGyro = false, hasAccel = false, hasMag = false;
- uint32_t virtualSensorsNeeds =
- (1< 0) {
- batchingSupported = true;
- break;
- }
- }
- if (batchingSupported) {
- // Increase socket buffer size to a max of 100 KB for batching capabilities.
- mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
- } else {
- mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
- }
- // Compare the socketBufferSize value against the system limits and limit
- // it to maxSystemSocketBufferSize if necessary.
- FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
- char line[128];
- if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
- line[sizeof(line) - 1] = '\0';
- size_t maxSystemSocketBufferSize;
- sscanf(line, "%zu", &maxSystemSocketBufferSize);
- if (mSocketBufferSize > maxSystemSocketBufferSize) {
- mSocketBufferSize = maxSystemSocketBufferSize;
- }
- }
- if (fp) {
- fclose(fp);
- }
- mWakeLockAcquired = false;
- mLooper = new Looper(false);
- const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
- mSensorEventBuffer = new sensors_event_t[minBufferSize];
- mSensorEventScratch = new sensors_event_t[minBufferSize];
- mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
- mCurrentOperatingMode = NORMAL;
- mNextSensorRegIndex = 0;
- for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
- mLastNSensorRegistrations.push();
- }
- mInitCheck = NO_ERROR;
- mAckReceiver = new SensorEventAckReceiver(this);
- mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
- run("SensorService", PRIORITY_URGENT_DISPLAY);
- }
- }
- }
void SensorService::onFirstRef()
{
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);
if (count > 0) {
ssize_t orientationIndex = -1;
bool hasGyro = false, hasAccel = false, hasMag = false;
uint32_t virtualSensorsNeeds =
(1< 0) {
batchingSupported = true;
break;
}
}
if (batchingSupported) {
// Increase socket buffer size to a max of 100 KB for batching capabilities.
mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
} else {
mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
}
// Compare the socketBufferSize value against the system limits and limit
// it to maxSystemSocketBufferSize if necessary.
FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
char line[128];
if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
line[sizeof(line) - 1] = '\0';
size_t maxSystemSocketBufferSize;
sscanf(line, "%zu", &maxSystemSocketBufferSize);
if (mSocketBufferSize > maxSystemSocketBufferSize) {
mSocketBufferSize = maxSystemSocketBufferSize;
}
}
if (fp) {
fclose(fp);
}
mWakeLockAcquired = false;
mLooper = new Looper(false);
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
mLastNSensorRegistrations.push();
}
mInitCheck = NO_ERROR;
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
}
}
}
另外在SensorFusion.cpp的构造函数里也要将gyro替换成light,不然没有陀螺仪的话,Fusion没办法初始化成功。
// 2016-12-22 morrowindxie replaced by light sensor if no gyroscope.
//if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
if (list[i].type == SENSOR_TYPE_LIGHT) {
后来发现替换成Light倒有个好处是能借用它来自动判断白天黑夜。例如Lux小于多少认为在黑暗环境下,就停止记步等。不过我的样例里暂时还没用到它,而只是采用了固定的算法:每秒钟记一步,每天根据设定好的开始时间跟结束时间片,累计总的步数这样。
最后贴上StepSensor.cpp和.h的代码,这两个文件都是新增的。这个文件里面包含了两个sensor类,一个是StepCounter,一个是StepDetector。StepCounter根据官方定义,每次手机重启后归零,写的字段是u64.step_counter,为开机以来的总步数。StepDetector根据定义,检测到走步的时候,data[0]置1,否则data[0]置0,然后上报消息。
我的样例里,走路的时间,定死在代码里了(后续想弄个配置文件放到sd卡里,代码读取配置文件来加载走路的时间段,更加灵活一点),简单模拟了白天的随机走路(主要是根据tm结构中的wday跟yday来做简单的随机,具体算法见代码),这样看起来比较真实点,不然每天固定时间开始运动,步数都一样多那也太假了。当然你愿意,改成所有时间都在走路,每秒走3步也无不可,不过小心被一些平台抓到作弊给封号了,哈哈。
StepSensor.cpp
- /*
- * Copyright (C) 2016 Morrowind.Xie
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * This project is an adaptation of the original fbvncserver for the iPAQ
- * and Zaurus.
- */
- #include
- #include
- #include
- #include
- #include
- #include "StepSensor.h"
- #include "SensorDevice.h"
- #include "SensorFusion.h"
- // Rule sample: 19:xx:yy ~ 21:yy:xx
- // Which xx = (tm_wday+3)^2 % 60, yy = (tm_yday+3)^2 % 60.
- // To get a random step count for each day.
- namespace android {
- // ---------------------------------------------------------------------------
- StepCounterSensor::StepCounterSensor()
- : mSensorDevice(SensorDevice::getInstance()),
- mSensorFusion(SensorFusion::getInstance())
- {
- ALOGD("StepCounterSensor initializing...");
- time_t timeNow;
- time(&timeNow);
- struct tm *localTimeNow = localtime(&timeNow);
- mLastReportTime = *localTimeNow;
- mStepCount = 0;
- }
- typedef struct {
- int startHour;
- int endHour;
- } WALKING;
- static WALKING walkingTimes[] = {
- {6, 7}, {8, 11}, {14, 16}, {19, 20}
- };
- static int nbrSegments = sizeof(walkingTimes)/sizeof(WALKING);
- static int countDailyCumulateSteps(struct tm *now) {
- int walkingSeconds = 0;
- int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;
- int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;
- int secStart, secEnd, secNow;
- for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;
- if(secEnd < secNow) {
- walkingSeconds += (secEnd-secStart);
- } else if(secStart < secNow) {
- walkingSeconds += (secNow-secStart);
- }
- }
- return walkingSeconds;
- }
- static int countPeriodSteps(struct tm *beginTime, struct tm *endTime) {
- int beginSteps = countDailyCumulateSteps(beginTime);
- int endSteps = countDailyCumulateSteps(endTime);
- int steps = 0;
- int offsetDays = endTime->tm_yday-beginTime->tm_yday;
- int offsetHours = 0;
- if(offsetDays < 0) {
- offsetDays = 1;
- }
- if(offsetDays > 0) {
- for(int i=0; itm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
- if(now->tm_hour != mLastReportTime.tm_hour
- || now->tm_min != mLastReportTime.tm_min
- || now->tm_sec != mLastReportTime.tm_sec) {
- mStepCount += countPeriodSteps(&mLastReportTime, now);
- mLastReportTime = *now;
- *outEvent = event;
- outEvent->u64.step_counter = (uint64_t)mStepCount;
- outEvent->sensor = '_scs';
- outEvent->type = SENSOR_TYPE_STEP_COUNTER;
- return true;
- }
- }
- return false;
- }
- status_t StepCounterSensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(ident, enabled);
- }
- status_t StepCounterSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
- return mSensorFusion.setDelay(ident, ns);
- }
- Sensor StepCounterSensor::getSensor() const {
- sensor_t hwSensor;
- hwSensor.name = "Step Counter";
- hwSensor.vendor = "MorrowindXie";
- hwSensor.version = 1;
- hwSensor.handle = '_scs';
- hwSensor.type = SENSOR_TYPE_STEP_COUNTER;
- hwSensor.maxRange = 90000000.0f;
- hwSensor.resolution = 1.0f;
- hwSensor.power = mSensorFusion.getPowerUsage();
- hwSensor.minDelay = mSensorFusion.getMinDelay();
- Sensor sensor(&hwSensor);
- return sensor;
- }
- // ---------------------------------------------------------------------------
- StepDetectorSensor::StepDetectorSensor()
- : mSensorDevice(SensorDevice::getInstance()),
- mSensorFusion(SensorFusion::getInstance())
- {
- ALOGD("StepDetectorSensor initializing...");
- mLastReportSeconds = 0;
- }
- bool StepDetectorSensor::process(sensors_event_t* outEvent,
- const sensors_event_t& event)
- {
- if(event.type == SENSOR_TYPE_ACCELEROMETER) {
- *outEvent = event;
- outEvent->data[0] = 0.0f;
- outEvent->sensor = '_sds';
- outEvent->type = SENSOR_TYPE_STEP_DETECTOR;
- time_t timeNow;
- time(&timeNow);
- struct tm *now = localtime(&timeNow);
- //ALOGD("StepCounterSensor process() event.type=%d, now=%d-%d-%d %d:%d:%d\n", event.type,
- // now->tm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
- int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;
- int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;
- int secStart, secEnd, secNow;
- for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;
- if(secNow > secStart && secNow <= secEnd && secNow != mLastReportSeconds) {
- mLastReportSeconds = secNow;
- outEvent->data[0] = 1.0f;
- break;
- }
- }
- return true;
- }
- return false;
- }
- status_t StepDetectorSensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(ident, enabled);
- }
- status_t StepDetectorSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
- return mSensorFusion.setDelay(ident, ns);
- }
- Sensor StepDetectorSensor::getSensor() const {
- sensor_t hwSensor;
- hwSensor.name = "Step Detector";
- hwSensor.vendor = "MorrowindXie";
- hwSensor.version = 1;
- hwSensor.handle = '_sds';
- hwSensor.type = SENSOR_TYPE_STEP_DETECTOR;
- hwSensor.maxRange = 1.0f;
- hwSensor.resolution = 1.0f;
- hwSensor.power = mSensorFusion.getPowerUsage();
- hwSensor.minDelay = mSensorFusion.getMinDelay();
- Sensor sensor(&hwSensor);
- return sensor;
- }
- // ---------------------------------------------------------------------------
- }; // namespace android
/*
* Copyright (C) 2016 Morrowind.Xie
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* This project is an adaptation of the original fbvncserver for the iPAQ
* and Zaurus.
*/
#include
#include
#include
#include
#include
#include "StepSensor.h"
#include "SensorDevice.h"
#include "SensorFusion.h"
// Rule sample: 19:xx:yy ~ 21:yy:xx
// Which xx = (tm_wday+3)^2 % 60, yy = (tm_yday+3)^2 % 60.
// To get a random step count for each day.
namespace android {
// ---------------------------------------------------------------------------
StepCounterSensor::StepCounterSensor()
: mSensorDevice(SensorDevice::getInstance()),
mSensorFusion(SensorFusion::getInstance())
{
ALOGD("StepCounterSensor initializing...");
time_t timeNow;
time(&timeNow);
struct tm *localTimeNow = localtime(&timeNow);
mLastReportTime = *localTimeNow;
mStepCount = 0;
}
typedef struct {
int startHour;
int endHour;
} WALKING;
static WALKING walkingTimes[] = {
{6, 7}, {8, 11}, {14, 16}, {19, 20}
};
static int nbrSegments = sizeof(walkingTimes)/sizeof(WALKING);
static int countDailyCumulateSteps(struct tm *now) {
int walkingSeconds = 0;
int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;
int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;
int secStart, secEnd, secNow;
for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;
if(secEnd < secNow) {
walkingSeconds += (secEnd-secStart);
} else if(secStart < secNow) {
walkingSeconds += (secNow-secStart);
}
}
return walkingSeconds;
}
static int countPeriodSteps(struct tm *beginTime, struct tm *endTime) {
int beginSteps = countDailyCumulateSteps(beginTime);
int endSteps = countDailyCumulateSteps(endTime);
int steps = 0;
int offsetDays = endTime->tm_yday-beginTime->tm_yday;
int offsetHours = 0;
if(offsetDays < 0) {
offsetDays = 1;
}
if(offsetDays > 0) {
for(int i=0; itm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
if(now->tm_hour != mLastReportTime.tm_hour
|| now->tm_min != mLastReportTime.tm_min
|| now->tm_sec != mLastReportTime.tm_sec) {
mStepCount += countPeriodSteps(&mLastReportTime, now);
mLastReportTime = *now;
*outEvent = event;
outEvent->u64.step_counter = (uint64_t)mStepCount;
outEvent->sensor = '_scs';
outEvent->type = SENSOR_TYPE_STEP_COUNTER;
return true;
}
}
return false;
}
status_t StepCounterSensor::activate(void* ident, bool enabled) {
return mSensorFusion.activate(ident, enabled);
}
status_t StepCounterSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
return mSensorFusion.setDelay(ident, ns);
}
Sensor StepCounterSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Step Counter";
hwSensor.vendor = "MorrowindXie";
hwSensor.version = 1;
hwSensor.handle = '_scs';
hwSensor.type = SENSOR_TYPE_STEP_COUNTER;
hwSensor.maxRange = 90000000.0f;
hwSensor.resolution = 1.0f;
hwSensor.power = mSensorFusion.getPowerUsage();
hwSensor.minDelay = mSensorFusion.getMinDelay();
Sensor sensor(&hwSensor);
return sensor;
}
// ---------------------------------------------------------------------------
StepDetectorSensor::StepDetectorSensor()
: mSensorDevice(SensorDevice::getInstance()),
mSensorFusion(SensorFusion::getInstance())
{
ALOGD("StepDetectorSensor initializing...");
mLastReportSeconds = 0;
}
bool StepDetectorSensor::process(sensors_event_t* outEvent,
const sensors_event_t& event)
{
if(event.type == SENSOR_TYPE_ACCELEROMETER) {
*outEvent = event;
outEvent->data[0] = 0.0f;
outEvent->sensor = '_sds';
outEvent->type = SENSOR_TYPE_STEP_DETECTOR;
time_t timeNow;
time(&timeNow);
struct tm *now = localtime(&timeNow);
//ALOGD("StepCounterSensor process() event.type=%d, now=%d-%d-%d %d:%d:%d\n", event.type,
// now->tm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;
int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;
int secStart, secEnd, secNow;
for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;
if(secNow > secStart && secNow <= secEnd && secNow != mLastReportSeconds) {
mLastReportSeconds = secNow;
outEvent->data[0] = 1.0f;
break;
}
}
return true;
}
return false;
}
status_t StepDetectorSensor::activate(void* ident, bool enabled) {
return mSensorFusion.activate(ident, enabled);
}
status_t StepDetectorSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
return mSensorFusion.setDelay(ident, ns);
}
Sensor StepDetectorSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Step Detector";
hwSensor.vendor = "MorrowindXie";
hwSensor.version = 1;
hwSensor.handle = '_sds';
hwSensor.type = SENSOR_TYPE_STEP_DETECTOR;
hwSensor.maxRange = 1.0f;
hwSensor.resolution = 1.0f;
hwSensor.power = mSensorFusion.getPowerUsage();
hwSensor.minDelay = mSensorFusion.getMinDelay();
Sensor sensor(&hwSensor);
return sensor;
}
// ---------------------------------------------------------------------------
}; // namespace android
- /*
- * Copyright (C) 2016 Morrowind.Xie
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * This project is an adaptation of the original fbvncserver for the iPAQ
- * and Zaurus.
- */
- #ifndef ANDROID_STEP_SENSOR_H
- #define ANDROID_STEP_SENSOR_H
- #include
- #include
- #include
- #include
- #include "SensorInterface.h"
- // ---------------------------------------------------------------------------
- namespace android {
- // ---------------------------------------------------------------------------
- class SensorDevice;
- class SensorFusion;
- class StepCounterSensor : public SensorInterface {
- SensorDevice& mSensorDevice;
- SensorFusion& mSensorFusion;
- int mStepCount;
- struct tm mLastReportTime;
- public:
- StepCounterSensor();
- virtual bool process(sensors_event_t* outEvent,
- const sensors_event_t& event);
- virtual status_t activate(void* ident, bool enabled);
- virtual status_t setDelay(void* ident, int handle, int64_t ns);
- virtual Sensor getSensor() const;
- virtual bool isVirtual() const { return true; }
- };
- class StepDetectorSensor : public SensorInterface {
- SensorDevice& mSensorDevice;
- SensorFusion& mSensorFusion;
- int mLastReportSeconds;
- public:
- StepDetectorSensor();
- virtual bool process(sensors_event_t* outEvent,
- const sensors_event_t& event);
- virtual status_t activate(void* ident, bool enabled);
- virtual status_t setDelay(void* ident, int handle, int64_t ns);
- virtual Sensor getSensor() const;
- virtual bool isVirtual() const { return true; }
- };
- // ---------------------------------------------------------------------------
- }; // namespace android
- #endif // ANDROID_STEP_SENSOR_H
/*
* Copyright (C) 2016 Morrowind.Xie
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* This project is an adaptation of the original fbvncserver for the iPAQ
* and Zaurus.
*/
#ifndef ANDROID_STEP_SENSOR_H
#define ANDROID_STEP_SENSOR_H
#include
#include
#include
#include
#include "SensorInterface.h"
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
class SensorDevice;
class SensorFusion;
class StepCounterSensor : public SensorInterface {
SensorDevice& mSensorDevice;
SensorFusion& mSensorFusion;
int mStepCount;
struct tm mLastReportTime;
public:
StepCounterSensor();
virtual bool process(sensors_event_t* outEvent,
const sensors_event_t& event);
virtual status_t activate(void* ident, bool enabled);
virtual status_t setDelay(void* ident, int handle, int64_t ns);
virtual Sensor getSensor() const;
virtual bool isVirtual() const { return true; }
};
class StepDetectorSensor : public SensorInterface {
SensorDevice& mSensorDevice;
SensorFusion& mSensorFusion;
int mLastReportSeconds;
public:
StepDetectorSensor();
virtual bool process(sensors_event_t* outEvent,
const sensors_event_t& event);
virtual status_t activate(void* ident, bool enabled);
virtual status_t setDelay(void* ident, int handle, int64_t ns);
virtual Sensor getSensor() const;
virtual bool isVirtual() const { return true; }
};
// ---------------------------------------------------------------------------
}; // namespace android
#endif // ANDROID_STEP_SENSOR_H
代码添加修改完成后,将同目录下的Android.mk文件里,LOCAL_SRC_FILES段增加StepSensor.cpp。然后就可以mm进行模块编译了。
编译结果在out\target\product\%prj_name%\system\lib\libsensorservice.so,还有一个lib64下同名的so库。我的版本是Android6.0,所以有lib64。如果代码比较老,可能只有一个so。
手机root之后,把这两个so对应替换到手机文件系统的/system/lib跟/system/lib64下,然后重启手机就可以工作了。
apk里对应的sensor type是Sensor.TYPE_STEP_COUNTER跟Sensor.TYPE_STEP_DETECTOR。