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

最近由于公司要分析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 floatsfloat 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 events
212     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的内核中的驱动实现。不过这个跟踪过程比较简单了。

android中的计步问题及计步传感器分析相关推荐

  1. Android中ActivityManagerService与应用程序(客户端)通信模型分析

    今天主要分析下ActivityManagerService(服务端) 与应用程序(客户端)之间的通信模型,在介绍这个通信模型的基础上,再 简单介绍实现这个模型所需要数据类型. 本文所介绍内容基于and ...

  2. Android中XML的三种解析器分析、实战

    XML解析器介绍 Android中提供了三种方式来解析XML: SAX(simple API for XML) DOM(文档对象模型) 以及Android内部使用的Pull解析. SAX(simple ...

  3. Android中Google Drive显示黑屏问题分析

    一.问题现象 在contacts中添加一个新的联系人,为新的联系人选择一个icon,在弹出的documents窗口中选择drive,在drive中选择一个图片,然后出现一段时间的黑屏. Platfor ...

  4. Android 中触摸事件与点击事件分析

    触摸事件 两种检测触摸事件的方式: 设置触摸监听  setOnTouchListener 返回 true: 表示消费事件 , 可以检测到 down/move/up 事件 返回 false: 不消费事件 ...

  5. Android中启动Activity(startActivity)流程图分析

    在上篇博文< Android中ActivityManagerService与应用程序(客户端)通信模型分析>中,我们从宏观架构上掌握 ActivityManagerService与应用程序 ...

  6. android classloader异常,Android中ClassLoader类加载机制

    Android中apk的构建过程 构建apk 如图 所示,典型 Android 应用模块的构建流程通常依循下列步骤: 编译器将您的源代码转换成 DEX(Dalvik Executable) 文件(其中 ...

  7. Android中RemoteViews的实现

    田海立@CSDN 2012-8-22 本文结合AppWidget的应用场景,分析Android中RemoteViews的内部具体实现. 从前文<Android中AppWidget的分析与应用:A ...

  8. Android中的传感器之---加速度传感器

    加速度传感器 加速度传感器又叫G-sensor,返回x.y.z三轴的加速度数值. 该数值包含地心引力的影响,单位是m/s^2. 将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81(由于地球 ...

  9. android外置传感器,Android中外接键盘的检测的实现

    今天来了一个问题:软键盘无法弹出.分析后是因为系统判断当前有外接硬键盘,就会隐藏软键盘.但实际情况并不是这么简单,该问题只有在特定条件下偶现,具体分析过程就不说了,就是软硬键盘支持上的逻辑问题.借着这 ...

最新文章

  1. python install scikit-image后,报错ImportError: DLL load failed: 找不到指定的模块
  2. Myeclipse7.5 下载 安装 注冊 注冊码 100%成功
  3. Tungsten Fabric SDN — SmartNIC vRouter 软件架构设计
  4. 处理机调度实验c语言,操作系统实验处理机调度C语言实现
  5. 湖北经济学院法商学院计算机分数线,湖北经济学院法商学院
  6. P3128-最大流Max Flow【树上差分,LCA】
  7. AndroidManifest.xml详解
  8. MYSQL教程之 concat
  9. java对mysql的简单操作的综合运用——登录系统
  10. python widget_python 图形界面
  11. KDD China技术峰会回顾:大牛云集,教你如何基于大数据 手握人工智能未来
  12. java web整合开发完全自学手册pdf_《JavaScript完全自学手册》PDF 下载
  13. 通过本地上传工具把CSV文件导入到百会报表
  14. Ubuntu 16.04 安装无线网卡 Tenda U12
  15. FPGA通过JTAG固化到EPCS芯片时无效的一些解决
  16. 百度指数Cipher-text加密
  17. 解读Verizon 2018数据泄漏调查报告:窃取身份仍是黑客最有效的攻击手段
  18. 甲骨文公司老板埃里森在耶如大学的…
  19. Java使用正则表达式从字符串中提取 IP 地址
  20. 视频中的音频提取如何操作?一分钟教会你

热门文章

  1. nginx使用Proxy-protocal
  2. 【Derivation】维纳—辛钦公式证明
  3. 35岁的程序员,该给领导送礼了!
  4. 下载文件、(Blob数据流)下载PDF
  5. 服务器证书 sll证书的理解
  6. Repeatable Read
  7. 巴菲特 投资“金”定律
  8. MongoDB和Node.js的Mongoose简介
  9. 【Matlab】设计状态观测器
  10. 设计状态观测器的目的