Search code examples
androidtimercountdowntimernumberpicker

How can I get my CoountDownTimer to stop ticking?


I'm making a simple timer in Android using a CountDownTimer and some NumberPickers. Right now when the user hits my button and the timer is not going it will start, when the hit the same button and timer is counting down it should stop. My problem is that it is not stopping. I call CountDownTimer.cancel() but this doesn't seem to do anything, the code in onTick() still continues to get executed, meaning the NumberPickers are still getting decremented as if the timer is still running.

I'm not sure if it is my code, or that I'm just using the CountDownTimer incorrectly. So when I call the Cancel() method should the onTick() events stop getting triggered? They don't seem to be so how can I do this?

I'll put some of my code here:

Code for my button:

@Override
public void onClick(View v) {
    //Calculate total time from NumberPickers in seconds
    long startTime = (numberPicker1.getValue() * 60) * 1000 + numberPicker2.getValue() * 1000;
    Log.i(TAG, "Start time: " + startTime + "");

    //Create CountDownTimer with values from NumberPickers
    countDownTimer = new MyCountDownTimer(startTime, interval);
    text.setText(text.getText() + String.valueOf(startTime / 1000));    //should be removed

    if(!timerHasStarted) {
        countDownTimer.start();
        timerHasStarted = true;

        //Disable the NumberPickers after 'Start' is pressed
        numberPicker1.setEnabled(false);
        numberPicker2.setEnabled(false);

        startButton.setText(R.string.stop);
    } else {
        countDownTimer.cancel();
        //countDownTimer = countDownTimer.pause();
        timerHasStarted = false;

        //Re-enable the NumberPickers after 'Start' is pressed
        numberPicker1.setEnabled(true);
        numberPicker2.setEnabled(true);

        startButton.setText(R.string.restart);
    }
}

onTick() code for my timer:

 @Override
    public void onTick(long millisUntilFinished) {
        text.setText("" + millisUntilFinished / 1000);

        //Decrement the NumberPickers after each second
        if(numberPicker2.getValue() > 0) {
            //When seconds left is greater than 0 decrement seconds
            changeValueByOne(numberPicker2, false);
        }
        else if(numberPicker1.getValue() > 0 && numberPicker2.getValue() <= 0) {
            //Else, if seconds <= 0 and minutes > 0 decrement minutes and reset seconds to 59
            changeValueByOne(numberPicker1, false);
            numberPicker2.setValue(59);
        }
        else if(numberPicker1.getValue() <= 0 && numberPicker2.getValue() <= 0){
            //Else, if both minutes and seconds <= 0 revert back to 0 and finish
            //This should never really happen, but just in case
            numberPicker1.setValue(0);
            numberPicker2.setValue(0);
            Log.i(TAG, "There is a tick when both are 0");
        }

        this.millisUntilFinished = millisUntilFinished;
    }

Solution

  • Problem: In your onClick() you are creating a new object of MyCountDownTimer for every click, without checking the value of timerHasStarted.

    countDownTimer = new MyCountDownTimer(startTime, interval);
    

    and then you are calling cancel() on this new object. Hence your countdown timer does not stop goes on.

    Solution:

    Create MyCountDownTimer object only if the value of timerHasStarted is false (in if block).

     @Override
     public void onClick(View v) {
        //Calculate total time from NumberPickers in seconds
        long startTime = (numberPicker1.getValue() * 60) * 1000 + numberPicker2.getValue() * 1000;
        Log.i(TAG, "Start time: " + startTime + "");        
    
        if(!timerHasStarted) {
    
            //Create CountDownTimer with values from NumberPickers
            countDownTimer = new MyCountDownTimer(startTime, interval); 
    
            countDownTimer.start();
            timerHasStarted = true;
    
            //Disable the NumberPickers after 'Start' is pressed
            numberPicker1.setEnabled(false);
            numberPicker2.setEnabled(false);
    
            startButton.setText(R.string.stop);
        } else {
            countDownTimer.cancel();
            //countDownTimer = countDownTimer.pause();
            timerHasStarted = false;
    
            //Re-enable the NumberPickers after 'Start' is pressed
            numberPicker1.setEnabled(true);
            numberPicker2.setEnabled(true);
    
            startButton.setText(R.string.restart);
        }
    }