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);
Related
I have created a handler for an alert that should activate for 4 seconds, stops for 4 seconds, and activates again. When i put it in the if statement, it doesn't work; the alert keeps playing, stops for less than a second and continues activating again without the delay. Wonder if anyone knows why is it happening and what should i do to correct it. Thank you.
private Handler handler2 = new Handler();
private Runnable startalert = new Runnable() {
#Override
public void run() {
alert2.start();
handler2.postDelayed(this, 4000);
}
};
#Override
public void onLocationChanged(Location location) {
if (location == null) {
speedo.setText("-.- km/h");
}
else {
currentSpeed = location.getSpeed() * 1.85f; //Knots to kmh conversion.
speedo.setText(Math.round(currentSpeed) + " km/h");
}
if (currentSpeed <=4.99) {
background.setBackgroundColor(Color.GREEN);
handler2.removeCallbacks(startalert);
} else if(currentSpeed >=5.00 && currentSpeed <=9.99) {
background.setBackgroundColor(Color.YELLOW);
handler2.removeCallbacks(startalert);
} else if(currentSpeed >=10.00) {
background.setBackgroundColor(Color.RED);
startalert.run();
}
}
Instead of 'this', use runnable object.
private Runnable startalert = new Runnable() {
#Override
public void run() {
alert2.start();
handler2.postDelayed(startalert, 4000);
}
};
Another method:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
alert2.start();
handler.postDelayed(this, 4000);
}
}, 4000);
I have a situation, I created a button and a function like this.
...
public void BtnOnClick(View view) {
displayMsg();
}
...
private void displayMsg(){
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, 3000);
}
...
If I click the button once a Toast should appear after a 3 seconds delay.
But if I quickly click the button two or more times then all the Toasts appear at the same time after 3 seconds without delay of 3 seconds between every Toast it's not good. I want a 3 seconds gap/delay between every Toast appearance despite of simultaneous clicks.
Is there any solution?
If there are multiple handlers in a queue then each handler delayed time start after the previous handler delay time end.
You can queue the requests to make sure the toasts are displayed at an interval.
ArrayList<Runnable> requests = new ArrayList<>;
bool inProgress = false;
private void displayMsg(){
Runnable runnable = new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
inProgress = false;
if (requests.size() > 0) {
handler.postDelayed(requests.remove(0), 3000 + Toast.LENGTH_SHORT);
}
}
}
if (!inProgress) {
inProgress = true;
handler.postDelayed(runnable, 3000);
} else {
requests.add(runnable);
}
}
Try this:
private final Handler handler = new Handler() {
final int DELAY = 3000;
final int DELAY_MSG = 1;
final Queue<Runnable> pendingRunnables = new ArrayDeque<>();
#Override
public void dispatchMessage(Message msg) {
if (msg.what == DELAY_MSG) {
final Runnable r = pendingRunnables.poll();
if (r != null) {
r.run();
sendEmptyMessageDelayed(DELAY_MSG, DELAY);
}
} else {
pendingRunnables.add(msg.getCallback());
if (!hasMessages(DELAY_MSG)) {
sendEmptyMessage(DELAY_MSG);
}
}
}
};
...
// post action
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
});
Maybe you can use postAtTime:
AtomicLong previous = new AtomicLong(System.currentTimeMillis());
private void displayMsg(){
handler.postAtTime(new Runnable() {
#Override
public void run() {
Toast.makeText(this, "TestQueue", Toast.LENGTH_SHORT).show();
}
}, previous.updateAndGet(operand -> Long.max(operand + 3000, System.currentTimeMillis() + 3000)));
}
onLongClick or onLongLouch a TextView , I need to increase its value by 1 every 60 seconds, like this:
<TextView
android:layout_width="match_parent"
android:text="00 min"
android:id="#+id/timer"
android:layout_height="120dp"
/>
Create a Timer that runs each time in miliseconds.
final Handler handlerIncrementar = new Handler();
Timer timerTexto = new Timer();
TimerTask tareaEjecucion = new TimerTask() {
#Override
public void run() {
handlerIncrementar.post(new Runnable() {
public void run() {
try {
yourtextview.setTextSize(yourtextview.getTextSize() + 1);
} catch (Exception e) {
}
}
});
}
};
timerTexto.schedule(tareaEjecucion, 0, 60000);
Below Code will increase the counter by one every one secound till you hold the touch on text view and stops when you relese the touch
private TimerTask timerTask;
private TextView textView;
private int counter = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
textView.setOnTouchListener(this);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
int code = event.getAction() & MotionEvent.ACTION_MASK;
if (code == MotionEvent.ACTION_DOWN) {
startTimer();
} else if ((code == MotionEvent.ACTION_POINTER_UP) || (code == MotionEvent.ACTION_UP) || (code == MotionEvent.ACTION_CANCEL)) {
stoptimertask();
}
return true;
}
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
Timer timer = new Timer();
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 0, 1000); //
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(counter++ + " Sec");
}
});
}
};
}
I hope this will help you.
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
I have two Buttons in main View, Button1 and Button2. How can I disable Button1 for specific time period after that time period it should Enable again.
Use a countdown Timer.
Say you have button button1 ;
button1.setEnabled(false);
new CountDownTimer(5000, 10) { //Set Timer for 5 seconds
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
button1.setEnabled(true);
}
}.start()
Aba: Applied correct View.setEnabled method.
Here is an example:
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run(){
button.setEnabled(false);
}
}, 5000);
Rest, figure out yourself.
You can call this method. Try this once
private void blink(){
final Handler handler = new Handler();
new Thread(new Runnable() {
#Override
public void run() {
int timeToBlink = 5000;
try{
Thread.sleep(timeToBlink);
}catch (Exception e) {
}
handler.post(new Runnable() {
#Override
public void run() {
if(button.isEnabled()){
button.setEnabled(false);
}else{
button.setEnabled(true);
}
blink();
}
});
}
}).start();
}
By calling this method You will get the effect you wanted
private fun initButton() {
button.setOnClickListener {
it.isEnabled = false
it.postDelayed({ it.isEnabled = true }, 3000)
//do stuff
}
}
This works in Kt, does require a handler tho
In the simplest way
yourView.setEnabled(false);
yourView.postDelayed(() -> yourView.setEnabled(true), 5000); // Wait for 5 seconds