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.
Related
i'm creating a location tracking app to let users plot a heat map of where they traveled throughout the day. this involves constantly gps querying the user's location, a battery-intensive operation. one way i thought to reduce the app's power consumption is to set up a geofence after a few location updates return roughly the same value, and shutting down the location updates until the user exits the geofence (signifying that they are once again on the move).
this will allow my app to only perform frequent GPS queries when the user is actually moving (triggered by them exiting a geofence).
however, i'm not quite sure if this will reduce power consumption, because if the geofence is triggered by constantly querying the user's location to see if they have moved outside the fence, it will have basically the same effect on the battery.
so my question is, how does the geofence know when the user has left/entered the area? is it based on simple periodic location queries? or is there some more clever mechanism involved? thanks!
link to current version of app:
https://play.google.com/store/apps/details?id=com.russ.locationalarm&hl=en
The way Android is handling geofencing is quite complex. There are many differences between devices, but also between Android versions. But as a quick answer, your solution could save battery, because detecting a zone exit don't necessarily require GPS, but could use other location methods like Cell ID or Wifi, which are much less battery consuming. You also need to know that geofencing is not a 100% reliability solution, in particularly on Zone Exit events (less than 50% of zone exits detected in average), that are less reliable than Zone Enter events. Some companies like Herow, Radar, Foursquare are building SDKs that manage specifically geofencing.
I've read a lot of conflicting information on this.
Suppose I use the Fused Location API in PRIORITY_HIGH_ACCURACY mode, does it make much difference if I set the interval to, say, 10 minutes vs 1 minute? 1 hour vs 10 seconds? If so, how drastically?
I don't know how it works internally so I'm just wondering what I can do to save battery if I need high accuracy location (and relative infrequency of polling isn't an issue).
https://developer.android.com/training/monitoring-device-state/index.html
The developer site has advice on how to save battery but they don't seem to give any concrete information on exactly how much polling frequency affects battery life.
Does enabling the service keep the GPS on all the time and therefore always using battery (and so the interval would be synthetic and solely for programmatic reasons)?
Thanks!
For Fused Location API, I'm not certain if they turn off GPS or adjust reporting interval while leaving it on, but I would assume they turn off GPS between updates, or else many others would complain about power drain.
As for what Android Location Service does, they do turn off GPS and allow the phone to idle between updates if the interval is greater than 0 (check out the source in LocationManagerService). I've done quite a bit of power testing on different android phones, and found that keeping the CPU from idling can draw a noticeable amount of power. Add the power draw of GPS (which keeps the CPU from idling) and you are looking at a decent power drain (about 50% of what the screen would draw for some devices).
In the end, I'd have to agree with Gabe Sechan and advise you on choosing whether accuracy is worth the battery drain. Just ask yourself these basic questions:
Do I need to know if my user is on one side of the street or the other?
If yes, use GPS, else use Network or low accuracy location.
How often do I need to check my user's location?
If you need it about once a minute, set your interval as such. If you only care when they leave a general area, setup a geofence, or use network locations. You can also listen to location updates from other apps, and make your app smarter about when to take updates.
If I can't get my user's location within X amount of time, can I skip this update altogether?
If you can, then put a timeout feature in your update logic. If not, I strongly recommend you re-evaluate the app logic in that case.
I'm creating an app wherein I'm need to perform an action when I'm within a certain radius of a location. But I don't want to be continuously polling the location because that'll drain the battery.
I thought about just putting an option for the user to specify how often to query the location. However, I'm concerned that if the user sets it too long, then my app will miss performing the action when it's near the location.
I in one Google IO session that Pay With Square had an auto tab feature, I'm not sure if they're constantly polling the location, have setting for the delay between querying the location or a third option that's efficient without draining the battery.
I would like to ask for suggestions on how to approach this.
Thanks in advance.
It looks like your question actually is: "how can I get an accurate position measurement while saving the battery of my device?"
There are mainly two ways to save battery AND have a good positioning:
Do not use GPS (that is a real battery hog)
Set a large interval between poll actions
You can get a quite good positioning (from 40 to 150m radius, that is better than GPS in many cases) using only the wi-fi and phone cell data. Just select "ACCURACY_COARSE", "ACCURACY_LOW" and/or "POWER_LOW" as a provider selection criteria in your code.
See the following links at Google Developer's web site:
Location Strategies
Location and Maps
LocationManager
And in particular these two:
getProviders
Criteria
You can select/set a battery-saving poll interval on the basis of the measured speed of the user. If the user is walking (less than 5 km/hour), you can use a 30 - 60 seconds interval without any risk to miss your alert. If the user is traveling by car (more than 50 km/hour) you will have to set a 1 - 10 second interval. Consider that location space accuracy is usually quite bad (100 m or so) so it does make very little sense to try to "cath" the point with a very high time (speed) accuracy.
Have a look at Google documentation for this, as well.
In any case, Google explicitly suggests to NOT try to save battery using your own code and rely on the getProviders criteria for this.
I need to implement location-based service. I don't need fine location, so no GPS is needed.
Easiest would be to start listening for locations updates at app start, and leave it ON:
mLocationMgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 100, mPendingIntent);
Since I don't need much accuracy, I set max frequency of updates, to 10s, and 100m instead of default 0, 0.
When we think location, we think battery drain, but I guess this is a shortcut and that only GPS really drains the battery. I think that such a use of network provider wouldn't drain the battery. Any thoughts?
Your 100m distance filter will do little for you from a battery drain standpoint. That will only control how many times your PendingIntent gets executed due to fixes.
Your 10 second time value might be used by the OS to control power usage, but there is no guarantee. And, with that low of a value, it seems highly unlikely that it would be used. Every hour, maybe, but not every 10 seconds.
The bigger thing is that you will be needing to keep the CPU powered on all the time. And, since you're using the PendingIntent flavor of requestLocationUpdates(), I am guessing that you plan on collecting data for a long time.
If you only have COARSE permission, Android hopefully eschews the WiFi hotspot proximity detection, which will save a bit of power.
On the whole, the network provider will consume less power than will the GPS provider. "Less" is a far cry from "little". On a Nexus-class Android device, GPS + CPU gives me a few hours battery life (as determined by using Google Navigation). I would expect network provider + CPU to last a few hours longer, but that's about it, because the CPU is a fairly significant battery drain in its own right.
My bigger concern is:
Easiest would be to start listening for locations updates at app start, and leave it ON
This sounds like you aren't actually planning on removing your location updates. This is a really bad idea, with any sort of provider (except maybe the passive provider). Please have a more concrete plan for when you are registering and removing the updates. In particular, make sure the user has the ability to control when you are consuming battery to this degree.
There is a topic about this included in the Android Developers Guide. I would recommend that you take a look at the code examples on the page.
This is what they mention regarding conserving battery and various parameters.
Adjusting the model to save battery and data exchange
As you test your application, you might find that your model for
providing good location and good performance needs some adjustment.
Here are some things you might change to find a good balance between
the two. Reduce the size of the window
A smaller window in which you listen for location updates means less
interaction with GPS and network location services, thus, preserving
battery life. But it also allows for fewer locations from which to
choose a best estimate. Set the location providers to return updates
less frequently
Reducing the rate at which new updates appear during the window can
also improve battery efficiency, but at the cost of accuracy. The
value of the trade-off depends on how your application is used. You
can reduce the rate of updates by increasing the parameters in
requestLocationUpdates() that specify the interval time and minimum
distance change. Restrict a set of providers
Depending on the environment where your application is used or the
desired level of accuracy, you might choose to use only the Network
Location Provider or only GPS, instead of both. Interacting with only
one of the services reduces battery usage at a potential cost of
accuracy.
Basically, consider reducing the frequency of the updates you request or the length of time you request them. This is like golf, the less locations you request the better. Consider the following use case:
In the example the application waits until the user performs an action that needs a location and then stops polling once the location data is no longer needed.
While polling constantly would allow the application to have a location ready at an instant notice its simply not worth the wasted resources, to mitigate the delay when requesting a location you can use getLastKnownLocation (String provider).
Edit:
There is a way to determine power usage for the various LocationProviders!
Calling getPowerRequirement () on a LocationProvider will return one of three constants.
int POWER_HIGH A constant indicating a high power requirement.
int POWER_LOW A constant indicating a low power requirement.
int POWER_MEDIUM A constant indicating a medium power requirement.
To make your code more readable look into using meetsCriteria (Criteria criteria) in any boolean checks to make your code more readable.
I would use this to determine what method your application should use for the lowest power cost, Also you have the benefit of supporting devices that have different power requirements for providers.
I just basically want to add about 20 and sometimes 80 Proximity Alerts with no time expiration with a radius of around 500 meters.
Just wondering whether by doing this will suck up the battery real quick? also would it make any difference by reducing the radius?
This will definitely eat your battery real quick. You never want to be setting more than a couple of proximity alerts in any case, the use-case you describe isn't really catered for in Proximity Alerts.
Proximity Alerts should switch between GPS and Network as required, but in my experience they tend to stick to GPS whenever it's available, and your battery will suffer as a result.
A better alternative would be to use an Alarm and a Service to check your current location against your set of 20 to 80 locations as required. This will let you manage the LBS you want to use (GPS or Cell ID), as well as the frequency of checks, all in one place. Doing it this way will let you manage your battery use much more effectively.