I get the current location in my app using requestLocationUpdates but in case it takes too long to detect I use a timer to cancel the operation.
For your information I tell you I do all this process in a WakefulBroadcastReceiver so the device should NOT sleep until either a position is received or the time out happens. Once one of those happens I call to completeWakefulIntent to let the device sleep again.
Everything works great but sometimes the timer never finishes and no location is got, either. I guess my process is maybe killed or destroyed by the system.
So, is there a way to ensure the timer to execute after an amount of time?
Any help would be appreciated
Check AlarmManager.
Schedule a non repeating alarm once the location finding activity is fired.
This alarm in turn fires your killer activity that cancels the location finding activity, after an appropriate amount of time
Or use Handler. Something like:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// do something
// this executes after 2000 milliseconds
}
}, 2000);
When it runs on the main thread you should never perform long-running operations in it (there is a timeout of 10 seconds that the system allows before considering the receiver to be blocked and a candidate to be killed).
Also if this BroadcastReceiver was launched through a <receiver> tag, then the object is no longer alive after returning from onReceive(). This means you should not perform any operations that return a result to you asynchronously.
Please see the documentation for BroadcastReceiver
Cheers!
Use Timer.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
//This will execute afteer every 1 Minute
}
}, 0, 60000);
Related
My Requirement is
Android application has to send user location details(latitude & longitude) to the server for every one hour(which is configurable).
The approach I followed is using the alarm manager i am invoking my service at configured intervals which will send the location details to server irrespective of whether the application is running.
Is this a good approach?
I prefer ScheduledExecutorService, because it is easier for background Tasks.
AlarmManager:
The Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the Alarm Manager releases this wake lock.
ScheduledThreadPoolExecutor:
You can use java.util.Timer or ScheduledThreadPoolExecutor (preferred) to schedule an action to occur at regular intervals on a background thread.
You can see complete answer here => Which is Better ScheduledExecutorService or AlarmManager in android? And Here
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// Hit WebService
}
}, 0, 1, TimeUnit.HOURS);
Yes, using AlarmManager is a good approach
The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
please refer this https://developer.android.com/training/scheduling/alarms.html
Android service run on UI thread so you should not execute long running task in it, like sending data to server. The approach you can use is ScheduledThreadPoolExecutor or AlarmManager for scheduling and using asynctask or any other background thread for sending data to servers
I prefer Timer for repeated tasks.
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
process();
}
};
Timer mTimer = new Timer();
mTimer.schedule(timerTask, 0,60*60*60*1000);
I am working on an application which requires it to go online every x minutes and check for some new data. To prevent heavy network and data usage the task should run at fixed rate, but what is the best approach to use for this kind of solution ? A Handler or a Timer object?
There are some disadvantages of using Timer
It creates only single thread to execute the tasks and if a task
takes too long to run, other tasks suffer.
It does not handle exceptions thrown by tasks and thread just terminates, which affects
other scheduled tasks and they are never run.
Whereas on Other hand, ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case
scheduleAtFixedRate(...)
scheduleWithFixedDelay(..)
class LongRunningTask implements Runnable {
#Override
public void run() {
System.out.println("Hello world");
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new LongRunningTask (), 0, duration, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
And to Cancel the Executor use this - ScheduledFuture
// schedule long running task in 2 minutes:
ScheduledFuture scheduleFuture = exec.scheduleAtFixedRate(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
... ...
// At some point in the future, if you want to cancel scheduled task:
scheduleFuture.cancel(true);
You should use a Service and an AlarmReceiver
Like This
That's what they're for. If you use a Timer or any other mechanism in your Activity and you set your data to update every "few minutes" there's a good chance the user will not be in your app and Android may very well clean it up, leaving your app *not updating. The Alarm will stay on till the device is turned off.
if you are looking for a good performance and less battery consume, you should consider an Alarm manager integrated with broadcast Reciever that will call a service in X time and let it do the work then turn it off again.
However, using timer or handler you need to let your service run in background at all times. unless, you want it to get data while the application is running therefore you dont need a service.
if your choice is whether handler or timer, then go with timer because it is more simpler and can do the job in better performance. handlers usually used to update the UI using Runnable or Messeges.
Maybe Alarm Manager, timer, handler or ScheduledThreadPoolExecutor.
Take a look at this:
Scheduling recurring task in Android
It depends on whether updates will occur while the user is not in the app (will the checks halt as soon as the user leaves to send an SMS, for example, or should polling continue?) can the check run on the UI thread then spawn the loading from a service or AsyncTask or other thread? Maybe none of that matters...
If you don't need to update anything while the user is not viewing the app, go with timer. Service would be an overkill. Here is a sample code to achieve this:
final Runnable updateRunnable = new Runnable() {
public void run() {
// Fetch the date here in an async task
}
};
final Handler myHandler = new Handler();
private Timer myTimer;
private void updateUI() {
myHandler.post(updateRunnable);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other things here
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
updateUI(); // Here you can update the UI as well
}
}, 0, 10000); // 10000 is in miliseconds, this executes every 10 seconds
// ... more other things here
}
Alarm manager or handler. If you use handler and postDelayed, your process doesn't have to stay active all the time.
In fact using Handler is officially recommended over Timer or TimerTask: http://android-developers.blogspot.ru/2007/11/stitch-in-time.html
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 have regular service that I start using alarms every 5 minutes.
Service Implements LocationListener to get GPS fix and save it into SqLite database.
I give service 1 minute to get best fix possible. If I get accuracy <20 before that - even better.
All that works fine. I also have code that checks if GPS disabled so I exit service.
What I want to do is: If there is no fix within 1 minute - I want to exit service. Currently since most logic (time checks, etc) is in onLocationChanged - I never have chance to do so because I never get location.
Is there timer or something like that I can use? I'm new to Java, example would be nice. I see it like this: On start I create timer with callback and in this callback function I will cleanup and shutdown. I'm not sure if there going to be any implications with possible onLocationChanged running?
Can I possibly disable timer as soon as I get onLocationChanged?
Use a android.os.Handler:
Handler timeoutHandler = new Handler();
timeoutHandler.postDelayed(new Runnable() {
public void run() {
stopSelf();
}
}, 60 * 1000);
You could schedule a timeout using Timer and TimerTask as follows...
Declare a global Timer object reference in your Service:
Timer timeout = null;
In onStartCommand(), instantiate this Timer and schedule a TimerTask to execute in one minute. Do this after you've registered for location updates from the desired provider:
timeout = new Timer();
timeout.schedule(timeoutTask, 60000);
Define timeoutTask somewhere in your Service class e.g:
private TimerTask timeoutTask = new TimerTask() {
public void run() {
// Handle timeouts here
}
}
If you get a callback via onLocationChanged() before the Timer expires, you'll want to stop timeoutTask from being executed, so inside onLocationChanged():
if(timeout != null) {
timeout.cancel()
}
Then just handle your location inside onLocationChanged() as normal, or call another method to do it, up to you.
There are probably better ways to do it, but this is straightforward and has worked for me on my project :) Hope it helps you too.
All the best,
Declan