0

I am trying to implement a CountDownTimer to post a visual text count-down until I get to 0, then send a specific message. Everything works fine until I get to 3 seconds, it calls the my done() method twice; once with 3 seconds left and once when the counter is done.

I am certain that the only time done() is called is when onFinish() in this CountDownTimer() is called. I have no clue why it is calling twice, and at consistently the same time.

My Java Code:

mainCounter = new CountDownTimer(30000, 1000){
@Override
public void onTick(long millisUntilDone){
    int hours = (int) (millisUntilDone/3600000);
    int mins = 0, secs = 0;
    long timeLeft = millisUntilDone % 3600000;
    if((int)timeLeft != 0){
        mins = (int) (timeLeft/60000);
    }
    long timeLeftStill = timeLeft % 60000;
    if((int)timeLeftStill != 0){
        secs = (int) (timeLeftStill/1000);
    }

    ((TextView)findViewById(R.id.timer_label)).setText("You have " + hours + " hours, " + mins + " mins, " + secs + " secs left");
    }

    @Override
    public void onFinish() {
    // Send Message, Out of Time
    ((TextView)findViewById(R.id.timer_label)).setText("MESSAGE!");
        num++;
        done();  //My Own Method
        this.cancel();
    }
}.start();

I have another counter that works perfectly, I have commented it out to ensure it doesn't affect this counter, and like I say this one works fine until I get to 3 second left.

zgc7009
  • 3,371
  • 5
  • 22
  • 34
  • What is line `178` in Trail.java file? Do you have some GPS stuff in your app? Why is caling `OnLocationChange` ? – Shobhit Puri Jun 01 '13 at 00:03
  • line 178 is the other ((TextView)findViewById(R.id.locat_label)).setText("Other message!"); I meant to add the LogCat where it says it is line 100, but accidentally added the one where it is commented out. And yes, I am working with speed. – zgc7009 Jun 01 '13 at 00:13
  • If its not the one you waned to show, please add the proper one. – Shobhit Puri Jun 01 '13 at 00:15
  • Fixed it, literally it is the exact same just line 100 instead of line 178 – zgc7009 Jun 01 '13 at 00:19
  • 1
    okay. Thanks :). Just curious as you why are you overriding those methods? – Shobhit Puri Jun 01 '13 at 00:20
  • Because Eclipse told me to :P, haven't messed with the timer's much didn't realize it wasn't a method that needed to be overriden. Thanks :) – zgc7009 Jun 01 '13 at 00:25
  • okay. You can try use debugger in eclipse, to see the values of the variables when just before it throws an exception. This will enable you to be more clear of the problem. – Shobhit Puri Jun 01 '13 at 00:26
  • I figured out the NPE was coming from an error in my done() method, but it doesn't change the fact that onFinish() is being called with 3 seconds left instead of when it is done (it is also being called again when it is done). Any clue? – zgc7009 Jun 01 '13 at 00:39
  • ^ Hey, I think i got the reason. See my answer for that. hat's the only thing that makes sense to me for the above behavior. – Shobhit Puri Jun 01 '13 at 01:02
  • @zgc7009 - I'm taking a stab here. It maybe due to the fact that you're calling `cancel()` within `onFinish()`. There's no reason to call `cancel()`. Give it a shot. – Karthik Balakrishnan Jun 01 '13 at 01:33

2 Answers2

1

For you problem concerning the call of onFinish() method when 3 seconds are left, you should read the answer here. Actually you should read all the answers on Android: CountDownTimer skips last onTick()! question. It will hep you understand the reason. Talking abou that thread, usually people have had problems where finish gets called approx. 1 second before the estimated time. For them it can be understood ( from the answer referenced) that at the start of every tick, before onTick() is called, the remaining time until the end of the countdown is calculated. If this time is smaller than the countdown time interval, onTick is not called anymore. But the answer there also states that there may be other processes in the background that delay the thread running CountDownTimer plus that Android itself will probably create a small delay when calling the message handler of CountDownTimer, so your undesired delay might be becauase of all that.

Few workaround have been suggested in the answers. One is either decreaseing the interval time or increasing the maximum countDownTimer value. There is also one alternative of countDownTimer method. Hope this helps you understand the possible reason and will aid you to do the workaround.

Community
  • 1
  • 1
Shobhit Puri
  • 25,769
  • 11
  • 95
  • 124
  • I appreciate your response, I will take a look. The problem I am having isn't necessarily that it is being called early is 3 seconds out of an hour doesn't mean much. It comes in the fact that it is being called twice even though it should only be called once. Hopefully your link helps. Thanks for your time. – zgc7009 Jun 01 '13 at 01:05
  • I'm curious to know why its happening. So if you get the answer please do coment. :). All the best! – Shobhit Puri Jun 01 '13 at 01:12
  • Right now I have implemented some interesting work arounds that work great but just look terrible in code haha. I haven't had a chance to read that yet, and when I figure out what the problem is I will definitely update. Thanks again. – zgc7009 Jun 01 '13 at 01:34
0

You can do like this

    private int secondsLeft = 0;
    private int minutes;
    private int seconds;
    private String timeString;

counter = new CountDownTimer(30000, 100) {
            public void onTick(long ms) {
                if (Math.round((float) ms / 1000.0f) != secondsLeft) {
                    secondsLeft = Math.round((float) ms / 1000.0f);
                    minutes = (secondsLeft % 3600) / 60;
                    seconds = secondsLeft % 60;
                    timeString = String.format("%02d:%02d", minutes, seconds);
                    textViewTimer.setText(timeString);
                }
            }
            public void onFinish() {
                textViewTimer.setText("00:00");
            }
        }.start();
Android Dev
  • 1,496
  • 1
  • 13
  • 25