Background:
My application should get its geographical location every X seconds, send the location to server. The server responds with new interval X' and from now on the application should get its geographical location every X' seconds and so on.
The application should run indefinitely.
Question:
AlarmManager can execute my application code at a specific time, even if my application is not currently running.
Can LocationManager do the same or I should keep my service running in background and "recreate" every time the OS kills it?
This article advocates the former approach but I'm not sure I can implement it with LocationManager.
you can define a BroadcastReceiver with an AlarmManager that uses AlarmManager.ELAPSED_REALTIME_WAKEUP
Check this answer: https://stackoverflow.com/a/7709140/779408
there is a solution there.
You need to create a service that implements "onlocationchanged" listener
Related
I'm developing an app that checks the weather based on the current location every 3 hours. I'm getting the location using the FusedLocationProviderApi and using a pendingIntent to a BroadCastReceiver that start up an IntentService.
In the FusedLocationProviderApi you can specify an interval period when you are creating the LocationRequest. So if I specify the interval to be 3 hours and the fastest interval as well to be 3 hours (I don't want to get updates before that), what happens if location is not available when it's time to do a location update?
Will I still get the location update intent at the scheduled time? I would like to use the last known location if the location is not available, but I need to be certain that I am still getting the PendingIntent at the scheduled time.
Or is it better to use an alarm manager to handle the periodic work and request the location update from within the IntentService instead?
Thanks
In the FusedLocationProviderApi you can specify an interval period when you are creating the LocationRequest. So if I specify the interval to be 3 hours and the fastest interval as well to be 3 hours (I don't want to get updates before that), what happens if location is not available when it's time to do a location update?
In this scnerio device must be awake to keep alive your location request. So it means you must have a non-stop(theoretically) background service, and partial wake lock as well. They sound not good.
Instead, you could refer AlarmManager approach which is set to wake up at each 3 hours. Then idea works like below
Device wakes up
Makes location request asap (set interval values to zero)
Continues to sleep after receiving location (and also doing your actual work)
I'm trying to make an optimized application that runs background 100% of the time.
It receives location updates and post them to a server.
I'd like to know if im doing things the way i should.
At this moment my app has a service that requestLocationUpdates using LocationServices API.
It accumulate locations and try to send them to the server.
This services is self terminated if no more locations are pending left.
Also i have an alarm to wake up this service every while.
So next time the service wake up, start a new session of GooglePlayServices and receive locations again.
I understand that using pendingIntents is better for unmanaged location tracking, but i still think that need the background service to upload locations in a timely manner.
- Should i stop using alarm raised services?
- Is there any way to start requesting location updates without user intervention / activity?
- Is a broadcastReceiver capable of managing heavy work like network posting?
Got this from google locationServices doc:
public abstract PendingResult<Status> requestLocationUpdates
(GoogleApiClient client, LocationRequest request, PendingIntent
callbackIntent)
Requests location updates with a callback on the specified
PendingIntent.
This method is suited for the background use cases, more specifically
for receiving location updates, even when the app has been killed by
the system. In order to do so, use a PendingIntent for a started
service. For foreground use cases, the LocationListener version of the
method is recommended, see requestLocationUpdates(GoogleApiClient,
LocationRequest, LocationListener).
Thanks in advance
Is there any way to start requesting location updates without user intervention / activity?
Yes, you can create nice scenarios setting up alarm with specified frequency. Even the app is not working, your alarm wakes up device, receives location and then sends to server. After it's work done, device sleeps again. Please check this project, here super scenario from commonsguy.
Is a broadcastReceiver capable of managing heavy work like network posting?
Yes, it does, You'll probably send location to server.
Should i stop using alarm raised services?
Depends on your tracking style.. Consider examples
Receiving location and sending to server at every 10 minutes (or more)
Receiving location and sending to server at every 5 seconds (like realtime tracking)
Probably, for the first example, you will set repeating alarm and then wake up device, receive and send location, and finally allow device's sleep (10 minutes). In this case, you must stop everything about tracking (location services, network operations)
But in the second example, you cant set alarm with lower frequency like 5 seconds. You should have not-stop background service (theoretically) and make location request with 5 seconds interval. In this case, you shouldn't stop resources like (awake device, location requests, network operations). And finally user uninstalls the app :-)
Bottom line, follow commonsguy's project
I'm working on an android app where I need to get location updates in the background for an extended period of time using the GPS provider, so I need the location udates to occur when the user is no longer interacting with it. I did some testing of my own comparing LocationManager's requestSingleUpdate (the provider, pendingIntent version) and requestLocationUpdates (the provider, minTime, minDistance, intent version). After taking a good bit of data on my Droid Razr HD, it looks like using requestLocationUpdates is significantly more reliable than requestSingleUpdate (for both methods I actually compared the GPS location reported to where I actually was, i.e. not using the reported accuracy, and requestLocationUpdates was not only significantly more accurate as to my actual location, but it returned a location fix time that was the same as the current time far more often then using the requestSingleUpdate option). I know how to use AlarmManager with a repeating alarm and call requestSingleUpdate so that I only need to hold a wakelock each time the the alarm goes off, but because of the increased accuracy of using requestLocationUpdates (at least in my tests on my phone) I would like to use that method instead. My problem is that if I use the requestLocationUpdates method, I am really unclear as to what I have to do in terms of holding a wakelock to keep the updates occuring when the user isn't interacting with the phone. I am calling requestLocationUpdates from a separate thread that is launched from a service (I read that that is the standard pattern). My question is, do I have to hold a wakelock for the entire time that I want location updates to keep coming? If I don't get my own wakelock do the location updates keep coming, waking the phone up for each new update? If this is true, do these updates create their own wakelock, and if so, when do they release the wakelock? I can't seem to find a clear answer on this. Any help is greatly appreciated.
No you don't need a wakelock because the OS takes the wakelock for you (code). The wakelock is released when onLocationChange() ends or when your broadcast receiver receives the intent (for the intent version of the interface). You need your own wakelock if you start some async work in onLocationChange() for example with an other thread.
I wrote a flight logging app which also needs update every few seconds to recognize take-oofs and landings. The received data is evaluated in a service. To keep the service alive you will need a WakeLock. I get the lock when the detector (automatically recognizing the relevant events) is started and I release the lock when the user turns the detector off; this is also the life time of the service, so the lock is aquired in onCreate and it is released in onDestroy. I use a SCREEN_DIM_WAKE_LOCK to save some power.
I want to keep listening for location update even when my app destroyed (or closed), do i have to run a service for this? and what is the best practice's for continuous location update other than the ones described here.
If your application is destroyed by the OS then it won't do anything. Activities and Services can both be killed by the OS if needed. Furthermore, unless you request a WAKE_LOCK you won't get updates if the phone enters sleep either.
Having said that, yes, you want to create a Service that implements locationListener and respond appropriately to onLocationChanged(). That way, the app will still receive the updates in the background.
Even better you can use this:
public void addProximityAlert (double latitude, double longitude, float radius, long expiration, PendingIntent intent)
The intent will be fired even if the app is not running via broadcast. Take the broadcast start a serviceintent to run your code. The service will die when it is done.
Yes using a service is the only safe way to continuously monitor location after your application is destroyed. It can be adventageous to persist your location info to an SQLite DB or flat file for reading the location information back out as binding to services can take some time.
I have an android application. Based on the current geo location of user, I want to fetch some remote data in background and store it. My implementation is:
At specific interval a alarm fires up my service. Service uses an anonymous class to query current location and registers a locationListener callback. On call of onLocationChanged() I initiate the remote data fetch from server.
However once my service is done registering the location listener using anonymos class, it returns as expected; as it doesn't wait for callback to happen before finishing. Since callback takes some time and makes a call when service has already returned, it throws an error saying:
java.lang.RuntimeException: Handler{43e82510} sending message to a Handler on a dead thread
Which is quite understandable. One quick workaround for me now is that I can use getLastKnownLocation from locationManager as that doesn't respond back by callback; but what if I do want the latest location right now, in a service and not activity? How can I wait for callback to happen and stop my service from returning.
Also, at what point does lastKnownlocation gets updated? Everytime GPS registers a new location; does it update it? What I want to know is that if it's not latest can it still be closed to latest? As I didn't see an option in android emulator to configure the time period between subsequent updates.
Any help is much appreciated.
Cheers
but what if I do want the latest location right now, in a service and not activity?
Sorry, but that is not possible, in either a service or an activity. For example, if the GPS radio is off, and you are requesting location data from GPS, it will take tens of seconds just to get a fix, and that's if you are lucky. It might not get a fix at all.
How can I wait for callback to happen and stop my service from returning.
You don't. You do what you said you would do:
use getLastKnownLocation from locationManager as that doesn't respond back by callback
So, have your Service (which is hopefully an IntentService) check to see if getLastKnownLocation() happens to have a value. If it does, use it. Otherwise, registerLocationUpdates() using a PendingIntent that will pass control back to your IntentService. When you get that Intent, use the location and unregister for updates (assuming the alarm period is nice and long, like, say, once an hour).
Things get tricky if your alarm is a _WAKEUP alarm. You will then need to hold a WakeLock, so the device does not fall back asleep while you are trying to get a GPS fix. However, you need to release that WakeLock sometime, and if we cannot get a GPS fix...ummm...well, that's the tricky part. Trying to figure out a nice clean way of handling this, and implementing it as a reusable component (e.g., LocationAlarmService), is one of 18,000 items on my to-do list.
Also, at what point does lastKnownlocation gets updated? Everytime GPS registers a new location; does it > update it?
AFAIK, yes.