1

I have made a Countdown to a future date (with remaining days, hours, minutes, seconds) using CountDownTimer and lots of code from this answer: https://stackoverflow.com/a/32773716/3984944 Now I want to do exactly the same but counting up from a past date. My TextView should refresh every second and show the elapsed time.

What I tried:
I tried manipulating the CountDownTimer so that it works in reverse order. Changing the interval to -1000 or adding 2000 milliseconds to the Countdown every second. Both didn't work.
Then I figured I should use the Chronometer class. The standard Chronometer only displays hours, minutes and seconds as far as I'm concerned. So no days. I then wrote the following code in the style of the CountDownTimer answer I found before that updates a TextView with the desired data:

    final Chronometer ch = (Chronometer) findViewById(R.id.ch_chronometer);
    final TextView tv = (TextView) findViewById(R.id.tv_show_stopwatch);

    ch.setBase(endMillis); //endMillis is the date in Milliseconds

    chCountdownSince.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
        public void onChronometerTick(Chronometer cArg) {
            long t = System.currentTimeMillis() - chCountdownSince.getBase();

            long days = TimeUnit.MILLISECONDS.toDays(t);
            t -= TimeUnit.DAYS.toMillis(days);

            long hours = TimeUnit.MILLISECONDS.toHours(t);
            t -= TimeUnit.HOURS.toMillis(hours);

            long minutes = TimeUnit.MILLISECONDS.toMinutes(t);
            t -= TimeUnit.MINUTES.toMillis(minutes);

            long seconds = TimeUnit.MILLISECONDS.toSeconds(t);
            String stopwatchDisplay = "Days: %d Hours: %d Minutes: %d Seconds: %d";
            stopwatchDisplay = String.format(stopwatchDisplay, days, hours, minutes, seconds);
            tv.setText(stopwatchDisplay);
        }
    });

I feel like this snipped makes absolute sense but upon execution it doesn't change my TextView at all. I feel like this is just not how Chronometer works but I don't know what I'm doing wrong.

Community
  • 1
  • 1
Tobias Mayr
  • 196
  • 4
  • 16

2 Answers2

1

Edit :

I think you forgot to start Chronometer completely.

Given that

The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete.

Its unlikely that ticks are done on UI thread, but this is exactly where you need to set your text, try changing

tv.setText(stopwatchDisplay);

to

tv.post(new Runnable() {
    public void run() {
        tv.setText(stopwatchDisplay);
    });
Oleg Bogdanov
  • 1,712
  • 13
  • 19
0

please use handler..

public void countDownStart() {
    handler = new Handler();
    runnable = new Runnable(){
        @Override
        public void run(){
            handler.postDelayed(this,1000);
            try {
                FestCountdownTimer timer = new FestCountdownTimer(00, 00, 9, 3, 01, 2017);
                new CountDownTimer(timer.getIntervalMillis(), 1000) {
                    @Override
                    public void onTick(long millisUntilFinished){
                        int days = (int) ((millisUntilFinished / 1000) / 86400);
                        int hours = (int) (((millisUntilFinished / 1000)
                                - (days * 86400)) / 3600);
                        int minutes = (int) (((millisUntilFinished / 1000)
                                - (days * 86400) - (hours * 3600)) / 60);
                        int seconds = (int) ((millisUntilFinished / 1000) % 60);
                        String countdown = String.format("%02dd %02dh %02dm %02ds", days,
                                hours, minutes, seconds);
                        txtTimerDay.setText("" + String.format("%02d", days));
                        txtTimerHour.setText("" + String.format("%02d", hours));
                        txtTimerMinute.setText(""
                                + String.format("%02d", minutes));
                        txtTimerSecond.setText(""
                                + String.format("%02d", seconds));
                    }
                    @Override
                    public void onFinish() {
                        textViewGone();
                MainActivity.aSwitch.setChecked(false);
        creditText.setText("Toggle On To Start");
                    }
                }.start();
            } catch (Exception e) {
                e.printStackTrace();                }
        }
    };
    handler.postDelayed(runnable, 1 * 1000);

}

Remember, 9 is Hours,3 is date,1 is Febraury Month..Month starts from 0th Index

FestCountdownTimer class

public class FestCountdownTimer {
    private long intervalMillis;
    public FestCountdownTimer(int second, int minute, int hour, int monthDay, int month, int year) {
        Time futureTime = new Time();
        // Set date to future time
        futureTime.set(second, minute, hour, monthDay, month, year);
        futureTime.normalize(true);
        long futureMillis = futureTime.toMillis(true);
        Time timeNow = new Time();
        // Set date to current time
        timeNow.setToNow();
        timeNow.normalize(true);
        long nowMillis = timeNow.toMillis(true);
        // Subtract current milliseconds time from future milliseconds time to retrieve interval
        intervalMillis = futureMillis - nowMillis;
    }
    public long getIntervalMillis() {
        return intervalMillis;
    }
}

Hope it helps.. :)

Ajay Jayendran
  • 1,584
  • 4
  • 15
  • 37
  • Thanks! Isn't Time() deprecated? I would like to avoid that. – Tobias Mayr Dec 31 '16 at 21:14
  • I got it running setting the Timer to a date in the past(since that is what I want) and setting the `timer.getIntervalMillis()` to the negative number. It shows me the correct time but the seconds and minutes are sort of "twitching". The longer the timer runs the worst it gets. After a while the seconds are unreadable because they change the value 50 times a second. – Tobias Mayr Dec 31 '16 at 22:57