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);
Related
I have a situation where I need to update the notification progress bar after some few more milliseconds. If I use notification manager to update the progress, then the notification will show up even after calling stopForground(true) which is not what I need.
Here is the sample code using the notification manager to update.
private void doStuff() {
// starting in foreground
startForeground(123, notification.build());
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
timer++;
if(timer > 10){
stopForeground(true);
stopSelf();
return;
}
if(!bound){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
notificationManager.notify(123, notification.setProgress(10, timer, false).build());
}
}, 2000);
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
});
thread.start();
}
otherwise, if I use startForground() way, the notification won't show up after the 2000 milliseconds and I get the desired behavior as shown below:
private void doStuff() {
// starting in foreground
startForeground(123, notification.build());
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
timer++;
if(timer > 10){
stopForeground(true);
stopSelf();
return;
}
if(!bound){
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startForeground(123, notification.setProgress(10, timer, false).build());
}
}, 2000);
}
handler.postDelayed(this, 1000);
}
}, 1000);
}
});
thread.start();
}
My question is if there would be something wrong I'm not aware of using this way because I have never seen anyone doing it. Please help! Thanks!
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)));
}
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);
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
I am using a hanfler within the service to call a method after a delay in android. Its not working for long delays but the same code works for small delay.
Handler mHandler;
Runnable runnable;
mHandler = new Handler();
runnable=new Runnable() {
#Override
public void run() {
Log.i("START SERVICE", "START SERVICE:3 Call to Check Status is called");
callToCheckStatus();
mHandler.postDelayed(this, 1000*60*60);
}
};
mHandler.postDelayed(runnable, 1000*60*60);
On some blogs i find that when device goes deep sleep then it does not work. SO whats the right way to call a method within in Android.
Try This
public static void intertiAdsStartTimer(Context cnxt) {
timer = new Timer();
initializeTimerTask(cnxt);
//timer.schedule(timerTask, delayTime, repeatedTime);
timer.schedule(timerTask, 0, Integer.parseInt("7") * 60 * 1000); //
}
public static void initializeTimerTask(final Context cnxt) {
try {
final Handler handler = new Handler(Looper.getMainLooper());
timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
try {
//call your method
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
} catch (Exception e) {
e.printStackTrace();
}
}
OR
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do something after 10s = 10000ms
}
}, 10000);