I have to do a particolar function one time Every 2 seconds, and I have to stop it when a certain broadcast message arrive then I have to restart it when other message arrives. I use handler postdelayed(runnable,time) and inside the runnable function i have called postdelayed(this,2000). But i can't stop it.. And when I restart the runnable I have different runnable started at the same time.
I call handler.removecallback
You can use the AlarmManager for scheduling repeat events, you can cancel the alarm using the cancel() method.
E.g. alarmManager.cancel(pendingIntent);
Related
In one of my android applications, I need to run a task for every minute. It should run even if the app closes and when device is in Idle state also.
I have tried handler, it is working fine when device is active, but not working when device is in idle state.
I have tried workmanager(one time and repeated ) as well. Document says this works even when the device is in Idle mode, but this is stops working after 3/4 repeats.Workmanager is inconsitent, its working sometimes and not working most of the cases till i reboot device.
Can anyone suggest better way to handle the situation?
Thanks
bhuvana
Work manager can only work within 15 minutes of interval, if you do not define a longer time. To run something every minute, you need a Foreground Service with a sticky notification in it. There is no other way to run something every minute.
To start a foreground service, create a service as usual, and in its onStartCommand, call startForeground and from the method, return START_STICKY. These should achieve what you need.
Edit: Sample code for handler thread (this is Java btw, should be similar on Xamarin):
private HandlerThread handlerThread;
private Handler backgroundHandler;
#Override
public int onStartCommand (params){
// Start the foreground service immediately.
startForeground((int) System.currentTimeMillis(), getNotification());
handlerThread = new HandlerThread("MyLocationThread");
handlerThread.setDaemon(true);
handlerThread.start();
handler = new Handler(handlerThread.getLooper())
// Every other call is up to you. You can update the location,
// do whatever you want after this part.
// Sample code (which should call handler.postDelayed()
// in the function as well to create the repetitive task.)
handler.postDelayed(() => myFuncToUpdateLocation(), 60000);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
handlerThread.quit();
}
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to fetch the Current Location in Every 1 min of Interval?
iam creted on working location class and another sendsms class
now I need to create background service with the help of timer to send sms current location after every 5 min
Why can't you do some research on your problem. Its very simple to get solution for such an easy question.
And don't ask same question multiple times
How to get location after every 5 minutes?.
Anyway still if you are unable to find it out, I could help my level best
Just you have following ways to do this,
Through Background running Service.
Create a Service that registers Location Listener.
Create an alarm , when Service get called and set your alarm time frequency.
Create a Broadcast Receiver for receive your alarm intent.
After fetching location unregister your Location Listener.
When you feel , no need to fetch location then stop the Service.
Sample codes will be very lengthy, So You can get easily examples for following in web,
Creating a Service
Create an alramIntent and register for BroadCast Receiver
Create a BroadCast Receiver and register it with an alarm Action.
Implementing Location Listener.
Through Timer with Runnable Thread,
Create a Timer.
Schedule the Timer with TimerTask run method. You can schedule initial start time duration and periodic interval call time delay too.
Invoke Runnable interface when scheduled time occurs.
Make sure the Runnable Interface runs on UI Thread by this.runOnUIThread(your_runnable_interface)
In Runnable run() method, register your LocationListener for updates
And do unregister in onLocationChanged() after processed your new location.
When you feel , no need to receive location then cancel the Timer.
Here is an example for Timer using,
//Declared Globally in class
Timer timer;
//Timer follows here
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
callRunnableMethod();
}
},Set your initial start time, Set your time delay for interval);
//callRunnableMethod() goes here
private void callRunnableMethod()
{
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
context or this .runOnUiThread(Location_Runnable);
}
//Location_Runnable goes here
private Runnable Location_Runnable = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
Just start calling or request for updates with your location listener here.
}
};
//Once you decided to stop the periodic location fetching then do cancel your timer,
timer.cancel();
Use the LocationListener and request position updates as detailed here to get location updates. I think you need a context to do that but I hope this tutorial on location updates will help.
http://www.vogella.com/articles/AndroidLocationAPI/article.html
I had a thread which executes a function in every 30 minutes, so I used a combination of handler and runnable thread ( like postdelayed,removemessages ).At that time I couldn’t find any way to stop thread.I tried hander. Removemessages() and hander.removeCallbacks(Runnable) but couldn’t help..
I will suggest you to use TimerTask instead of Thread. Here you can cancel & restart the TimerTask.
I suggest you to use alarmmanager. There is a problem with timertask.
Sometimes the service where the timertask is initiated might be destroyed. If the service is not running timertask will also become disable. It happen frequently when the device is in idle state. So the best solution is to use alarmmanager which trigger an alarm in every 30 minutes whether your device is in idle state or not. You only need to initiate the alarm when you first start the application and need to re-initiate when the device is rebooted. You can use a broadcast receiver to get message when your device is rebooted.
To stop a thread in java, you need to call thread.interrupt(); method.
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if(your condition to stop thread)
{
timer.cancel();
}else
{
\\ your code
}
}
}, 0, 1800000);
use timer inside....it will solve your problem
I want to stop my Service after a user defined time (choosen in a activity).
Now I want to start the timer in the service, but I cant use static timer because I have to stop the service (stopService(), stopSelf() are non-static methods.
Is there a simple way to do it?
(Now I used a handler with a runnable which checks if a variable is set to true and then starts the timer)
Use AlarmManager. Call set() on an AlarmManager, supplying the time when you want your service to stop and a getService() PendingIntent that will send a command to your service. In onStartCommand(), when you receive the Intent command from the PendingIntent, call stopSelf().
I'm trying to create a service that runs in a given interval. The service's purpose is to update a database and when done notify an Activity with an Intent.
The service should also be callable from the activity when the user chooses to 'refresh'.
I have accomplished this, but I can't get it to run in a detached thread.
The service executes an update method in a Runnable:
private Runnable refresh = new Runnable() {
public void run() {
update(); //Runs updates
didUpdate(); //Sends broadcast
handler.postDelayed(this, 50000); // 50 seconds, calls itself in 50 secs
}
};
I have another runnable called ManualRefresh that is called via a broadcast from the activity.
However these runnables seem to be blocking the UI.
Need advice! :)
When you run a Runnable by calling it's run method, it runs on the current thread. To run on a background thread, you need to use new Thread(refresh).start(); (if the Runnable you want run is refresh).
You can also make use of AsyncTask for this, but that's more appropriate for an activity than for a Service. Information about using AsyncTask can be found in the API docs and in the article Painless Threading.
I suggest to write the service using the AlarmManager. The service will receive an Intent to tell it to periodically to update the database.
Once updated, you can notify the Activity with an Intent (as you mentioned).
When the user wants to manually refresh, have the Application sent an Intent to you service. Receiving the Intent from the AlarmManager or from the Activity would perform the same code.
You may also want to reschedule the alarm after a request to manually refresh.