概述
Android应用监听Sensor获取的SensorEvent对象
本文基于aosp/android11-release -- 清华大学开源软件镜像站AOSP
1.应用监听某颗sensor中注册SensorEventListener
可以查看SensorService数据传递给APK
private SensorEventListener mStepCounterListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// event.values[0];
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
mSensorManager.registerListener(mStepCounterListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/java/android/hardware/SystemSensorManager.java
frameworks/base/core/java/android/hardware/SensorEvent.java
通过SensorService数据传递给APK查看,注册最后SystemSensorManager中registerListenerImpl会创建SensorEventQueue,并在addSensor添加addSensorEvent(sensor)。
2. 通过JNI实际获取
查看SensorService数据传递给APK,通过Receiver被监听fd被触发回调response.request.callback->handleEvent(fd, events, data),即Receiver中handleEvent被回调。获取读取到sensors_event_t,从中只看到SensorEvent中System.arraycopy 赋值values数组,默认是buffer[i].data。
frameworks/base/core/jni/android_hardware_SensorManager.cpp
frameworks/native/services/sensorservice/SensorService.cpp
frameworks/native/include/android/sensor.h
class Receiver : public LooperCallback {
//。。。 。。。
jfloatArray mFloatScratch;
//。。。 。。。
private:
//。。。 。。。
virtual int handleEvent(int fd, int events, void* data) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
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(mFloatScratch, 0, 1, &value);
} else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
float value[2];
value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
value[1] = float(buffer[i].dynamic_sensor_meta.handle);
env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
} else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
env->SetIntArrayRegion(mIntScratch, 0, 14,
buffer[i].additional_info.data_int32);
env->SetFloatArrayRegion(mFloatScratch, 0, 14,
buffer[i].additional_info.data_float);
} else {
env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
}
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
//。。。 。。。
}else {
//。。。 。。。
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mFloatScratch,
status,
buffer[i].timestamp);
}
}
//。。。 。。。
}
mSensorQueue->sendAck(buffer, n);
}
if (n<0 && n != -EAGAIN) {
// FIXME: error receiving events, what to do in this case?
}
return 1;
}
};
3. Sensor HAL获取Sensor对象
查看SensorService数据传递给APK,设备device.poll 通过 SensorEventConnection 中 sendEvents 发送 sensors_event_t 给上层。上面主要是默认的buffer[i].data就是上报的sensor数据data[16]。
frameworks/native/services/sensorservice/SensorService.cpp
hardware/libhardware/include/hardware/sensors.h
typedef struct sensors_event_t {
/* must be sizeof(struct sensors_event_t) */
int32_t version;
/* sensor identifier */
int32_t sensor;
/* sensor type */
int32_t type;
/* reserved */
int32_t reserved0;
/* time is in nanosecond */
int64_t timestamp;
union {
union {
float data[16];
/* acceleration values are in meter per second per second (m/s^2) */
sensors_vec_t acceleration;
/* magnetic vector values are in micro-Tesla (uT) */
sensors_vec_t magnetic;
/* orientation values are in degrees */
sensors_vec_t orientation;
/* gyroscope values are in rad/s */
sensors_vec_t gyro;
/* temperature is in degrees centigrade (Celsius) */
float temperature;
/* distance in centimeters */
float distance;
/* light in SI lux units */
float light;
/* pressure in hectopascal (hPa) */
float pressure;
/* relative humidity in percent */
float relative_humidity;
/* uncalibrated gyroscope values are in rad/s */
uncalibrated_event_t uncalibrated_gyro;
/* uncalibrated magnetometer values are in micro-Teslas */
uncalibrated_event_t uncalibrated_magnetic;
/* uncalibrated accelerometer values are in meter per second per second (m/s^2) */
uncalibrated_event_t uncalibrated_accelerometer;
/* heart rate data containing value in bpm and status */
heart_rate_event_t heart_rate;
/* this is a special event. see SENSOR_TYPE_META_DATA above.
* sensors_meta_data_event_t events are all reported with a type of
* SENSOR_TYPE_META_DATA. The handle is ignored and must be zero.
*/
meta_data_event_t meta_data;
/* dynamic sensor meta event. See SENSOR_TYPE_DYNAMIC_SENSOR_META type for details */
dynamic_sensor_meta_event_t dynamic_sensor_meta;
/*
* special additional sensor information frame, see
* SENSOR_TYPE_ADDITIONAL_INFO for details.
*/
additional_info_event_t additional_info;
};
union {
uint64_t data[8];
/* step-counter */
uint64_t step_counter;
} u64;
};
/* Reserved flags for internal use. Set to zero. */
uint32_t flags;
uint32_t reserved1[3];
} sensors_event_t;
4. Sensor和SensorEvent区别
Android为什么要用两个对象呢???有什么区别吗?还是设备厂商需要???
其时实质是sensors.h种结构体 sensor_t 和 sensors_event_t 区别。
应用获取Sensor请查看:Android获取这颗Sensor对象
frameworks/base/core/java/android/hardware/SensorEvent.java
frameworks/base/core/java/android/hardware/Sensor.java
hardware/libhardware/include/hardware/sensors.h
- 4.1 SensorEvent.java包含Sensor.java;sensor_t 和 sensors_event_t 通过handle和sensor成员变量联系;
- 4.2 这颗Sensor传感器内部的变量和这颗传感器数据变化上传的data是不一样的,不能混淆
- 4.3 Android 11:sensor.resolution必须具有非零分辨率;传感器的最大范围传sensor.maxRange不是分辨率sensor.resolution的倍数,计算SensorDeviceUtils::quantizeValue
最后
以上就是高兴金鱼为你收集整理的Android应用监听Sensor获取的SensorEvent对象Android应用监听Sensor获取的SensorEvent对象的全部内容,希望文章能够帮你解决Android应用监听Sensor获取的SensorEvent对象Android应用监听Sensor获取的SensorEvent对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复