如何在要求时仅读取一次 Android 传感器数据

问题描述

我正在尝试读取 Java android 应用程序中的加速度计和/或地磁传感器,以确定某一点的设备方向。但是传感器本身并不重要,我的问题可以应用于您想要读取的任何类型的传感器,无论是运动、温度、光线、压力还是其他什么。

我看到到处都是用于设置来自传感器的数据“流”的代码,带有事件侦听器,并且能够对传感器通过回调发送给您的数据进行“反应”。

那不是我所追求的,我认为可能无法做我想做的事。

我们想要的是读取一次传感器数据。 不是两次,不是连续 3 秒,不是在传感器向我发送事件时。 打开,阅读,关闭

当我要求阅读时,我只需要阅读一次。 当我得到那个读数时,我不需要更多的读数。

一旦您拥有 anysensor.getCurrentState() 等足够的权限,感觉这应该是一个简单的单行操作。 但是从我可以阅读的内容来看,我只发现文档依赖于来自 sensorManager 的事件侦听器并且必须设置整个类和 5 个不同的事件回调:

https://developer.android.com/guide/topics/sensors/sensors_position#sensors-pos-orient

我想我可以做到这一点,并尝试让它尽可能轻,让 eventListeners 在第一次阅读时自动停止。但是感觉很潮,而且我需要的代码很多。而且我正在尝试做一个非常简单的任务,阅读,了解它,然后完成它,这需要一些异步的东西。 所以我想我必须“暂停”应用程序,直到我得到第一个结果。

这真的是最简单/唯一的方法吗?

解决方法

从我在这里读到的内容来看,如果不设置 eventListeners,似乎无法读取传感器数据。

Android get sensor data without EventListeners

我还没有结束这个问题,以防万一有人可以确认是不是这样。

如果有人有将这个异步步骤集成到同步函数中间的最佳方式的提示,那将是受欢迎的!

,

我正在写我的问题的最终答案,因为我找到了适合我的特定用例的解决方案。

尽管我的动作不应该是“异步的”,但我最终做的是拆分我的脚本,以便“job.done();”继续我的脚本的其余部分,使“编码”大部分类似于同步脚本。

为了分享的目的,我去掉了大部分内容,只保留了有趣的部分。我希望这对任何尝试做类似事情的人来说都足够了。这也是我发现的访问加速度计数据的最短方式。

基本上,想法是我有一个switch,根据结果我可能需要传感器或我可能不需要它(只保留两个案例来说明我的观点)。 当 case"portrait" 时,我可以保持一切同步,并调用“job.done();”这将继续脚本的其余部分。

但是,如果 case"auto_landscape",我想使用传感器。因为我只需要一个读数,当传感器发送它的第一个回调 (onSensorChanged()) 时,它会自行注销,然后使用相同的 job.done(); 方法来完成脚本。

这里是:

sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);

switch(currentMode) {
    case "portrait":
        setRotation(0);
        job.done("Portrait");
        break;

    case "auto_landscape":
        sensorListener = new SensorEventListener() {
            @Override public void onAccuracyChanged(Sensor arg0,int arg1) {}
            @Override public synchronized void onSensorChanged(SensorEvent event) {
                if (event.values[0] > 0 ) {
                    // landscape right
                    setRotation(1);
                } else {
                    // landscape left
                    setRotation(3);
                }
                sensorManager.unregisterListener(sensorListener);
                job.done("Landscape (auto)");
            }
        };
        sensorManager.registerListener(sensorListener,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST );
        break;
    default:
        job.done("Something is wrong!");
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...