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;
}
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);
}
}