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
    在这里插入图片描述在这里插入图片描述
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android Studio中,可以使用SensorManager类来获取和管理传感器数据。以下是一个简单的示例代码,演示如何在Android Studio中使用传感器: ```java // 导入必要的类 import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements SensorEventListener { private SensorManager sensorManager; private Sensor accelerometer; private TextView xValue, yValue, zValue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化传感器管理器 sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); // 获取加速度传感器 accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 初始化TextView xValue = findViewById(R.id.x_value); yValue = findViewById(R.id.y_value); zValue = findViewById(R.id.z_value); } @Override protected void onResume() { super.onResume(); // 注册传感器监听sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); // 取消注册传感器监听sensorManager.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { // 当传感器数据发生变化时调用 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { // 获取加速度传感器的值 float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; // 更新TextView显示的值 xValue.setText("X轴值: " + x); yValue.setText("Y轴值: " + y); zValue.setText("Z轴值: " + z); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // 当传感器精度发生变化时调用 } } ``` 这个示例代码演示了如何在Android Studio中使用传感器。它创建了一个MainActivity类,实现了SensorEventListener接口来监听传感器数据的变化。在onCreate方法中,我们初始化了传感器管理器,并获取了加速度传感器。在onResume方法中,我们注册了传感器监听器,并在onPause方法中取消注册。在onSensorChanged方法中,我们获取了加速度传感器的值,并更新了TextView显示的值。 请注意,这只是一个简单的示例,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xhBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值