タイムスタンプと 3 軸加速度センサー データ (タイムスタンプ、ax、ay、az) を csv ファイルに書き込む Android アプリを開発しています。最初に 2 つの問題が発生しています。いくつかのエントリのタイムスタンプが昇順でファイルに書き込まれていないことです (画像の黄色で強調表示されたタイムスタンプを参照してください)。
2 つ目は、単一のタイムスタンプ (重複したエントリではなく) に対して多くのエントリを取得していることです。理想的には、一意のタイムスタンプに対して単一のエントリのみを取得する必要があります。
私のアプリの設計は次のとおりです。バックグラウンドで実行され、すべてのセンサー データをファイルに記録するサービスを作成しています。BufferedOutputStream と FileOutputStream をラップする ZipOutputStream を使用して、センサー データをファイルに書き込みます。以下は のコード スニペットです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();
}
}