I have an activity that vibrates the phone for 9 seconds after it starts. I want the vibration action to be canceled when the activity leaves the foreground. Here is my current code:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// change image
screen.setImageResource(R.drawable.yama);
vibrateMe();
}
}, 9000);
}
public void vibrateMe() {
Vibrator vibrate = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrate.vibrate(2000);
}
public void stopVibrating(Vibrator vibrate) {
vibrate.cancel();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
You want to cancel your runnable?
There are 2 options:
you can cancel all your delayed runnables with handler.removeCallbacksAndMessages(null)
you should save ref to runnable (Runnable vibrateRunnable = new Runnable() ... ) and then remove it if needed with handler.removeCallbacks(vibrateRunnable)
You can cancel all CallBacks and Messages using removeCallbacksAndMessages();
public final void removeCallbacksAndMessages (Object token)
Added in API level 1
Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed.
Related
I have been using handler inside service class, the handler is responsible for sending location every 5 seconds via socket. When logging out, the service gets stopped but the handler still running.
I tried every possible way, By using any boolean variable is not feasible in my case because i have to start again that handler.
public Runnable mn_Runnable12 = new Runnable() {
public void run() {
gps = new GPSTracker(LocationService.this);
if (gps.canGetLocation()) {
latString = Double.toString(gps.getLatitude()); // Live
logString = Double.toString(gps.getLongitude());
connection= MyApplication.getInstance().getConnection();
if (connection!=null&&connection.isConnected()) {
sendLocation();
}
}
}
};
this is inside onCreate() of service.
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler12.postDelayed(mn_Runnable12, 5000);
}
},
5000,
5000);
I try to stop the handler in onDestroy method of service, service gets topped but the handler still running.
#Override
public void onDestroy() {
System.out.println("Location Service Detaroy-----");
if (connection.isConnected()) {
unSubscribe();
}
mHandler12.removeCallbacksAndMessages(null);
mHandler10.removeCallbacksAndMessages(null);
}
You Also have to cancel Timer Since its running repeatedly with an interval.
First cancel timer and then remove handlers callback.
T.cancel();
T.purge();
// remove handler here
I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
I want every 1 second registerReceiver.
I try
registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIME_TICK));
but this code every 1 minute
I want every 1 second.
Perhaps, android have a form ?
thanks
What are you trying to accomplish? If you just want to have some code executed every 1s, don't user a BroadcastReceiver. Receivers result in inter-process communication every time they are triggered which is (relatively) expensive.
Best way would be to use a handler,
private static final long TICK_INTERVAL = TimeUnit.SECONDS.toMillis(1);
private static final Handler tickHandler = new Handler(Looper.getMainLooper());
public void onResume() {
super.onResume();
tick(TICK_INTERVAL);
}
private void tick(final long interval) {
tickHandler.postDelayed(
new Runnable() {
public void run() {
tick(interval);
onTick();
}
},
);
}
protected void onTick() {
// do something
}
Ensure you stop the ticking when your activity pauses,
public void onPause() {
super.onPause();
tickHandler.removeCallbacksAndMessages(null);
}
I have a situation in an Android app where I want to start a network activity (sending out some data) which should run every second. I achieve this as follows:
In the onCreate() I have the code:
tv = new TextView(this);
tv.postDelayed(sendData, 1000);
The sendData() function:
Handler handler = new Handler();
private Runnable sendData=new Runnable(){
public void run(){
try {
//prepare and send the data here..
handler.removeCallbacks(sendData);
handler.postDelayed(sendData, 1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
The problem come in like this: When user presses the back buttons and app comes out (UI disappears) the sendData() function still gets executed which is what I want. Now when user re-starts the app, my onCreate() gets called again and I get sendData() invoked twice a second. It goes on like that. Every time user comes out and starts again, one more sendData() per second happens.
What am I doing wrong? Is it my new Handler() creating problem? What is the best way to handle this? I want one sendData() call per second until user quits the app (form application manager).
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 100ms
Toast.makeText(c, "check", Toast.LENGTH_SHORT).show();
handler.postDelayed(this, 2000);
}
}, 1500);
Perhaps involve the activity's life-cycle methods to achieve this:
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler.post(sendData);
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendData);
}
private final Runnable sendData = new Runnable(){
public void run(){
try {
//prepare and send the data here..
handler.postDelayed(this, 1000);
}
catch (Exception e) {
e.printStackTrace();
}
}
};
In this approach, if you press back-key on your activity or call finish();, it will also stop the postDelayed callings.
Why don't you create service and put logic in onCreate(). In this case even if you press back button service will keep on executing. and once you enter into application it will not call
onCreate() again. Rather it will call onStart()
You can simplify the code like this.
In Java:
new Handler().postDelayed (() -> {
//your code here
}, 1000);
In Kotlin:
Handler().postDelayed({
//your code here
}, 1000)
Please check the below its working on my side in below code your handler will run after every 1 Second when you are on same activity
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
runnable = new Runnable()
{
#Override
public void run()
{
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
Handler h = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==0){
// do stuff
h.removeMessages(0); // clear the handler for those messages with what = 0
h.sendEmptyMessageDelayed(0, 2000);
}
}
};
h.sendEmptyMessage(0);
I think you could experiment with different activity flags, as it sounds like multiple instances.
"singleTop"
"singleTask"
"singleInstance"
Are the ones I would try, they can be defined inside the manifest.
http://developer.android.com/guide/topics/manifest/activity-element.html
You should set andrid:allowRetainTaskState="true" to Launch Activity in Manifest.xml. If this Activty is not Launch Activity. you should set android:launchMode="singleTask" at this activity
I am using handler.postDelayed() to create a waiting period before the next stage of my app takes place. During the wait period I am displaying a dialog with progress bar and cancel button.
My problem is I can't find a way to cancel the postDelayed task before the time elapses.
I do this to post a delayed runnable:
myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH);
And this to remove it: myHandler.removeCallbacks(myRunnable);
In case you do have multiple inner/anonymous runnables passed to same handler, and you want to cancel all at same event use
handler.removeCallbacksAndMessages(null);
As per documentation,
Remove any pending posts of callbacks and sent messages whose obj is
token. If token is null, all callbacks and messages will be removed.
Another way is to handle the Runnable itself:
Runnable r = new Runnable {
public void run() {
if (booleanCancelMember != false) {
//do what you need
}
}
}
Here is a class providing a cancel method for a delayed action
public class DelayedAction {
private Handler _handler;
private Runnable _runnable;
/**
* Constructor
* #param runnable The runnable
* #param delay The delay (in milli sec) to wait before running the runnable
*/
public DelayedAction(Runnable runnable, long delay) {
_handler = new Handler(Looper.getMainLooper());
_runnable = runnable;
_handler.postDelayed(_runnable, delay);
}
/**
* Cancel a runnable
*/
public void cancel() {
if ( _handler == null || _runnable == null ) {
return;
}
_handler.removeCallbacks(_runnable);
}}
It worked for me when I called CancelCallBacks(this) inside the post delayed runnable by handing it via a boolean
Runnable runnable = new Runnable(){
#Override
public void run() {
Log.e("HANDLER", "run: Outside Runnable");
if (IsRecording) {
Log.e("HANDLER", "run: Runnable");
handler.postDelayed(this, 2000);
}else{
handler.removeCallbacks(this);
}
}
};