1. Are you ready for the Galaxy S20? Here is everything we know so far!

Sensors don't gather data when phone is idle

Discussion in 'Android Development' started by Louen, Feb 10, 2020.

  1. Louen

    Louen Lurker
    Thread Starter

    Hi everyone,

    I’m trying to develop an app for Android in which I pick up data from several sensors (if available on the device) and write it down to a file which will later be analyzed for certain uses.
    I’m facing several problems, a minor one which I can kind of ignore and a major one that I haven’t been able to solve and makes the app not work properly.

    - Minor problem

    I’m gathering data from: Accelerometer, Linear Accelerometer, Gyroscope and Magnetometer and also from the GPS but that works quite differently and can only be sampled at much lower frequencies, so I’ll ignore it for now.
    I gather the data by implementing a listener for each sensor:

    Code (Java):
    1.     public class AccelerometerWatcher implements SensorEventListener
    2.     {
    3.         private SensorManager sm;
    4.         private Sensor accelerometer;
    6.         AccelerometerWatcher(Context context) {
    8.             sm = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
    10.             assert sm != null;
    11.             if (sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
    12.                 accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    13.             }
    14.         }
    15.     }
    And I’m setting the frequency to ~50Hz by using:

    Code (Java):
    1.     sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
    When gathering data, I understand the frequency can’t be 100% stable, but the weird thing is it stays more or less stable on every sensor (at around 50Hz) except on the Accelerometer, where most of the time it samples at 100Hz and sometimes drops down to 50Hz.

    Is there something I might be doing wrong or any way to control this? So far it’s happened in every device I tried, although they don’t all behave in exactly the same way.

    - Major problem

    I’m writing down the info to a file by first writing everything I pick up from the sensors to a string and then every X seconds, writing what’s on the string to a file and clearing it so the sensor listeners can keep on writing on it but it doesn’t become infinitely long.

    I write on the string like this:

    Code (Java):
    1.      @override
    2.         public void onSensorChanged(SensorEvent event) {
    4.             if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
    5.                 return;
    8.                 if(initTime == -1)
    9.                     initTime = event.timestamp;
    11.                 MyConfig.SENSOR_ACCEL_READINGS += ((event.timestamp - initTime) / 1000000L) + MyConfig.DELIMITER + event.values[0] + MyConfig.DELIMITER + event.values[1] + MyConfig.DELIMITER + event.values[2] + "\n";
    12.     }
    And then save it to a file using this:

    Code (Java):
    1.     public class Utils {
    3.         private static Timer timer;
    4.         private static TimerTask timerTask;
    6.         public static void startRecording() {
    7.             timer = new Timer();
    8.             timerTask = new TimerTask()
    9.             {
    10.                 @override
    11.                 public void run()
    12.                 {
    13.                     // THIS CODE RUNS EVERY x SECONDS
    14.                     writeDataToFile();
    15.                 }
    16.             };
    17.             timer.scheduleAtFixedRate(timerTask, 0, MyConfig.SAVE_TIMER_PERIOD);
    18.         }
    20.         public static void stopRecording()
    21.         {
    22.             if(timer != null)
    23.                 timer.cancel();
    24.             if(timerTask != null)
    25.                 timerTask.cancel();
    27.             writeDataToFile();
    28.         }
    30.         private static void writeDataToFile()
    31.         {
    32.             String temp_accel = String.copyValueOf(MyConfig.SENSOR_ACCEL_READINGS.toCharArray());
    33.             WriteData.write(MyConfig.RECORDING_FOLDER, MyConfig.FILENAME_ACCEL, temp_accel);
    34.             MyConfig.SENSOR_ACCEL_READINGS = MyConfig.SENSOR_ACCEL_READINGS.replaceFirst(temp_accel, "");
    35.         }
    In the listener, every time I stop listening, I set “initTime” to -1 so the samples always start at 0 and go up to the duration of the listening period in miliseconds. (Ignore the DELIMITER it’s just a matter of formatting).

    My main app-breaking problem, is the following:

    In most phones (a few lucky ones work flawlessly) 1 or 2 things fail.

    In some, after being idle for a while (locked and in your pocket for example) the sensors stop recording data so the app just writes blank values until I wake the phone up again.

    In others, it’s even worse, not only do the sensors stop recording data, but the timer / writing to file, seems to stop working too, and when the phone wakes up again, it tries to write what it should’ve written while it wasn’t working and messes up all the timestamps, writing the same samples at different points “in the past” until it catches up to the current time. (If you visualize it as a graph, it basically looks as if the data gathering travelled back in time).

    Is there any way in which I can make sure that the app keeps on working no matter what, whether the phone is locked, dozing, the app is minimized, on the background, foreground, etc.?

    I tried a method I googled that consists of setting and alarm to "wake up the process" every X seconds (no matter what time I set to it, it only worked max once per minute).
    I saw how for a few miliseconds every time the alarm went off, it captured samples again but then went to sleep right away, it didn't keep the phone "awake" for a longer period of time.
    It solved nothing and even for the brief period it forced the sensors to gather data, it only helped wake up the sensors, the problem with the timer / writing to file still persisted.

    Hope someone can shed some light on how to keep the phone gathering data no matter what, I've been trying everything I could think of and I'm not getting anywhere. Sorry for the brick of text, but I didn't really know how to explain it in a shorter way.

    P.S: I saw that having the Battery Saver ON made it even worse, even on the phones where it usually worked properly, it started messing things up. So another question would be... How can I stop it from interfering?

    #1 Louen, Feb 10, 2020
    Last edited: Feb 13, 2020

Share This Page