繁体   English   中英

将加速度传感器数据写入文件不正确

[英]Writing accelerometer sensor data to file is out of order

我正在开发一个Android应用程序,它将把时间戳和3轴加速度传感器数据(时间戳,ax,ay,az)写入一个csv文件。 我首先遇到两个问题,就是文件中的几个条目的时间戳记不是按升序编写的(请参阅图像中黄色突出显示的时间戳记)。 图片1

其次,单个时间戳记有很多条目(不是重复的条目),理想情况下,唯一的时间戳记我们应该只有一个条目 image2

我的应用程序的设计是:我正在创建一个将在后台运行的服务,并将所有传感器数据记录到文件中。 我正在使用ZipOutputStream,它包装BufferedOutputStream和FileOutputStream将传感器数据写入文件。 以下是AccelerometerLoggingService的代码段。 我正在使用onDestroy()服务方法关闭文件。 您能建议我代码或设计中可能存在的缺陷吗? 我认为线程可能存在一些问题,但是我不知道如何调试它。 任何帮助表示赞赏。

public class AccelerometerLoggingService extends Service {

class AccelerometerEventLoggerTask extends AsyncTask<Acceleration, Void, Void> {
    @Override
    protected Void doInBackground(Acceleration... accelerations) {
        Acceleration acc = accelerations[0];
        writeAcceleration(acc);
        return null;
    }
}

class AccelerometerSensorListener implements SensorEventListener {

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
            return;

        Acceleration acc = new Acceleration(System.currentTimeMillis(),
                event.values[0],
                event.values[1],
                event.values[2]);
        new AccelerometerEventLoggerTask().execute(acc);
    }

 }
}

writeAcceleration(Acceleration acc) {
    zipOutputStream.write(acc.toString().getBytes());
}
// 
ZipOutputStream zipOutputStream = new ZipOutputStream(new   BufferedOutputStream(new FileOutputStream(logFile)));

更新2:

我认为问题出在线程同步。 因此,我决定在单独的后台线程上运行加速度传感器,并将传感器数据写入同一线程中的文件中,但仍然在文件中出现乱序记录。 以下是我所做的新代码更改。

     public void startAccelerometer() {
        // creating new thread for onSensorChanged method to run
        handlerThread = new HandlerThread("AccelerometerSensorThread");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper());

        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager
                .SENSOR_DELAY_GAME, handler);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
            return;
        Acceleration acc = new Acceleration(System.currentTimeMillis(),
                event.values[0],
                event.values[1],
                event.values[2]);
        accelerometerLogger.writeAcceleration(acc); // writing sensor data to file

        Log.d(TAG, "onSensorChanged Thread name " + Thread.currentThread().getName()); // AccelerometerSensorThread
    }

    public void stopAccelerometer() {
        // first unregister the sensor listener then stop the thread
        mSensorManager.unregisterListener(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            handlerThread.quitSafely();
        } else {
            handlerThread.quit();
        }

    }

该问题似乎与事件的写入顺序无关。 在获得“乱序”时间戳后,后续时间将从新时间戳而不是旧时间戳继续增加。 可能发生的情况是您的蜂窝网络https://developer.android.com/reference/android/os/SystemClock.html重置了系统时间。

解决方案取决于您的要求。 在这种情况下,您可以记住上一次写入的时间,并在该时间之前丢弃任何传感器读数。 另外,您可以使用uptimeMillis()方法将时间戳调整为相对于开始记录的时间。

尝试跟随(添加的synchronized块)

@Override 
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
        return; 

    synchronized(this) {
        Acceleration acc = new Acceleration(System.currentTimeMillis(),
                event.values[0],
                event.values[1],
                event.values[2]);
       new AccelerometerEventLoggerTask().execute(acc);
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM