Android应用监听Sensor获取的SensorEvent对象

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
    在这里插入图片描述在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_23452385/article/details/109701646