Я пытаюсь разработать приложение для Android, в котором я собираю данные с нескольких датчиков (если они есть на устройстве) и записываю их в файл, который впоследствии будет проанализирован для определенных целей. Я сталкиваюсь с несколькими проблемами, мелкой, которую я могу игнорировать, и одной, которую я не смог решить, и которая заставляет приложение работать неправильно.
- Незначительная проблема
Я собираю данные с: акселерометра, линейного акселерометра, гироскопа и магнитометра, а также с GPS, но это работает совсем по-другому и может быть взято только на гораздо более низких частотах, поэтому я проигнорирую это для сейчас же. Я собираю данные путем реализации прослушивателя для каждого датчика:
public class AccelerometerWatcher implements SensorEventListener
{
private SensorManager sm;
private Sensor accelerometer;
AccelerometerWatcher(Context context) {
sm = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
assert sm != null;
if (sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
}
}
И я устанавливаю частоту ~ 50 Гц, используя:
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
При сборе данных я понимаю частота не может быть стабильной на 100%, но странная вещь заключается в том, что она остается более или менее стабильной на каждом датчике (на частоте около 50 Гц), за исключением акселерометра, где большую часть времени он производит выборку на частоте 100 Гц, а иногда падает до 50 Гц.
Есть ли что-то, что я могу делать неправильно или какой-либо способ контролировать это? До сих пор это происходило в каждом устройстве, которое я пробовал, хотя они не все ведут себя одинаково.
- Основная проблема
Я записываю информация в файл, сначала записывая все, что я собираю с датчиков в строку, а затем каждые X секунд, записывая то, что находится в строке, в файл и очищая его, чтобы слушатели датчика могли продолжать писать на нем, но это не становится бесконечно долго.
Я пишу в строке так:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
if(initTime == -1)
initTime = event.timestamp;
MyConfig.SENSOR_ACCEL_READINGS += ((event.timestamp - initTime) / 1000000L) + MyConfig.DELIMITER + event.values[0] + MyConfig.DELIMITER + event.values[1] + MyConfig.DELIMITER + event.values[2] + "\n";
}
И затем сохраняю ее в файл, используя:
public class Utils {
private static Timer timer;
private static TimerTask timerTask;
public static void startRecording() {
timer = new Timer();
timerTask = new TimerTask()
{
@Override
public void run()
{
// THIS CODE RUNS EVERY x SECONDS
writeDataToFile();
}
};
timer.scheduleAtFixedRate(timerTask, 0, MyConfig.SAVE_TIMER_PERIOD);
}
public static void stopRecording()
{
if(timer != null)
timer.cancel();
if(timerTask != null)
timerTask.cancel();
writeDataToFile();
}
private static void writeDataToFile()
{
String temp_accel = String.copyValueOf(MyConfig.SENSOR_ACCEL_READINGS.toCharArray());
WriteData.write(MyConfig.RECORDING_FOLDER, MyConfig.FILENAME_ACCEL, temp_accel);
MyConfig.SENSOR_ACCEL_READINGS = MyConfig.SENSOR_ACCEL_READINGS.replaceFirst(temp_accel, "");
}
В слушателе каждый Когда я прекращаю слушать, я устанавливаю «initTime» на -1, чтобы сэмплы всегда начинались с 0 и go вплоть до продолжительности периода прослушивания в миллисекундах. (Игнорируйте РАЗДЕЛИТЕЛЬ, это всего лишь вопрос форматирования).
Моя главная проблема, связанная с нарушением работы приложений, заключается в следующем:
В большинстве телефонов (работают несколько счастливчиков) без нареканий) 1 или 2 вещи терпят неудачу.
В некоторых из них после некоторого простоя (например, заблокированного и находящегося в вашем кармане) датчики перестают записывать данные, поэтому приложение просто записывает пустые значения, пока я снова не проснусь.
В других случаях это даже хуже, датчики не только прекращают запись данных, но и таймер / запись в файл, кажется, тоже перестает работать, и когда телефон снова просыпается, он пытается записать то, что должен был написать, пока он не работал и испортил все временные метки, записывая одни и те же сэмплы в разные моменты «в прошлом», пока не догонит текущее время. (Если вы визуализируете его в виде графика, он в основном выглядит так, как будто сбор данных перемещен во времени).
Есть ли способ, которым я могу убедиться, что приложение продолжает работать независимо от того, что, будь то телефон заблокирован, дремлет, приложение свернуто, на заднем плане, на переднем плане, и т. д. c.?
Я попробовал метод, который я гуглил, который состоит из установки и тревоги для " «запускать процесс» каждые X секунд (независимо от того, какое время я установил, он работал только один раз в минуту). Я видел, как в течение нескольких миллисекунд каждый раз, когда срабатывал будильник, он снова собирал образцы, но затем сразу же засыпал, что не давало телефону «проснуться» в течение более длительного периода времени. Это ничего не решало и даже на короткий период заставило датчики собирать данные, это только помогло разбудить датчики, проблема с таймером / записью в файл все еще сохранялась.
Надеюсь, что кто-то может пролить свет на как вести телефонный сбор данных, несмотря ни на что, я пробовал все, что мог придумать, и никуда не денусь. Извините за текст, но я не знаю, как объяснить это в более краткой форме.
PS: я видел, что включение Battery Saver сделало его еще хуже, даже на телефонах, где он как правило, работали должным образом, он начал все портить. Так что другой вопрос будет ... Как я могу остановить это от вмешательства?