Android CountDownTimer shows 1 for two seconds [duplicate] - android

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

Related

CountDownTimer skipping one second when displaying on TextView

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.

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

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

Sleep() in android

I am working on a mini game for Android. I am using this code to create a 3 minute timer that pauses when the game is paused:
class update extends Thread{
#Override
public final void interrupt(){
super.interrupt();
}
#Override
public void run(){
try{
while(true){
sleep(50);
iTime++;
if(iTime>=3600)
bEnd = true; //finish
postInvalidate();
}
}catch(InterruptedException e){
}
}
}
update thread = null;
3600 = 20*3*60
The timer finishes in the emulator within about 5 minutes, and in the Galaxy Tab after about 1.5 minutes.
Why doesn't it always take 3 minutes? How do I ensure that it finishes within 3 minutes?
How about using the Android CountDownTimer class?
// 30 second countdown
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
I am not sure what are you doing in the postInvalidate() but maybe you can do something with AlarmManager and a service. You could create a task that will run in 3 minutes from now, and it will execute the service which, in your case, will invalidate the game.
I've seen many questions that were trying to handle timeouts with sleep method and I believe Android doesn't guaranteed that it will work that way.
Post back if you need help creating the service or running something with AlarmManager. I answered a question about it a couple of days ago.

Categories

Resources