CountDownTimer been decreses by 2, which should be just 1 sec - java

I'm creating a quiz game, and there is a countdown timer. But, the countdown decreases by two seconds, which should be just one second. My code is working okay sometimes, but when I install it again, it decreases again in 2 seconds.
countDownTimer = new CountDownTimer(timer, 1200) {
#Override
public void onTick(long l) {
timeText.setText(String.valueOf(timeValue));
timeValue = timeValue - 1;
if (timeValue == -1){
FLAG = 3;
playAudio.setAudioforEvent(FLAG);
timerDialog.timerDialog();
}
}
#Override
public void onFinish() {
// timerDialog.timerDialog();
}
}.start();

Related

Looping through Countdown

I am trying to loop through a CountDownTimer several times but the problem is the loop finishes before the timer finishes so the countdown only runs once.
function that loops through the timer
private void doWorkout(){
int currentSet = 1;
for (int i = 1; i<= NUMBER_OF_SETS; i++){
Log.d(TAG, "doWorkout: iteration " + i);
startWorkoutTimer();
//make for loop sleep till timer is done
}
}
private void startWorkoutTimer() {
mWorkoutCountDownTimer = new CountDownTimer(START_TIME, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mWorkRestLabel.setText("Work");
mWorkRestLabel.setVisibility(View.VISIBLE);
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mWorkoutTimerRunning = false;
mButtonStartPause.setText("start");
mButtonStartPause.setVisibility(View.INVISIBLE);
mButtonReset.setVisibility(View.VISIBLE);
mWorkRestLabel.setVisibility(View.INVISIBLE);
startRestTimer();
}
}.start();
mWorkoutTimerRunning = true;
mButtonStartPause.setText("pause");
mButtonReset.setVisibility(View.INVISIBLE);
}
The for loop doesn't wait for the CountDownTimer to finish. So it is starting all the timers at once, so it looks like it only ran once.
To fix this, instead of a loop, you have to start a new timer in startRestTimer() (which as per your code is in onFinish() & runs after a timer is finished) when NUMBER_OF_SETS is > 0 and decrement the NUMBER_OF_SETS.
So, it will run one after another.
Hope it helps.

Java Android, Countdown Timer and ProgressBar (read first)

I have count down timer which is display by ProgressBar and successfully. But unfortunately there is problems.
The progressBar Start in 1/5 instead 0/5. and Stuck 2 seconds in 4/5 progress
If I recall the Function of Count down Timer before
public void onFinish() {
progresBar.setProgress(100);
}
display will be mess up for a while.
I really miss Unity Engine with Time.deltaTime;
Here is my code:
countDownTimer2 = new CountDownTimer(5000,1000) {
int i = 0;
#Override
public void onTick(long milliSecondUntilFinished) {
i++;
progresBar.setProgress((int) i * 100 / (5000/1000));
}
#Override
public void onFinish() {
progresBar.setProgress(100);
}
}.start();
You are incrementing your i variable before setting your progress. When onTick() is called for the first time, the value of i is 1. Thus progress you are setting is 20 which is equivalent to 1/5. Use this -
#Override
public void onTick(long milliSecondUntilFinished) {
progresBar.setProgress((int) i * 100 / (5000/1000));
i++;
}
Also, you should better use milliSecondUntilFinished to find progress instead of unneccesarily introducing i variable.
For the problem with the display, I highly doubt that you have not canceled the timer already running before calling a new one. If yes, then both timer would be running until older one finishes (till this point, the progress bar will be behaving weirdly).
You can cancel the previous timer as -
countDownTimer2.cancel();
Do this before starting a new one.
Using:
countDownTimer2 = new CountDownTimer(1000,5000) {
int i = 0;
#Override
public void onTick(long milliSecondUntilFinished) {
i++;
progresBar.setProgress((int) i * 100 / (5000/1000));
}
#Override
public void onFinish() {
progresBar.setProgress(100);
}
}.start();

How to loop countdown timer multiple times

I am having a problem repeating countdown timer multiple times,in my case 12 times. I have made two countdown timers,one for roundtime and one for pause and works great.Problem is when the pause is finihed I want that roundtime countdown starts again automaticly until 12 rounds with pause are finished.
I use for loop.Is there any better way?
Here is code: when user clicks the button countdown starts
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
long roundtime= Long.parseLong(String.valueOf(msg1))*1000;//user has picked roundtime
Counting timer = new Counting(roundtime, 100);//class Counting extends CountdownTimer
for(int i=0;i<12;i++){
timer.start(); // It goes just ones!
}
}
And countdown timer:
class Counting extends CountDownTimer {
public Counting(long roundtime, long countDownInterval) {
super(roundtime, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
textView.setText("" + String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
#Override
public void onFinish() { // When roundtime is finished,start pause time!
int seconds = msg1 % 60;
int minutes = (msg1 / 60) % 60;
textView.setText(String.format("%02d : %02d", minutes, seconds));
long pause= Long.parseLong(String.valueOf(msg2))*1000; //user has picked pause time
Counting2 timer2 = new Counting2(pause, 100);
timer2.start();
}
}
class Counting2 extends CountDownTimer {
public Counting2(long pause, long countDownInterval) {
super(pause, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
textView2.setText("" + String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
#Override
public void onFinish() {
int seconds = msg2 % 60;
int minutes = (msg2 / 60) % 60;
textView2.setText(String.format("%02d : %02d", minutes, seconds));
}
}
});
}
First off, you want it to loop 12 times.
This isn't the issue at hand, however, you'll thank me when it only loops 11 times.
it should be
for(int i=0;i<=12;i++){
timer.start(); // It goes just ones!
}
As I do not know the implementation of Counting2, it appears to be getting hung up on the start function there. I do not know if it's overridden or not. If you have a similar onFinish method, this is due to a recursive call back on the original Counting timer. Because of this, it loops with a waiting period in between (It doesn't get a stack overflow 'as quickly' as a result).
Try busy waiting for the previous timer to finish and then start it again, and it'll do so 12 times.
for(int i=0;i<12;i++){
while(!previousTimerActive);
timer.start();
previousTimerActive = true;
}
And in your Counting2's onFinish() set the indicator previousTimerActive = false;. Now you just need to see what way you want this boolean previousTimerActive to be 'global' (so it can be accessed from both your activity and your class Counting2). You can get it and set it in the SharedPreferences or use a third-party tool like EventBus to send it's value from one to the other.

How to store countdown timer value in a variable?

So, I have a countdown timer in my activity. Now, I have a button which opens another activity. When that button is clicked I need to store the current countdown timer value, and start a countdown timer in the second activity from that saved value. I was thinking to pass the time using the Intent but I don't know what value to pass. How can I do that? My timer:
public String formatTime(long millis) {
String output = "00:00";
long seconds = millis / 1000;
long minutes = seconds / 60;
seconds = seconds % 60;
minutes = minutes % 60;
String sec = String.valueOf(seconds);
String min = String.valueOf(minutes);
if (seconds < 10)
sec = "0" + seconds;
if (minutes < 10)
min= "0" + minutes;
output = min + " : " + sec;
return output;
}
And in onCreate method:
// New timer for 40 minutes, starts after initialization
new MyCount(2400000, 1000)
{
// Updates the text on your "scoreboard" every second
public void onTick(long millisUntilFinished)
{
vreme.setText("" + formatTime(millisUntilFinished));
}
public void onFinish()
{
}
}.start();
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
public void onFinish() {
}
public void onTick(long millisUntilFinished) {
vreme.setText("" + millisUntilFinished / 1000);
}
It doesn't look like the information you're looking for is available from the CountDownTimer. If you don't need to be very precise with your time then you can just pull the string out of vreme.
Assuming you want to be more precise than that, I would suggest saving a timestamp when the timer starts, and then get the difference between that and the current time when you need to know how much time has elapsed. Check out uptimeMillis() or elapsedRealtime() depending on your needs.
OK, to answer myself. Here's what I did. In my first activity I did all the stuff in original post, plus I added this, in MyCount method, right below vreme.setText....:
currentTime = millisUntilFinished;
And previously I declared in my activity scope:
long currentTime;
After that, on my button onClickListener I did this:
Intent i = new Intent(Game1.this, Game2.class);
i.putExtra("timeCode", currentTime);
startActivity(i);
After that in my Game2 class's onCreate method (also declared long variable):
Bundle extras = getIntent().getExtras();
if(extras !=null) {
currentTime = extras.getLong("timeCode");
}
Then this (it's basically the same code from the Game1 class, only one change, my passed variable instead that 240000 value):
new MyCount(currentTime, 1000)
{
// Updates the text on your "scoreboard" every second
public void onTick(long millisUntilFinished)
{
vreme.setText("" + formatTime(millisUntilFinished));
}
public void onFinish()
{
}
}.start();
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
public void onFinish() {
}
public void onTick(long millisUntilFinished) {
vreme.setText("" + millisUntilFinished / 1000);
}
And it works like a charm!

Why is my countdown timer in Android so slow?

I'm trying to make a countdown timer in android for use in a small android app. The app will countdown from some number of seconds to 0, upon which it will do some action. I'm using the coundowntimer supplied by android.os.countdowntimer. Here is my code:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quizlayout);
new CountDownTimer(30000, 1000) {
TextView tx = (TextView) findViewById(R.id.textView2);
public void onTick(long millisUntilFinished) {
tx.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
tx.setText("done!");
}
}.start();
}
However, this countdown timer is really slow. It takes like 3 real-time seconds for the timer to countdown by one second. I wonder what's going on? The code I have above is more or less copied straight from google (CountDownTimer)
Can anyone help me as per why my timer is so slow, and offer a way to speed it up a bit?
(EDIT): I am running this on an emulator, the intel atom x86. I am emulating an android 2.3.3 environment.
According to Android documentation for countdown timer
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
Take a look at this example for countdown timer
Countdown timer example
Alternately you can spawn a new thread and just get that thread to sleep for the interval you want and take actions when it wakes or vice versa.
You can also timertask
use a handler that will post the same runnable . this will remove the need for extra threads :
Handler handler=new Handler();
handler.postRunnable(... , 1000) ;
in the runnable , call the postRunnable again for the same handler (and add a condition for when to stop) .
CountDownTimer is not efficient regardless to ui updating performances. For a flawless ui update, it is better to create a custom countdown. I did my own so here it is. It is flawless on my app.
public abstract class CountDown {
int totalTime = 0;
int tickTime = 0;
Thread thread;
boolean canceled = false;
public CountDown(int totalTime,int tickTime){
this.totalTime = totalTime;
this.tickTime = tickTime;
}
public abstract void onTick();
public abstract void onFinish();
public void start(){
thread = new Thread(new Runnable() {
#Override
public void run() {
// Do in thread
canceled = false;
for (int elapsedTime = 0; elapsedTime < totalTime; elapsedTime += tickTime) {
if(!canceled){
onTick();
try {
thread.sleep(tickTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
if(!canceled){
onFinish();
}
}
});
thread.start();
}
public void cancel(){
canceled = true;
}
}
Remember that every time you have to update your ui, call a runOnUiThread, or else you will have an exception, you are not in a handler and not on ui thread.
Here is how to use it in your code, it is identical to CountDownTimer, so you could just rename lines in your code :
CountDown cDown = new CountDown(10000, 20) {
public void onTick() {
// Do something
}
public void onFinish() {
runOnUiThread(new Runnable() {
#Override
public void run() {
myButton.setImageDrawable(drawable);
}
});
}
};

Categories

Resources