Android programming is a brand new thing to me, i've been playing with android's location and i have a same issue, im going to send a periodic location updates to a server in background and i'm using the AlarmManager/LocationManager approach, set an alarmManager with a defined Interval then when the alarmReceiver is triggered it will get device's current location (using locationManager) and send it to the server on its onReceive method. i found out this FusedLocation as a great replacement as LocationManager give me an additional job to get the best location provider. is it possible to perform sending location updates in background periodically using fusedLocation api without an alarmManager? if so, how can i do that? thanks in advance!
Per the LocationRequest documentation:
In between these two extremes is a very common use-case, where applications definitely want to receive updates at a specified interval, and can receive them faster when available, but still want a low power impact. These applications should consider PRIORITY_BALANCED_POWER_ACCURACY combined with a faster setFastestInterval(long) (such as 1 minute) and a slower setInterval(long) (such as 60 minutes). They will only be assigned power blame for the interval set by setInterval(long), but can still receive locations triggered by other applications at a rate up to setFastestInterval(long). This style of request is appropriate for many location aware applications, including background usage. Do be careful to also throttle setFastestInterval(long) if you perform heavy-weight work after receiving an update - such as using the network.
This allows you to guarantee you'll get location updates based on the interval you set with setInterval(long), giving you the equivalent behavior to a periodic alarm, but if other apps request location information, you may get location information as often as your setFastestInterval(long) - you can set your fastest interval to your interval if you just want location updates at a set interval.
Related
Given the limits placed on location gathering on Android apps running in the background on O devices, what are good options for developers who want more frequent location updates?
I realize that O is still in developer preview, but there are significant changes to how location can be gathered in the background, and I want to project ahead to changes that might be needed in my apps.
Apps requesting location updates that are not in the foreground are subject to some limits when running on O devices. Location updates are still available in the background, but they may be happen less frequently than the interval specified in LocationRequest#setInterval. Developers have the following options for getting more frequent location updates:
Request updates in the foreground. This means requesting and removing updates as part of the activity lifecycle (request in onResume() and remove in onPause(), for example). Apps running in the foreground are not subject to any location limits on O devices .
Request updates using a foreground service. This involves displaying a persistent notification to users.
Use geofencing to trigger notifications based on the device’s location. If your use case relies on the device entering, dwelling, or exiting a particular area of interest, this API provides a performant way to get these notifications. See the GeofencingEvent#getTriggeringLocation[, which gets the location that triggered the geofence transition.
Use batched location updates using LocationRequest#setMaxWaitTime. With this API, locations may be provided more frequently than the non-batched API however, will be delivered in a batch after the interval specified in setMaxWaitTime (also limited to a few times an hour)
Use passive location updates: While your app is in the background, it may continue to receive location updates passively if another app in the foreground requests location updates. You can receive some of these updates by using LocationRequest#setFastestInterval with a small interval, such as 5 min.
Given that this is a large-scoped question on how to handle Android O background location restrictions, this may be relevant:
If your app needs to receive locations in the background primarily to use as a dependent input, Awareness API may be useful for you.
Geofence is one example where you want to be notified when device moves by X miles (and you do not really care about the actual location coordinates). Similarly, if you need location for things like fetching location-dependent data on server, or triggering location-dependent notifications, Awareness has a bunch of useful APIs.
For example, the weather snapshot API lets you get the weather at device location without you having to request locations. TimeFence has APIs for waking-up apps at instants based on timezone or sunrise/set etc at device location.
I am developing an android application wherein I need the user location updates pretty frequently. Say 2 times a minute.
Earlier I had been using Google Play Service's "Fused location service" but the location updates were not received as requested.
The location updates got stuck for sometime, the interval between updates jumped to 10min or so.Sometimes even if I put my priority to "PRIORITY_HIGH_ACCURACY" the same happened.
I then went back to the old "Location Manager" and when I used the "NETWORK_PROVIDER", I noticed that the location updates got stuck due to this provider. Also the GPS does not get activated immediately, it takes some time. I am trying to build my custom fused location provider. How can I efficiently switch between providers, without getting lags on location updates.
I want to know what are the best practices for getting location updates regularly, all the time, be it either NW, GPS or both. Like it should work for an application where location updates getting stuck cannot be afforded.
Battery drain is not an issue for me right now.I am aware of all the supporting docs that Google provides regarding location access.
Any help would be much appreciated.
Thankyou !
FusedLocationProvider really is the best option for obtaining locations at the moment, because it uses a lot more than just GPS or Network data to obtain location fixes. I have experienced issues regarding intervals being missed as well, but ultimately this is something down to luck depending on availability of GPS, Network, etc. etc.
My favourite usage of FusedLocationProvider so far is in conjunction with the AlarmManager class: Basically, the idea is to start location tracking at intervals specified by the Alarm Manager (this can be set to every 30 seconds such as in your case). Once the interval is hit, the location provider is to obtain a location fix as soon as possible (so in the setInterval method or whatever it's called, the parameter is a 0). This way, you can avoid having to wait another 30 seconds for a new location, instead having the location tracker attempt to provide a location as soon as possible after the interval specified by the Alarm Manager is hit.
By the way, when making custom location tracking wrappers, be careful of using the .getLastKnownLocation() method as it only uses cached locations - you could end up sending the same location to the user every 30 seconds.
Good luck!
I'm fresh with Android. I face some ambitious university project, so I hope you'll tell me if my idea about following app's implementation is correct and efficient:
Business scenario:
WebService consumes informations about user's sms (sendt/received) and GPS/"network provided" position
GPS/"network provided" position's should be sendt to WebService every 1 minute (if it's value changed)
sms update should be sendt to WebService immediately
My implementation idea...
I'm going to use AlarmManager prepare Intent matching BroadcastReceiver (and schedule it with 1 minute interval). Then I'll start WakefullIntentService in onReceive() method. This will feed my WebService in the background. That would work for sending data over HTTP in the background.
... and doubts:
How about updating GPS/"network provided" position data in the background? Should I start some additional service and use LocationListener within it? There would be no sense for using AlarmManager then - I could feed my WebService from this location-monitoring service.
But as I read here: Diamonds Are Forever. Services Are Not. it's not a good practise to play with never-ending services. As I understand it would not work correctly when my phone is sleeping.
First things first, polling the GPS every minute is going to KILL your users battery. So I'd rethink about that portion of your application.
Your alarm manager idea is fine in theory with the exception of using a Wakeful IntentService. If you're waking up the phone every minute (or more often), you're once again going to kill the battery. What you should do is when you get the broadcast, save what ever data contains to disk (probably in a sqlite database). When the device fully wakes up (this is a broadcast you can recieve), then flush the content to your webservice.
Do not use the alarm manager. It is unnecessary for what you want to do.
Use a background service that implements LocationListener. You can specify how often you want to check for location updates and even how much distance must change in order to consider it a new location. This is done in the requestLocationUpdates method.
Here is some code to get you started:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000, 1, this);
This will try to get a new location every 60 seconds and only if the distance has changed by 1 meter. That is the location listener will only fire if the conditions above are met.
Hope this helps.
I am experimenting with Androids location updates. The requestLocationUpdates is responsible for providing the updates. With the following code:
locationManager.requestLocationUpdates(provider, 300000, 10, this);
I am only supposed to receive updates 5 minutes and 10 meters apart. But the updates just keep coming in seconds apart and even when I am sitting still.
GPS is the provider I am using.
I need to space the updates out. What can I try?
The 10m is too small - I would increase that. GPS accuracy isn't great, and so every time it senses a small difference you will get another location. I'd bump it up to 100m and I expect you will then get a sensible number of locations coming through.
If you do want it more specific, then you'll need to handle the volume as more accurate means more volume.
Hers what i'd do:
First of all I check what providers are enabled. Some may be disabled on the device, some may be disabled in application manifest.
If any provider is available I start location listeners and timeout timer. It's 20 seconds in my example, may not be enough for GPS so you can enlarge it.
If I get update from location listener I use the provided value. I stop listeners and timer.
If I don't get any updates and timer elapses I have to use last known values.
I grab last known values from available providers and choose the most recent of them.
The 10m is too small for a GPS reading, try 100m. You'll also have issues with power saving mode, and app battery optimisation on most Android phones.
Android 10 and above has very strict background location updates, and may kill apps that run in the background. Later versions will also remove apps that have not be used recently.
I am trying to determine if an Android user has had a close proximity to a list of predetermined locations. I'd like to do this with the least amount of drain on the phone's battery. The two mechanisms I see for accomplishing this are proximity alerts and requesting location updates. What are the pros and cons of the two methods? Will one have less affect on the battery than the other? In either case I would guess the specific location manager used would have some affect power usage (existing Stack Overflow answer).
Location updates are probably less expensive than proximity alerts in terms of battery usage.
Since addProximityAlert uses both NETWORK_PROVIDER and GPS_PROVIDER, you lose the ability to pick which provider you want to use. Additionally, while the documentation suggests that it limits proximity checks to once every four minutes when the screen is off, I can't find the code to support such functionality and what I can find is essentially a call to requestLocationUpdates with a minimum time interval hint of 1000 ms. Since it is recommended that background services use values over 60000 ms, I suspect that it would be less expensive to call requestLocationUpdates directy with a large minimum time interval and NETWORK_PROVIDER.