I am making a chess clock but in it I need a delay (Like it waits 10 seconds before counting). I used a Handler for it but if the button is clicked in the 10 seconds, nothing happens. Please help! Thanks!
My code:
mHandler.postDelayed(new Runnable() {
public void run() {
// count down timer start
timer2 = new CountDownTimer(totalSeconds, Integer.parseInt(delay.getText().toString())) {
public void onTick(long millisUntilFinished) {
secondsTimer = (int) (millisUntilFinished / 1000) % 60;
minutesTimer = (int) ((millisUntilFinished / (1000 * 60)) % 60);
hoursTimer = (int) ((millisUntilFinished / (1000 * 60 * 60)) % 24);
person2.setText(hoursTimer + ":" + minutesTimer + ":" + secondsTimer);
}
public void onFinish() {
person2.setText("Time Up!");
person2.setBackgroundColor(Color.RED);
mp.start();
}
}.start();
}
}, finalDelay);
I want a delay but I don't want to lock the UI and make the app unresponsive as it is doing right now with the handler. Any help will be appreciated! Thanks in advance!
I think you shouldn't put CountdownTimer into Handler. You could create 2 handler instead. Here is an example.
private void startHandlerAndWait10Seconds(){
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
public void run() {
// Start Countdown timer after wait for 10 seconds
startCountDown();
}
}, 10000);
}
private void startCountDown {
final Handler handler2 = new Handler();
handler2.post(new Runnable() {
int seconds = 60;
public void run() {
seconds--;
mhello.setText("" + seconds);
if (seconds < 0) {
// DO SOMETHING WHEN TIMES UP
stopTimer = true;
}
if(stopTimer == false) {
handler2.postDelayed(this, 1000);
}
}
});
}
If you want to start the timer immediately,
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().post(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
});
}
});
And if you want to execute it after a certain time period, then
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().postDelayed(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
}, 1000);
}
});
You can avoid using Handler starting timer immediately
private fun start10SecondsDelayTimer() {
var delayCount = 10
val timer = object : CountDownTimer(1_000_000L, 1000L) {
override fun onTick(millisUntilFinished: Long) {
if (delayCount > 0) {
delayCount--
} else {
//your calculations
}
}
override fun onFinish() {
//some calculations
}
}
timer.start()
}
but first ticks will be without your calculations
Related
I have a count down timer that must run for 30 seconds with a tick interval of 3 seconds.
But it seems the first tick happens as soon as the timer starts. I want the first tick to happen after 3 seconds.
And the next tick every 3 seconds. How can I do this?
Here is my code -
if (!timerRunning && timer == null) {
timer = new CountDownTimer(300000, 3000) {
#Override
public void onTick(long l) {
timerRunning = true;
Log.e(TAG,"Tick every 3 seconds");
}
#Override
public void onFinish() {
timerRunning = false;
}
}.start();
}
One possible solution is using a handler like below:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 3000ms
}
}, 3000);
So this code can help you:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!timerRunning && timer == null) {
timer = new CountDownTimer(300000, 3000) {
#Override
public void onTick(long l) {
timerRunning = true;
Log.e(TAG,"Tick every 3 seconds");
}
#Override
public void onFinish() {
timerRunning = false;
}
}.start();
}
}
}, 3000);
So I have 3 timers. For the first one I want only to appear once, because it's something like get ready timer.
For the second and third I want to appear as many times as user wants. Before timers start user must select number of times by pressing on + or - buttons which then set value of a TextView.
That's done with this code:
int counter = 0;
homeScreenPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dodajInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
homeScreenMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
oduzmiInterval();
homeScreenMinus.setEnabled(counter > 0);
}
});
}
private void oduzmiInterval() {
counter--;
brojIntervala.setText(Integer.toString(counter));
}
private void dodajInterval() {
counter++;
brojIntervala.setText(Integer.toString(counter));
}
And here's the code for timers:
public void homeScreenStart(View view) {
linearniLayoutSetup.setVisibility(View.GONE);
CountDownTimer firstCountDown = new CountDownTimer(seekBarTimerDelay.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_trci));
}
}.start();
}
public void countDownTimerTrci() {
for (int i = 0; i < counter; i++) {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
}
}.start();
}
}.start();
}
}
As you can see, it's a method which is called when button is pressed and I wan't first timer to appear only once and that's why I didn't include it in foor loop.
First timer shows only once and that works, but other two timers keep repeating until I close the app.
Can someone tell me where the problem is?
Try this ,replace your countDownTimerTrci method with mine
public void countDownTimerTrci() {
if(counter>0) {
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_trci));
CountDownTimer secondCountDown = new CountDownTimer(seekBarIntervaliVisokogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
textViewTimerVrijeme.setText("00:00");
karticaTimera.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
imageViewTimerSlika.setImageResource(R.drawable.ic_timer_niski_intenzitet);
textViewTimerTrciHodajBlaBla.setText(getResources().getString(R.string.timer_hodaj));
toolbar.setBackgroundColor(getResources().getColor(R.color.kartica_hodaj));
CountDownTimer thirdCountDown = new CountDownTimer(seekBarIntervaliNiskogIntenziteta.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
counter--;
textViewTimerVrijeme.setText("00:00");
countDownTimerTrci();
}
}.start();
}
}.start();
}
}
i have a textview that has a int number of seconds to count down from all the way to 0. i pass in a random number selected by a user to the timer and it counts down to 0. so i pass the variable S into timer
my textview:
mSeconds = (TextView)findViewById(R.id.secondsLabel);
my timer:
int s = //int taken from on spinner in another class
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
finish();
}
}, s * 1000);
new CountDownTimer(s, 1000) {
public void onTick(long millisUntilFinished) {
mSeconds.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
finish();
}
};
my textview does not display anything at all? how can i get it to show the seconds counting down?
You are not starting the CountDownTimer.
Do this
new CountDownTimer(s, 1000) {
public void onTick(long millisUntilFinished) {
mSeconds.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
finish();
}
}.start();
Start your count down timer
CountDownTimer ct = new CountDownTimer(s, 1000) {
public void onTick(long millisUntilFinished) {
mSeconds.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
finish();
}
};
ct.start();
You should manage it on UI thread
I am new to Android Development and trying to make little Game.
CountDownTimer.cancel() is not working for me.
Any Idea?
Thank Your for your Answer!
CountDownTimer cdt = new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
maxTime = (int) (millisUntilFinished / 1000);
timer.setText(String.valueOf(maxTime));
}
public void onFinish() {
}
};
if (startTimer == true) {
cdt.start();
} else {
cdt.cancel();
}
I have to do an assumption right here because the code doesn't show much! apparently you are using the countDownTimer inside your onCreate as an inner class so that will trigger the timer when startTimer == true and it would create the object no matter what! I guess it would be better to create a global instance of CountDownTimer.
And write your code in this way:
if(startTimer == true) {
cdt = new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
maxTime = (int) (millisUntilFinished / 1000);
timer.setText(String.valueOf(maxTime));
}
public void onFinish() {
}
}.start(); //start the countdowntimer
}
else{
cdt.cancel();
}
Boolean Myboolean = true;
CountDownTimer MyCountDownTimer = new CountDownTimer(10000, 1000)
{
#Override
public void onFinish()
{
}
#Override
public void onTick(long millisUntilFinished)
{
Log.i("onTick" , String.valueOf((millisUntilFinished / 1000) % 60));
if(!Myboolean ) { cancel(); }
}
}.start();
i had this issue , the CountDownTimer will not cancle with (MyCountDownTimer.cancel();) , the best way is to use Boolean , set the Boolean to false to cancel the CountDownTimer. in any place you want (Myboolean =false;)
I am trying to start a timer when activity created and be able to reset the timer back from zero if the same button is pressed but every time I press the button that initiates the set Interval it seems to be creating a new interval and not resetting the one that was already creating. Can someone help please? Here is my code
timer = (TextView) findViewById(R.id.timer_value);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 10000;
}
AlertDialog.Builder builder = new AlertDialog.Builder(
TicTacToe.this);
builder.setMessage("You are Out of Time").setPositiveButton(
"Replay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// reset the game environment.
Count.onFinish();
// Count.cancel();
Count.start();
new_game(player_name_1);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}.start();
you can use timers
//in global
Timer myTimer
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null); //it resets all timer which handler holds
myTimer.cancel();
}
public void setTimer(int time){//give it 5 for 5 secs
final Runnable Update = new Runnable() {
public void run() {
//do sth
}
};
myTimer = new Timer();
myTimerTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
If you want to restart your timer, remove Count.onFinish();
Update:
I replaced AlertDialog with a new thread and here is the code that works on my emulator
public class MainActivity extends Activity
{
int time = 10000;
CountDownTimer Count;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView timer = (TextView) findViewById(R.id.timer);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 100000;
}
}
}.start();
}
public void buttonClicked(View view)
{
Log.i("Timer", "Resetting timer");
Count.cancel();
Count.start();
}
}