I'm using a chronometer and it needs to run persistently until stopped.
The code I'm using below works well and the chronometer keeps running, however, when the device restarts, I get negative values.
SharedPreferences sharedPreferences = getSharedPreferences("chronometer", MODE_PRIVATE);
//Check if the start time was saved before
long elapsedTime = sharedPreferences.getLong("elapsed_time", 0);
if (elapsedTime != 0) {
//It means the chronometer was running before, so we set the time from SharedPreferences
chronometer.setBase(elapsedTime);
chronometer.start();
}
//Code below starts the chronometer, after the user manually starts it
Button startButton = findViewById(R.id.btnStart);
startButton.setOnClickListener(v -> {
//Save the starting time
long elapsedRealtime = SystemClock.elapsedRealtime();
sharedPreferences.edit().putLong("elapsed_time", elapsedRealtime).apply();
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
});
Why does the chronometer display negative values after a re-boot & how can I sort it out?
From Android Documentation
The timebase of this class is based on SystemClock.elapsedRealtime().
Back to your questions:
Here is an example to demonstrate this scenario.
Assume your phone is running about 10 minutes from last booting, at that time users open the activity, the
elapsedRealtime()method will return 600000L (10 mins = 10 * 60 * 1000 milliseconds). When users click on the Start button, you set that time for Chronometer as basetime and save 600000L to SharePreferences usingelapsed_timekey.Right now:
elapsedRealTime()= 10 mins | Chronometer = 00:00After 1 min:
elapsedRealtime()= 11 mins | Chronometer = 01:00After 10 minutes:
elapsedRealTime()= 20 mins | Chronometer = 10:00At this time users press the BACK key to exit the app and restart the phone.
The phone is kinda slow, so it took 2 mins from booting. Users open the activity again. At this time.
elapsedRealtime()returns 120000L (2 mins = 2 * 60 * 1000 milliseconds)The value you saved in the SharePreferences (
elapsed_time) is 600000LBecause the value you set as basetime of Chronometer is ahead of the
elapsedRealtime(), so the Chronometer will display -08:00 and start counting up from that value.You can save the elapsed time of Chronometer and the elapsed time from the last time users leave the activity until the next time users open the activity. Then using these two values to calculate the basetime for Chronometer.
activity_main.xml
MainActivity.java