Android NDK中提供了一系列接口来监听传感器数据,都包含在 <android/sensor.h> 中,所以首先要在代码中添加引用:
#include <android/sensor.h>
- ASensorManager
首先就是要获取 sensor manager,在应用里它是一个单例,只能通过接口来获取它的引用:
ASensorManager * mpSensorManager = ASensorManager_getInstance();
- ASensorRef
接下来是通过 sensor manager 获取我们需要的传感器引用,这一步需要我们指定要获取的类型,这里以陀螺仪为例,
ASensorRef mSensorRef = ASensorManager_getDefaultSensor(mpSensorManager, ASENSOR_TYPE_GYROSCOPE);
if (mSensorRef == NULL){
LOGE("no gyro sensor");
return;
}
系统所支持的传感器类型有30多个,具体可以查看sensor.h里的枚举定义。
在调用完成后最好检查一下结果,如果出现错误,该接口会返回一个 NULL。
- ASensorEventQueue
另外还需要我们自己创建消息队列:
ASensorEventQueue * mpSensorEventQueue = ASensorManager_createEventQueue(mpSensorManager, mpLooper, 0, NULL, NULL);
在这里,需要传入一个 ALooper,作为处理消息队列的执行者,参考后面创建的线程。
第三个参数是个ID,注意大于等于0就可以。
第四个参数可以设置回调函数,在这里没有设置,是主动去调用获取event的,如果设置了回调函数,有event的时候就能收到回调。
最后一个参数,目前没发现什么用处,置空。
- Update Thread
完成了这些,还需要一个线程来处理 sensor event,下面是该线程的主函数:
void run() {
mpLooper = ALooper_prepare(0);
while (true) {
usleep(10 * 1000);
if ( 1 == ASensorEventQueue_hasEvents(mpSensorEventQueue) ) {
ASensorEvent event;
int result = ASensorEventQueue_getEvents(mpSensorEventQueue, &event, 1);
if (result <= 0) {
LOGE("get event fail %d",result);
continue;
}
LOGI("event is %f %f %f", event.vector.x, event.vector.y, event.vector.z);
}
};
}
注意,looper 就是在这里创建的。
这里实现的比较简单,就每间隔10ms获取一个event,实际中要根据传感器采样频率来决定,以获得最精确的数据。
- Enable Sensor
以上这些准备工作完成,就可以开始运行了。
int errorCode = ASensorEventQueue_enableSensor(mpSensorEventQueue, mSensorRef);
if( errorCode != 0 ){
LOGE("enable sensor error: %d",errorCode);
}
//先enable之后,再设置刷新率,比如这里时间间隔10*1000us,是100Hz
ASensorEventQueue_setEventRate(mpSensorEventQueue, mSensorRef, 10*1000);