android中的计步问题及计步传感器分析
今天打开博客,才发现居然有一年多没有写博客了。。。
最近由于公司要分析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中的计步问题及计步传感器分析相关推荐
- Android中ActivityManagerService与应用程序(客户端)通信模型分析
今天主要分析下ActivityManagerService(服务端) 与应用程序(客户端)之间的通信模型,在介绍这个通信模型的基础上,再 简单介绍实现这个模型所需要数据类型. 本文所介绍内容基于and ...
- Android中XML的三种解析器分析、实战
XML解析器介绍 Android中提供了三种方式来解析XML: SAX(simple API for XML) DOM(文档对象模型) 以及Android内部使用的Pull解析. SAX(simple ...
- Android中Google Drive显示黑屏问题分析
一.问题现象 在contacts中添加一个新的联系人,为新的联系人选择一个icon,在弹出的documents窗口中选择drive,在drive中选择一个图片,然后出现一段时间的黑屏. Platfor ...
- Android 中触摸事件与点击事件分析
触摸事件 两种检测触摸事件的方式: 设置触摸监听 setOnTouchListener 返回 true: 表示消费事件 , 可以检测到 down/move/up 事件 返回 false: 不消费事件 ...
- Android中启动Activity(startActivity)流程图分析
在上篇博文< Android中ActivityManagerService与应用程序(客户端)通信模型分析>中,我们从宏观架构上掌握 ActivityManagerService与应用程序 ...
- android classloader异常,Android中ClassLoader类加载机制
Android中apk的构建过程 构建apk 如图 所示,典型 Android 应用模块的构建流程通常依循下列步骤: 编译器将您的源代码转换成 DEX(Dalvik Executable) 文件(其中 ...
- Android中RemoteViews的实现
田海立@CSDN 2012-8-22 本文结合AppWidget的应用场景,分析Android中RemoteViews的内部具体实现. 从前文<Android中AppWidget的分析与应用:A ...
- Android中的传感器之---加速度传感器
加速度传感器 加速度传感器又叫G-sensor,返回x.y.z三轴的加速度数值. 该数值包含地心引力的影响,单位是m/s^2. 将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81(由于地球 ...
- android外置传感器,Android中外接键盘的检测的实现
今天来了一个问题:软键盘无法弹出.分析后是因为系统判断当前有外接硬键盘,就会隐藏软键盘.但实际情况并不是这么简单,该问题只有在特定条件下偶现,具体分析过程就不说了,就是软硬键盘支持上的逻辑问题.借着这 ...
最新文章
- python install scikit-image后,报错ImportError: DLL load failed: 找不到指定的模块
- Myeclipse7.5 下载 安装 注冊 注冊码 100%成功
- Tungsten Fabric SDN — SmartNIC vRouter 软件架构设计
- 处理机调度实验c语言,操作系统实验处理机调度C语言实现
- 湖北经济学院法商学院计算机分数线,湖北经济学院法商学院
- P3128-最大流Max Flow【树上差分,LCA】
- AndroidManifest.xml详解
- MYSQL教程之 concat
- java对mysql的简单操作的综合运用——登录系统
- python widget_python 图形界面
- KDD China技术峰会回顾:大牛云集,教你如何基于大数据 手握人工智能未来
- java web整合开发完全自学手册pdf_《JavaScript完全自学手册》PDF 下载
- 通过本地上传工具把CSV文件导入到百会报表
- Ubuntu 16.04 安装无线网卡 Tenda U12
- FPGA通过JTAG固化到EPCS芯片时无效的一些解决
- 百度指数Cipher-text加密
- 解读Verizon 2018数据泄漏调查报告:窃取身份仍是黑客最有效的攻击手段
- 甲骨文公司老板埃里森在耶如大学的…
- Java使用正则表达式从字符串中提取 IP 地址
- 视频中的音频提取如何操作?一分钟教会你