簡體   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