今天打开博客,才发现居然有一年多没有写博客了。。。


最近由于公司要分析android上的计步问题,顺便把计步器在android上的实现跟踪了一下。结果发现悲催的是,android的api19上,是用的硬件本身的计步实现了。


android源码中的流程追踪如下:

frameworks/base/core/java/android/hardware/Sensor.java 中定义了TYPE_STEP_DETECTOR和TYPE_STEP_COUNTER。 请注意,detector启动后,确认了,才启动counter.

然后在jni以下查到调用。

frameworks/base/core/jni/android_hardware_SensorManager.cpp

    virtual int handleEvent(int fd, int events, void* data) {        JNIEnv* env = AndroidRuntime::getJNIEnv();        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);        ssize_t n;        ASensorEvent buffer[16];        while ((n = q->read(buffer, 16)) > 0) {            for (int i=0 ; i<n ; i++) {                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {                    // step-counter returns a uint64, but the java API only deals with floats                    float value = float(buffer[i].u64.step_counter);                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);                } else {                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);                }

可以看到,如果是计步器,直接从q里面读出的原生值。其中q被转化成了SensorEventQueue.查找转化方法:

frameworks/native/libs/gui/SensorEventQueue.cpp

ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {    if (mAvailable == 0) {        ssize_t err = BitTube::recvObjects(mSensorChannel,                mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);        if (err < 0) {            return err;        }           mAvailable = err;        mConsumed = 0;    }       size_t count = numEvents < mAvailable ? numEvents : mAvailable;    memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent));    mAvailable -= count;    mConsumed += count;    return count;}
也就是说,SensorEvent是保存在ASensorEvent的结构中。查找原型。

frameworks/native/include/android/sensor.h

/* NOTE: Must match hardware/sensors.h */typedef struct ASensorEvent {    int32_t version; /* sizeof(struct ASensorEvent) */    int32_t sensor;    int32_t type;    int32_t reserved0;    int64_t timestamp;    union {        union {            float           data[16];            ASensorVector   vector;            ASensorVector   acceleration;            ASensorVector   magnetic;            float           temperature;            float           distance;            float           light;            float           pressure;            float           relative_humidity;            AUncalibratedEvent uncalibrated_gyro;            AUncalibratedEvent uncalibrated_magnetic;            AMetaDataEvent meta_data;        };          union {            uint64_t        data[8];            uint64_t        step_counter;        } u64;    };      int32_t reserved1[4];} ASensorEvent;
这时数据出来了。。。。直接调用硬件上的计步器实现。

hal层的相关文件。

./hardware/libhardware/include/hardware/sensors.h

#define SENSOR_TYPE_STEP_DETECTOR                   (18)...#define SENSOR_TYPE_STEP_COUNTER                    (19)
OK。这时候查找hal层的使用方法。

invensense/65xx/libsensors_iio/sensors_mpl.cpp

202 int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count)203 {204     VHANDLER_LOG;205 206     int nbEvents = 0;207     int nb, polltime = -1;208 209     polltime = ((MPLSensor*) mSensor)->getStepCountPollTime();210 211     // look for new events212     nb = poll(mPollFds, numFds, polltime);213     LOGI_IF(0, "poll nb=%d, count=%d, pt=%d", nb, count, polltime);214     if (nb > 0) {215         for (int i = 0; count && i < numSensorDrivers; i++) {216             if (mPollFds[i].revents & (POLLIN | POLLPRI)) {               217                 LOGI_IF(0, "poll found=%d", i);218                 nb = 0;219                 if (i == mpl) {220                     ((MPLSensor*) mSensor)->buildMpuEvent();221                     mPollFds[i].revents = 0;222                 } else if (i == compass) {223                     ((MPLSensor*) mSensor)->buildCompassEvent();224                     mPollFds[i].revents = 0;....268         if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {269             nb = 0;270             nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(data, count, ID_SC, SENSOR_TYPE_STEP_COUNTER, 0);271             LOGI_IF(HANDLER_DATA, "sensors_mpl:readStepCount() - nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, data->data[0]=%f,",272                           nb, count, nbEvents, data->timestamp, data->data[0]);273             if (nb > 0) {274                 count -= nb;275                 nbEvents += nb;276                 data += nb;277             }278         }                    
可以看出,270行把数据读出来了。。。


顺便查了一下android中的sensor的实现方法。

https://source.android.com/devices/sensors/sensor-stack.html 官方的介绍。sensor层次的介绍,不是很详细。

https://docs.google.com/file/d/0B2IJqxU5nzCyQWZ1TzhGd3FUWlNCQjhqV0psV1l3dw/edit 2012的文档,现在的实现有变化,大致可以参考一下。

http://processors.wiki.ti.com/index.php/Android_Sensor_PortingGuide 内核层的更改方法。


手上没有nexus5的内核源码,所以暂时没有跟n5中的step counter的内核中的驱动实现。不过这个跟踪过程比较简单了。





更多相关文章

  1. 利用BLCR加快android的启动过程
  2. Android(安卓)滑动效果高级篇(七)—— 华丽翻页效果
  3. 两种特殊TabHost实现
  4. Android——腾讯X5使用记录
  5. 在Android平台上实现条型码扫描与识别
  6. Android(安卓)创建与解析XML(一)—— 概述
  7. Android(安卓)集成Chrome 浏览器内核 Crosswalk
  8. android 轻松实现语音识别
  9. Android操作Excel文件的功能实现

随机推荐

  1. Android(安卓)处理音频焦点 AudioFocus,停
  2. 安卓系统修改host文件简单教程
  3. Android开发:界面布局的基本使用
  4. CMake Android(安卓)交叉编译
  5. Android(安卓)studio APP开发 控制UI布局
  6. Android培训班(4)
  7. Android中Shared Preferences、Files、Ne
  8. Android下的配置管理之道之gerrit权限管
  9. android ListView显示网络图片
  10. Android到处都在使用的回调分析