如何以固定速率记录Android Motion Sensors的数据

thi*_*-Me 10 java android android-sensors sensor-fusion

我正在学习Android编程的基础知识.

我有一个简单的android测试应用程序,其中我将加速度计,磁力计和方向数据记录到外部文件,同时也显示它.我通过调用方法initLogger来单击Start按钮(相关传感器的registerListener)来启动日志记录过程.

看起来与此类似......

public void initLogger(View view)
{
    boolean bFlag = false;

    Button btnStart = (Button)findViewById(R.id.btnStartLog);
    Button btnStop = (Button)findViewById(R.id.btnStopLog);

    btnStart.setEnabled(bFlag);
    btnStop.setEnabled(!bFlag);

    bEnableLogging = true;
    //Start reading the sensor values
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);

   //so on.... 
Run Code Online (Sandbox Code Playgroud)

还有一个Stop按钮,它将停止记录过程(最后通过为每个传感器调用unregisterListener来取消注册)

数据检索过程发生在onSensorChanged处理程序中,该处理程序将从相关传感器检索数据,将值设置为相应的UI元素,最后将数据记录到外部.csv文件.

onSensorChanged事件处理程序看起来像这样......

public void onSensorChanged(SensorEvent event) {


    // TODO Auto-generated method stub
    // accelerometer
    TextView tAX = (TextView) findViewById(R.id.txtViewAxValue);
    TextView tAY = (TextView) findViewById(R.id.txtViewAyValue);
    TextView tAZ = (TextView) findViewById(R.id.txtViewAzValue);

    // magnetic field
    TextView tMX = (TextView) findViewById(R.id.txtViewMx);
    TextView tMY = (TextView) findViewById(R.id.txtViewMy);
    TextView tMZ = (TextView) findViewById(R.id.txtViewMz);

    if (bEnableLogging) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

            accelerometerdata = event.values.clone();

            tAX.setText(Double.toString(accelerometerdata[0]));
            tAY.setText(Double.toString(accelerometerdata[1]));
            tAZ.setText(Double.toString(accelerometerdata[2]));


        }

        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

            magneticmatrixdata = event.values.clone();

            tMX.setText(Double.toString(magneticmatrixdata[0]));
            tMY.setText(Double.toString(magneticmatrixdata[1]));
            tMZ.setText(Double.toString(magneticmatrixdata[2]));

        }

               // so on ....
Run Code Online (Sandbox Code Playgroud)

虽然我从所有配置的传感器接收数据,但我无法控制接收数据的速率.即

我知道当Sensor数据发生变化时会触发SensorChanged事件.但是我希望以固定费率解雇此事件.例如:每40ms

题:

  1. 如何确保以恒定速率触发SensorChanged事件?
  2. 在这种情况下,Java中的类TimerTask是否有任何帮助?

专家在这里SO.Please帮帮我:)

nur*_*gan 2

因为您知道如果没有触发 SensorChanged 事件,则没有变化,您可以只使用旧值。当您要求特定时间间隔内的日志数据时,我不会在 onSensorChanged 方法中执行任何输出,只是将新数据克隆到您的 accelerometerdata 变量中。并且每 40 毫秒记录一次加速度计数据的值。这样,即使数据没有改变,您也可以每 40 毫秒记录一次实际值......

注意:根据 Ridcullys Answer,似乎也可以在特定时间间隔内“传递”传感器数据。但由于 Android 上的传感器数据始终存在这些“交付”延迟,因此使用我的解决方案,您将更准确地保持 40 毫秒间隔。另一方面,如果传感器数据在您记录时发生变化,则可能会发生新数据延迟一个时间间隔的情况。我猜(不确定这一点) - 因为它只是关于日志记录,而不是像“实时尽可能快地获取它”之类的东西,所以这不是一个要求 - 计时器解决方案会导致更少的 CPU 负载。