CountDownTimer skipping one second when displaying on TextView - android

I want to display a simple CountDownTimer in a TextView, but it seems to go from 30 down to 28 right away, as if there was a lag in between. I'm not sure how to go about on fixing this small bug. Here is my code:
This is in the click listener of the Button:
new CountDownTimer(30000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
coolDownTimer.setText("Cool Down for: " + String.valueOf(millisUntilFinished / 1000));
}
#Override
public void onFinish() {
animatedPic.setClickable(true);
// reregister the proximity sensor
sm.registerListener(sensorListener, proxSensor, SensorManager.SENSOR_DELAY_NORMAL);
coolDownTimer.setText("GO!");
}
}.start();

There are 2 issues:
The first issue is that the countdown timer doesn't execute until time has elapsed for the first tick, in this case, after 1000ms.
The second is that the elapsed time is only approximate. millisUntilFinished is not guaranteed to come in increments of the interval (you can see that if you don't divide by 1000, the first tick is slightly under 29000).
Another thing to keep in mind is that you're not guaranteed to receive a tick call. That is to say, if the device did not have enough time to complete a tick, it may skip it (generally only noticeable for faster intervals).
To solve issue 1, you can simply run the onTick code (or refactor it into its own method) and run it as you start the countdown timer.
For issue 2, you can simply round the number.
For example:
new CountDownTimer(30000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
performTick(millisUntilFinished);
}
#Override
public void onFinish()
{
animatedPic.setClickable(true);
// reregister the proximity sensor
sm.registerListener(sensorListener,proxSensor,SensorManager.SENSOR_DELAY_NORMAL);
coolDownTimer.setText("GO!");
}
}.start();
performTick(30000);
void performTick(long millisUntilFinished) {
coolDownTimer.setText("Cool Down for: " + String.valueOf(Math.round(millisUntilFinished * 0.001f)));
}
If you want to make sure the appropriate value is updated with minimal latency, you may want to consider reducing the interval.

It is skipping because CountDownTimer is not a precise timer. Try to print just the millisUntilFinished without dividing it you'll see some excess number that it wont be exactly 29000 when it hits its first tick.
you can refer on this thread for the solution.

Related

Android - Properly creating and countdown of timer?

Ive been working hard this week at learning android, and one thing I cant find a good
example for is timers, so if someone could maybe take the time to write asimple timer that counts down and displays in a textview, i would be eternally grateful, thanks a lot!
Following code will start from 30sec and end when it reaches 1 sec. Please note that timer uses milliseconds instead for seconds.
1 sec = 1000 milliseconds
Thus, 30 sec = 30x1000 milliseconds
mTextField is your regular TextView, replace it with your own TextView.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();

I'd like to make a countdown timer do a continuous loop in android - need opinions on how to do it

Is there a way to continuously loop through a countdown timer? I have a basic timer of going though 60 seconds, then updating a text field and it's working, but I want to add the functionality: when it's counted down, to automatically restart again until the user cancels it? Maybe run it through a thread? Not sure how to handle it. Here is what I have, and again, this code works, but I can only stop and start the countdown timer, not do a continuous loop:
cdt = new CountDownTimer(60000,1000) {
public void onTick(long millisUntilFinished) {
tvTimer.setText("remaining : " + millisUntilFinished/1000 + " secs");
}
public void onFinish() {
tvTimer.setText("");
bell.start();
}
};
/***************On Click/Touch Listeners*******************/
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tvTimer.setText("");
btnStart.setText("Start Timer");
SetImageView2(myDbHelper);
cdt.cancel();
}
});
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!TimerTicking){
cdt.start();
btnStart.setText("Stop Timer");
}
else {
tvTimer.setText("");
cdt.cancel();
btnStart.setText("Start Timer");
}
}
});
One very basic way to loop a CountDownTimer is to call start() in onFinished().
public void onFinish() {
...
start(); // Start this timer over
}
(Make sure you cancel your CountDownTimer in onPause() when you do this otherwise the timer might leak and keep firing in the background... Oops.)
However CountDownTimers has fundamental flaws (in my opinion): it often skips the last call to onTick() and it gains a few milliseconds each time onTick() is called... :( I re-wrote CountDownTimer in a previous question to be more accurate and call every tick.
The first value to the CountDownTimer() constructor, the total time to run, is a long and can hold a value approaching 300 million years. That ought to be long enough for most mobile applications. :-)
So just call it with cdt = new CountDownTimer(Long.MAX_VALUE, 1000) for a one second loop that will run continously.

How can I display countdown timer on the canvas in android?

I am making a simple android app in which i want to display countdown timer on canvas.
I just want that when the game starts the countdown timer begins with 60 sec and decrements along.....
Pls can someone suggests me how do i use the countdown timer class?
There's plenty of documentation available if you actually look for it:
// 60 second (60000ms) timer with ticks every second (1000ms)
new CountDownTimer(60000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Now just replace the mTextField.setText() lines to something that would update your Canvas (or update the variable the Canvas uses for your time notification, then invalidate() the Canvas to display the update).
Even though I believe it's self-explanatory, when onFinish() is called, the CountDownTimer has reached 0 and is finished counting down.

how can i set the time in digital clock

I want to build an android application, this application allow the users to answer some questions.
For every question, User have to answer it in 360 seconds, so I want to make a digital clock starts from 360secons and then down to 0 seconds
I read that I can't set time on digital clock , is it so?
or I have to use Chronometer?
this is my digital clock
DigitalClock timer;
public void init(){
timer=(DigitalClock)findViewById(R.id.dcTimer);
}
any help appreciated.
Use CountDownTimer instead.
That link also shows you how to update a TextView every 1 second.
Just change new CountDownTimer(30000, 1000) so the first parameter is 360000 instead of 30000 and that will give you a good start to your code.
EDIT : You need to import android.os.CountDownTimer and the code example I referred to is below. Good luck.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();

Android CountDownTimer shows 1 for two seconds [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How come millisUntilFinished cannot detect exact CountDownTimer intervals?
Why does using the CountDownTimer show "1" twice? I just want it to countdown smoothly and not look like it is getting hung up on the last second. Anybody have any ideas on how to solve this problem??
Here is the code from the Android Developers page:
new CountdownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
I created a new project and copied and pasted this code in just to make sure that I wasn't accidentally messing something up in my program. I've been testing this on a Tab 10.1. It does this when I run it: "5", "4", "3", "2", "1", "1", "done!".
The CountDownTimer is not precise, it will return as close to 1 second (in this case) as it can but often that won't be enough to give you what you want.
If you Log the ms var you will see that the result is something like 29384 for the first hit, and so on, it will never be 30000, 29000 etc. There is no way to get the precision you need to make the counter work as you intended as currently implemented.
You can fix this for most cases. First lower you interval so that you get more updates than what you want to output, so instead of 1 second do 100ms and that should get you the illusions of a 1 second countdown timer since you will get at least a few updates per second (worst case)
To optimize that bit round the result on each entry and do a simple check to see if you should do the update (secondsLeft has changed) and if it has update the UI and the secondsLeft accumulator. Also I suggest that onFinish produce the final result (0) just in case the system glitches because something is happening that eats cpu cycles.
Anyway here is the modified code that works for this 99.99 times out of a 100 if your system is not loaded heavily. NOTE: You can probably get away with 250ms, up to you really.
int secondsLeft = 0;
new CountDownTimer(30000, 100) {
public void onTick(long ms) {
if (Math.round((float)ms / 1000.0f) != secondsLeft)
{
secondsLeft = Math.round((float)ms / 1000.0f);
TV.setText("seconds remaining: " +secondsLeft );
}
Log.i("test","ms="+ms+" till finished="+secondsLeft );
}
public void onFinish() {
TV.setText("0");
}
}.start();

Categories

Resources