Я разрабатываю приложение для Android, которое будет записывать временные метки и данные с 3-х осевым акселерометром (timestamp, ax, ay, az) в файл csv. Сначала я получаю две проблемы: временная метка из нескольких записей не записывается в порядке возрастания в файле (см. Желтую выделенную метку времени на изображении). Запись данных датчика акселерометра в файл не работает
Во-вторых, что я получаю много записей для одной метки времени (не дублирующие записей), в идеале мы должны получить только одну запись для уникальной метки времени .
Дизайн моего приложения: Я создаю службу, которая будет работать в фоновом режиме и записывать все данные датчика в файл. Я использую 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();
}
}
да сон. проблема заключается в 'System.currentTimeMillis()', который может быть изменен сетевым провайдером. Теперь я использую 'SystemClock.elapsedRealTime()', который не зависит от часов пользователя. –
не могли бы вы рассказать о времени? Дает ли вам абсолютное время (время unix) или относительное время (время работы от загрузки)? –