I had a similar question about the Chronometer class and how to survive orientation changes. While there are several useful posts and examples, none that I found addressed the total question.
This was a helpful post here Android_Chronometer pause, which helped with demonstrating the need to save the elapsedTime in order to resume timing.
However, this did not discuss how to make the Chronometer survive Android life cycle orientation changes. What you do with the elapsed time is slightly different between when the timer is running vs. when it is paused.
Here is that I did to put it all together - pausing, resuming, resetting, in a nice class, and surviving orientation:
public class ChronometerWithPause extends Chronometer {
private long timeWhenStopped = 0;
private boolean isRunning = false;
private final String getTimeKey() {
return "KEY_TIMER_TIME" + getId();
}
private final String getIsRunningKey() {
return "KEY_TIMER_RUNNING" + getId();
}
public ChronometerWithPause(Context context) {
super(context);
}
public ChronometerWithPause(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChronometerWithPause(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void start() {
setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
isRunning = true;
super.start();
}
@Override
public void stop() {
isRunning = false;
timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
super.stop();
}
public void reset() {
stop();
isRunning = false;
setBase(SystemClock.elapsedRealtime());
timeWhenStopped = 0;
}
public boolean isRunning() {
return isRunning;
}
public long getCurrentTime() {
return timeWhenStopped;
}
public void setCurrentTime(long time) {
timeWhenStopped = time;
setBase(SystemClock.elapsedRealtime() - timeWhenStopped);
}
public void saveInstanceState(Bundle outState) {
if (isRunning) {
timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
}
outState.putLong(getTimeKey(), getCurrentTime());
outState.putBoolean(getIsRunningKey(), isRunning());
}
public void restoreInstanceState(Bundle inState) {
isRunning = inState.getBoolean(getIsRunningKey());
setCurrentTime(inState.getLong(getTimeKey()));
timeWhenStopped = SystemClock.elapsedRealtime() - getBase();
if (isRunning) {
super.start();
}
}
}
Note that you can use this in onSaveInstanceState()
and onCreate()
like this:
protected void onSaveInstanceState(Bundle outState) {
...
timer.saveInstanceState(outState);
...
and then in onCreate you can restore the timer function with:
if (savedInstanceState != null) {
// . . .
timer.restoreInstanceState(savedInstanceState);
// . . .
}