1

I´m using a Chronometer in my Android App. I can start it, stop it and continue counting after pushing the start button again:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_projektbeschreibung, container, false);



    if (savedInstanceState != null){
        stoppedmillis = savedInstanceState.getLong(STATE_TIME);
        hh = savedInstanceState.getString(STATE_HH);
        mm = savedInstanceState.getString(STATE_MM);
        ss = savedInstanceState.getString(STATE_SS);

    }



    mChronometer = (Chronometer) rootView.findViewById(R.id.chronometer2);
    mChronometer.setText(hh + ":" + mm + ":" + ss);
    mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
        @Override
        public void onChronometerTick(Chronometer cArg) {
            long time = SystemClock.elapsedRealtime() - cArg.getBase() ;
            int h = (int) (time / 3600000);
            int m = (int) (time - h * 3600000) / 60000;
            int s = (int) (time - h * 3600000 - m * 60000) / 1000;
            hh = h < 10 ? "0" + h : h + "";
            mm = m < 10 ? "0" + m : m + "";
            ss = s < 10 ? "0" + s : s + "";
            cArg.setText(hh + ":" + mm + ":" + ss);

        }
    });


    ((Button) rootView.findViewById(R.id.startbutton)).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //if first start
            if(stoppedmillis == 0) {
                mChronometer.setBase(SystemClock.elapsedRealtime());


            } else {//Point A
                long pausetime = (SystemClock.elapsedRealtime() - stoppedmillis);
                mChronometer.setBase(mChronometer.getBase() + pausetime);
            }
            mChronometer.start();

        }
    });

    ((Button) rootView.findViewById(R.id.stopbutton)).setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View view) {
        mChronometer.stop();
        stoppedmillis = SystemClock.elapsedRealtime();
        }
    });

After a screen rotation (so the Activity restarts) the chronometer starts counting from the point of 00:00:00 again. My first try was to save the stoppedmillis with a onSaveInstanceState method like the following:

 public void onSaveInstanceState(Bundle savedInstanceState){
    savedInstanceState.putLong(STATE_TIME, stoppedmillis);
    savedInstanceState.putString(STATE_HH, hh);
    savedInstanceState.putString(STATE_MM, mm);
    savedInstanceState.putString(STATE_SS,ss);

    super.onSaveInstanceState(savedInstanceState);
}

Now, I can get the value of the stoppedmillis after a restart, but I don't know how to set the Base for the Chronometer with the help of the stoppedmillis. At Point A in the Code you can see how it works with stopping the Chronometer with a button but this part of code does not working after a screen rotation.

Snowman
  • 169
  • 4
  • 17

4 Answers4

0

I know that this is old. Although, I have created a simple application using a chronometer and done the following and it has kept counting across screen rotation. It is spot on with Andrew's original answer. Here is how I outlined it:

Chronometer mChronometer; // this is a global variable

@Override
protected void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     mChronometer = (Chronometer)findViewById(R.id.chronometer);


    if(savedInstanceState != null){

       mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
       mChronometer.start();
          }

    }

Now set up onSaveInstanceState:

  @Override
  public void onSaveInstanceState (Bundle savedInstanceState){
     super.onSaveInstanceState(savedInstanceState);

     savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
   }
0

Fast solution, using this class: https://github.com/ahmedrizwan/ChronometerPersist/blob/master/chronometerpersist/src/main/java/library/minimize/com/chronometerpersist/ChronometerPersist.java

ChronometerPersist chronometerPersist = ChronometerPersist.getInstance(chronometer, sharedPreferences);

//Starting the chronometer
startChronometer();
//Stoping the chronometer
stopChronometer();
//Pausing the chronometer
pauseChronometer();

I have lost much time trying to restore the current time with the android chronometer widget.

Pablo Cegarra
  • 20,955
  • 12
  • 92
  • 110
0

This is how i solved saving the state of the Chronometer.

 private static final int TIME_MULTIPLIER = 60;

Step 1: Convert time to Seconds:

NOTE: If you don't like my method of converting time to second you could do your ways.

 private static int convertTimeToSeconds(Long... time) {
    int seconds = 0;
    if (time.length == 2) {
        seconds += time[0] * TIME_MULTIPLIER + time[1];
    } else if (time.length == 3) {
        seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
    }
    return seconds;
}

Step 2: Setting and starting time of Chronometer

NOTE: I'm saving the data in a custom object persist that object with any database / SharedPreference / your wish.

 public static void setAndStartTime(final Chronometer chronometer) {
    long second = 0;

   // i have multiple time saved into map. You could save just 1 time and reuse that time.
    for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
        second += data.getDailyTimeSpent();
    }
    chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
    chronometer.start();
}

Step 3: Saving Time:

public static void saveTime(String timeText) {
    String[] timeParts = timeText.split("[:]");
    long savedTime = 0;
    if (timeParts.length == 2) {
        savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
    } else if (timeParts.length == 3) {
        savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
    }
    DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
}

Calling the saved method:

      ChronoHelper.saveTime(chronometer.getText().toString());

COMPLETE CLASS:

public class ChronoHelper {

private static final int TIME_MULTIPLIER = 60;

public static void setAndStartTime(final Chronometer chronometer) {
    long second = 0;
    for (DailyData data : DailyData.DailyDataHolder.getDailyDataMap().values()) {
        second += data.getDailyTimeSpent();
    }
    chronometer.setBase(SystemClock.elapsedRealtime() - (second * 1000));
    chronometer.start();
}

public static void saveTime(String timeText) {
    String[] timeParts = timeText.split("[:]");
    long savedTime = 0;
    if (timeParts.length == 2) {
        savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]));
    } else if (timeParts.length == 3) {
        savedTime = convertTimeToSeconds(Long.parseLong(timeParts[0]), Long.parseLong(timeParts[1]), Long.parseLong(timeParts[2]));
    }
    DailyData.DailyDataHolder.getDailyData().setDailyTimeSpent(savedTime);
}

private static int convertTimeToSeconds(Long... time) {
    int seconds = 0;
    if (time.length == 2) {
        seconds += time[0] * TIME_MULTIPLIER + time[1];
    } else if (time.length == 3) {
        seconds += (time[0] * TIME_MULTIPLIER) + (time[1] * TIME_MULTIPLIER) + (time[2]);
    }
    return seconds;
}

public static String secondsToTimeText(DailyData dailyData) {
    long savedSeconds = dailyData.getDailyTimeSpent();
    long minutes = savedSeconds / TIME_MULTIPLIER;
    long seconds = savedSeconds % TIME_MULTIPLIER;
    long hours = minutes / TIME_MULTIPLIER;
    return hours + ":" + minutes + ":" + seconds;
   }
}
Sz-Nika Janos
  • 811
  • 6
  • 19
-1

Save the base time of the chronometer in onSaveInstanceState and set it back in onRestoreInstanceState like this:

public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putLong("ChronoTime", mChronometer.getBase());
    super.onSaveInstanceState(savedInstanceState);
}

public void onRestoreInstanceState(Bundle savedInstanceState){
    if((savedInstanceState !=null) && savedInstanceState.containsKey("ChronoTime"))
        mChronometer.setBase(savedInstanceState.getLong("ChronoTime"));
    super.onRestoreInstanceState(savedInstanceState);
}
Andrew Brooke
  • 12,073
  • 8
  • 39
  • 55
  • Cannot resolve the method onRestoreInstanceState...I have just tried to save the base time with the onSaveInstanceState and restore it with the if (savedInstance != null), but its not possible to set the Chronometer base there. Saving the Chronometer base in a variable and reset the base with the variable causes the Chronometer to count wrong – Snowman Aug 19 '15 at 11:21
  • You can put the `onRestoreInstanceState` code in `onCreate`. Calling `chronometer.setBase()` with the value that is saved in `onSaveInstanceState` does work. It continues to count up, even when the phone's orientation changes. – Andrew Brooke Aug 19 '15 at 18:56