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)
Related
I wanted to know what is the most battery efficient way to send accurate location updates to server/firebase every 5 seconds, even if app is closed or phone is rebooted. I tried using AlarmManager.setRepeating along with android.intent.action.BOOT_COMPLETED receiver-
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
5*1000, // 60000 = 1 minute,
pendingIntent);
But this doesn't work on Android 5.1+ due to -
Frequent alarms are bad for battery life. As of API 22, the
AlarmManager will override near-future and high-frequency alarm
requests, delaying the alarm at least 5 seconds into the future and
ensuring that the repeat interval is at least 60 seconds.
Using post a delayed message or runnable to a Handler is not a reliable solution because as soon as application is swiped off location updates are stopped.
Is there any reliable way to send accurate location updates to server every 5 seconds?
Firstly (if you haven't already) - check out Google's FusedLocationProviderApi which is designed to be network/battery efficient when it comes to location updates.
Also, have you looked in to GCM Network manager? This was designed to allow for battery efficient tasks (either one-off or recurring). It tries to batch those tasks them with other network requests to save multiple activiations of the device's radio. (Here's a short explanation)
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
Posted question recently about why my onGpsStatusChanged is called only once and not called anymore, got no answers so will assume solution is unknown (been trying it out for 2 days), so is there perhaps any alternative solution to detect if GPS signal was lost and no location updates are available?
I am running LocationListener in background service.
I need to detect when user lost GPS -> Start alarmManager for 5 minutes and if GPS appears online again -> cancel alarm.
The only problem I have detecting if gps was lost or not.
Loosing GPS just means that you will receive no more location updates.
So why not just setting the Alarm again with each location update you receive.
The set-Methods of the AlarmManager are automatically cancelling Alarms previously set with the same PendingIntent. So you will have only one Alarm set all the time. As soon as no new location is received for longer than 5 minutes your Alarm will be executed.
May be setting the Alarm again every second is too expensive (I have no idea about that). In this case, add a counter, that resets the AlarmManager only every n-th location update. The idea is still the same.
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
I would like to write an app on Android to upload my GPS location to an external website once every ~5 minutes. This needs to have as minimal an impact on battery life as possible, but it also needs to work without any user interaction. (Background: I'm competing in an Ironman triathlon which will take me about 14 hours to complete, and want to broadcast my location in near-real-time but without having to worry about fiddling with my phone.)
So my initial thought is to write a Service which uses LocationManager.requestLocationUpdates() with a minTime of 5 minutes, but will this actually wake the device up every 5 minutes for my service to do its job?
It sounds like I would also need to use AlarmManager.setInexactRepeating() to make sure my service is awake while it completes its task but how does that play with requestLocationUpdates()? Should I instead set minTime=0 on requestLocationUpdates() but then go back to sleep as soon as the next update is obtained?
Any general guidance on how to design this is greatly appreciated. I'm a competent Java programmer & will be using Google Maps on the server to plot my location, but am pretty new to Android development so I'm basically looking for a high-level plan on how to architect the client app.
Your service must be alive all the time you want to receive updates.
http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28java.lang.String,%20long,%20float,%20android.location.LocationListener%29
You can tell how often you want to be informed of location change with minTime parameter. It does not however decrease battery consumption. GPS is enabled unless you use removeUpdates method no matter how often you want to receive updates.
You can use another approache:enable GPS using method above, read one value, use removeUpdates method, wait 5 minutes and all over again. Delay between enabling and retreiving a location can be between few seconds to few minutes.