Android模拟计步器,即Step Counter Sensor, Step Detector Sensor

转自: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相关的部分了。

  1. void SensorService::onFirstRef()  
  2. {  
  3.     ALOGD("nuSensorService starting...");  
  4.     SensorDevice& dev(SensorDevice::getInstance());  
  5.   
  6.     if (dev.initCheck() == NO_ERROR) {  
  7.         sensor_t const* list;  
  8.         ssize_t count = dev.getSensorList(&list);  
  9.         if (count > 0) {  
  10.             ssize_t orientationIndex = -1;  
  11.             bool hasGyro = false, hasAccel = false, hasMag = false;  
  12.             uint32_t virtualSensorsNeeds =  
  13.                     (1< 0) {  
  14.                     batchingSupported = true;  
  15.                     break;  
  16.                 }  
  17.             }  
  18.   
  19.             if (batchingSupported) {  
  20.                 // Increase socket buffer size to a max of 100 KB for batching capabilities.  
  21.                 mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;  
  22.             } else {  
  23.                 mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;  
  24.             }  
  25.   
  26.             // Compare the socketBufferSize value against the system limits and limit  
  27.             // it to maxSystemSocketBufferSize if necessary.  
  28.             FILE *fp = fopen("/proc/sys/net/core/wmem_max""r");  
  29.             char line[128];  
  30.             if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {  
  31.                 line[sizeof(line) - 1] = '\0';  
  32.                 size_t maxSystemSocketBufferSize;  
  33.                 sscanf(line, "%zu", &maxSystemSocketBufferSize);  
  34.                 if (mSocketBufferSize > maxSystemSocketBufferSize) {  
  35.                     mSocketBufferSize = maxSystemSocketBufferSize;  
  36.                 }  
  37.             }  
  38.             if (fp) {  
  39.                 fclose(fp);  
  40.             }  
  41.   
  42.             mWakeLockAcquired = false;  
  43.             mLooper = new Looper(false);  
  44.             const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;  
  45.             mSensorEventBuffer = new sensors_event_t[minBufferSize];  
  46.             mSensorEventScratch = new sensors_event_t[minBufferSize];  
  47.             mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];  
  48.             mCurrentOperatingMode = NORMAL;  
  49.   
  50.             mNextSensorRegIndex = 0;  
  51.             for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {  
  52.                 mLastNSensorRegistrations.push();  
  53.             }  
  54.   
  55.             mInitCheck = NO_ERROR;  
  56.             mAckReceiver = new SensorEventAckReceiver(this);  
  57.             mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);  
  58.             run("SensorService", PRIORITY_URGENT_DISPLAY);  
  59.         }  
  60.     }  
  61. }  
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

  1. /* 
  2.  * Copyright (C) 2016 Morrowind.Xie 
  3.  * 
  4.  * This program is free software; you can redistribute it and/or modify it 
  5.  * under the terms of the GNU General Public License as published by the 
  6.  * Free Software Foundation; either version 2, or (at your option) any 
  7.  * later version. 
  8.  * 
  9.  * This program is distributed in the hope that it will be useful, but 
  10.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  12.  * General Public License for more details. 
  13.  * 
  14.  * This project is an adaptation of the original fbvncserver for the iPAQ 
  15.  * and Zaurus. 
  16.  */  
  17.   
  18. #include   
  19. #include   
  20. #include   
  21.   
  22. #include   
  23.   
  24. #include   
  25.   
  26. #include "StepSensor.h"  
  27. #include "SensorDevice.h"  
  28. #include "SensorFusion.h"  
  29.   
  30. // Rule sample: 19:xx:yy ~ 21:yy:xx  
  31. // Which xx = (tm_wday+3)^2 % 60, yy = (tm_yday+3)^2 % 60.  
  32. // To get a random step count for each day.  
  33. namespace android {  
  34. // ---------------------------------------------------------------------------  
  35.   
  36. StepCounterSensor::StepCounterSensor()  
  37.     : mSensorDevice(SensorDevice::getInstance()),  
  38.       mSensorFusion(SensorFusion::getInstance())  
  39. {  
  40.     ALOGD("StepCounterSensor initializing...");  
  41.     time_t timeNow;  
  42.     time(&timeNow);  
  43.     struct tm *localTimeNow = localtime(&timeNow);  
  44.     mLastReportTime = *localTimeNow;  
  45.     mStepCount = 0;  
  46. }  
  47.   
  48. typedef struct {  
  49.     int startHour;  
  50.     int endHour;  
  51. } WALKING;  
  52. static WALKING walkingTimes[] = {  
  53.     {6, 7}, {8, 11}, {14, 16}, {19, 20}  
  54. };  
  55. static int nbrSegments = sizeof(walkingTimes)/sizeof(WALKING);  
  56. static int countDailyCumulateSteps(struct tm *now) {  
  57.     int walkingSeconds = 0;  
  58.     int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;  
  59.     int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;  
  60.     int secStart, secEnd, secNow;  
  61.     for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;  
  62.         if(secEnd < secNow) {  
  63.             walkingSeconds += (secEnd-secStart);  
  64.         } else if(secStart < secNow) {  
  65.             walkingSeconds += (secNow-secStart);  
  66.         }  
  67.     }  
  68.     return walkingSeconds;  
  69. }  
  70.   
  71. static int countPeriodSteps(struct tm *beginTime, struct tm *endTime) {  
  72.     int beginSteps = countDailyCumulateSteps(beginTime);  
  73.     int endSteps = countDailyCumulateSteps(endTime);  
  74.     int steps = 0;  
  75.     int offsetDays = endTime->tm_yday-beginTime->tm_yday;  
  76.     int offsetHours = 0;  
  77.     if(offsetDays < 0) {  
  78.         offsetDays = 1;  
  79.     }  
  80.     if(offsetDays > 0) {  
  81.         for(int i=0; itm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);  
  82.   
  83.         if(now->tm_hour != mLastReportTime.tm_hour  
  84.                 || now->tm_min != mLastReportTime.tm_min  
  85.                 || now->tm_sec != mLastReportTime.tm_sec) {  
  86.             mStepCount += countPeriodSteps(&mLastReportTime, now);  
  87.             mLastReportTime = *now;  
  88.             *outEvent = event;  
  89.             outEvent->u64.step_counter = (uint64_t)mStepCount;  
  90.             outEvent->sensor = '_scs';  
  91.             outEvent->type = SENSOR_TYPE_STEP_COUNTER;  
  92.             return true;  
  93.         }  
  94.     }  
  95.     return false;  
  96. }  
  97.   
  98. status_t StepCounterSensor::activate(void* ident, bool enabled) {  
  99.     return mSensorFusion.activate(ident, enabled);  
  100. }  
  101.   
  102. status_t StepCounterSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {  
  103.     return mSensorFusion.setDelay(ident, ns);  
  104. }  
  105.   
  106. Sensor StepCounterSensor::getSensor() const {  
  107.     sensor_t hwSensor;  
  108.     hwSensor.name       = "Step Counter";  
  109.     hwSensor.vendor     = "MorrowindXie";  
  110.     hwSensor.version    = 1;  
  111.     hwSensor.handle     = '_scs';  
  112.     hwSensor.type       = SENSOR_TYPE_STEP_COUNTER;  
  113.     hwSensor.maxRange   = 90000000.0f;  
  114.     hwSensor.resolution = 1.0f;  
  115.     hwSensor.power      = mSensorFusion.getPowerUsage();  
  116.     hwSensor.minDelay   = mSensorFusion.getMinDelay();  
  117.     Sensor sensor(&hwSensor);  
  118.     return sensor;  
  119. }  
  120.   
  121. // ---------------------------------------------------------------------------  
  122.   
  123. StepDetectorSensor::StepDetectorSensor()  
  124.     : mSensorDevice(SensorDevice::getInstance()),  
  125.       mSensorFusion(SensorFusion::getInstance())  
  126. {  
  127.     ALOGD("StepDetectorSensor initializing...");  
  128.     mLastReportSeconds = 0;  
  129. }  
  130.   
  131. bool StepDetectorSensor::process(sensors_event_t* outEvent,  
  132.         const sensors_event_t& event)  
  133. {  
  134.     if(event.type == SENSOR_TYPE_ACCELEROMETER) {  
  135.         *outEvent = event;  
  136.         outEvent->data[0] = 0.0f;  
  137.         outEvent->sensor = '_sds';  
  138.         outEvent->type = SENSOR_TYPE_STEP_DETECTOR;  
  139.   
  140.         time_t timeNow;  
  141.         time(&timeNow);  
  142.         struct tm *now = localtime(&timeNow);  
  143.         //ALOGD("StepCounterSensor process() event.type=%d, now=%d-%d-%d %d:%d:%d\n", event.type,  
  144.         //    now->tm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);  
  145.   
  146.         int xx = (now->tm_wday+3)*(now->tm_wday+3)%60;  
  147.         int yy = (now->tm_yday+3)*(now->tm_yday+3)%60;  
  148.         int secStart, secEnd, secNow;  
  149.         for(int i=0; itm_hour*60 + now->tm_min)*60 + now->tm_sec;  
  150.             if(secNow > secStart && secNow <= secEnd && secNow != mLastReportSeconds) {  
  151.                 mLastReportSeconds = secNow;  
  152.                 outEvent->data[0] = 1.0f;  
  153.                 break;  
  154.             }  
  155.         }  
  156.         return true;  
  157.     }  
  158.     return false;  
  159. }  
  160.   
  161. status_t StepDetectorSensor::activate(void* ident, bool enabled) {  
  162.     return mSensorFusion.activate(ident, enabled);  
  163. }  
  164.   
  165. status_t StepDetectorSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {  
  166.     return mSensorFusion.setDelay(ident, ns);  
  167. }  
  168.   
  169. Sensor StepDetectorSensor::getSensor() const {  
  170.     sensor_t hwSensor;  
  171.     hwSensor.name       = "Step Detector";  
  172.     hwSensor.vendor     = "MorrowindXie";  
  173.     hwSensor.version    = 1;  
  174.     hwSensor.handle     = '_sds';  
  175.     hwSensor.type       = SENSOR_TYPE_STEP_DETECTOR;  
  176.     hwSensor.maxRange   = 1.0f;  
  177.     hwSensor.resolution = 1.0f;  
  178.     hwSensor.power      = mSensorFusion.getPowerUsage();  
  179.     hwSensor.minDelay   = mSensorFusion.getMinDelay();  
  180.     Sensor sensor(&hwSensor);  
  181.     return sensor;  
  182. }  
  183.   
  184. // ---------------------------------------------------------------------------  
  185. }; // 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


StepSensor.h
  1. /* 
  2.  * Copyright (C) 2016 Morrowind.Xie 
  3.  * 
  4.  * This program is free software; you can redistribute it and/or modify it 
  5.  * under the terms of the GNU General Public License as published by the 
  6.  * Free Software Foundation; either version 2, or (at your option) any 
  7.  * later version. 
  8.  * 
  9.  * This program is distributed in the hope that it will be useful, but 
  10.  * WITHOUT ANY WARRANTY; without even the implied warranty of 
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  12.  * General Public License for more details. 
  13.  * 
  14.  * This project is an adaptation of the original fbvncserver for the iPAQ 
  15.  * and Zaurus. 
  16.  */  
  17.   
  18. #ifndef ANDROID_STEP_SENSOR_H  
  19. #define ANDROID_STEP_SENSOR_H  
  20.   
  21. #include   
  22. #include   
  23. #include   
  24. #include   
  25.   
  26. #include "SensorInterface.h"  
  27.   
  28. // ---------------------------------------------------------------------------  
  29. namespace android {  
  30. // ---------------------------------------------------------------------------  
  31.   
  32. class SensorDevice;  
  33. class SensorFusion;  
  34.   
  35. class StepCounterSensor : public SensorInterface {  
  36.     SensorDevice& mSensorDevice;  
  37.     SensorFusion& mSensorFusion;  
  38.     int mStepCount;  
  39.     struct tm mLastReportTime;  
  40.   
  41. public:  
  42.     StepCounterSensor();  
  43.     virtual bool process(sensors_event_t* outEvent,  
  44.             const sensors_event_t& event);  
  45.     virtual status_t activate(void* ident, bool enabled);  
  46.     virtual status_t setDelay(void* ident, int handle, int64_t ns);  
  47.     virtual Sensor getSensor() const;  
  48.     virtual bool isVirtual() const { return true; }  
  49.   
  50. };  
  51.   
  52. class StepDetectorSensor : public SensorInterface {  
  53.     SensorDevice& mSensorDevice;  
  54.     SensorFusion& mSensorFusion;  
  55.     int mLastReportSeconds;  
  56.   
  57. public:  
  58.     StepDetectorSensor();  
  59.     virtual bool process(sensors_event_t* outEvent,  
  60.             const sensors_event_t& event);  
  61.     virtual status_t activate(void* ident, bool enabled);  
  62.     virtual status_t setDelay(void* ident, int handle, int64_t ns);  
  63.     virtual Sensor getSensor() const;  
  64.     virtual bool isVirtual() const { return true; }  
  65. };  
  66.   
  67. // ---------------------------------------------------------------------------  
  68. }; // namespace android  
  69.   
  70. #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。


另外,这个样例里只是虚拟了Step Sensor,人不用真的在走路就能上报计步消息。
其实,也可以通过SensorFusion里的加速度传感器,来计算是否真的在走路,是的话才记步。怎么使用加速度传感器的数据,可以参考原有的GravitySensor.cpp源码。至于通过加速度传感器来判断走路的算法,那就是另外一个大大大话题了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值