I am developing a Human Activity Recognition Android application and I have to measure both time being sedentary (static) and time spent active. At first, I thought to store a long variable in the sharedPreferences and increment it every 5 seconds (I am classifying the user activity every 5 seconds) by 5000 (5 seconds in milliseconds).
However, when I start my service (I am using a background service to do the classification and store it in the SharedPreferences) and check at a later point - say after 2 hours, the time I have in the sharedPreferences and the actual time that has passed differs significantly. For example, I will start my service at 12pm and check at 2pm and the value in the shared preferences will be something like 40 minutes (when converted from milliseconds - value/1000/60 minutes).
P.S.: My service looks like that:
public class MyService extends Service implements SensorEventListener {
public static final String COUNTER_KEY = "counterKey3";
public int counter = 0;
private static final long WINDOW_LENGTH = 5000;
private long windowBegTime = -1;
private SensorManager mSensorManager;
private Sensor accSensor;
private ArrayList<Double> xValues = new ArrayList<>();
private ArrayList<Double> yValues = new ArrayList<>();
private ArrayList<Double> zValues = new ArrayList<>();
private SharedPreferences mSharedPreferences;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_GAME);
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
mSharedPreferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);
counter = mSharedPreferences.getInt(COUNTER_KEY, 0);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
xValues.add((double) sensorEvent.values[0]);
yValues.add((double) sensorEvent.values[1]);
zValues.add((double) sensorEvent.values[2]);
if (SystemClock.elapsedRealtime() - windowBegTime > WINDOW_LENGTH) {
if (windowBegTime > 0) {
mSharedPreferences.edit().putInt(COUNTER_KEY, mSharedPreferences.getInt(COUNTER_KEY, 0) + 5).apply();
Log.i("MyService", "WindowTimeIssue! " + mSharedPreferences.getInt(COUNTER_KEY, 0));
// DETECT ACTIVITY - store it in a db
}
windowBegTime = SystemClock.elapsedRealtime();
}
}
}
You need to make your service a foreground service. Background services are killed by OS when resources are needed.
Also, you should look into Activity Recognition API (https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionApi)