Performing an action based on location - android

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.

Related

Battery impact of polling for location updates less often?

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.

Android: Right approach for sensing the distance between current location and some point of interest?

I have a question regarding my programming approach for android - whether it's efficient or not. Just to give you an idea what I try to accomplish:
There are multiple points of interests on a map. If the user gets nearer to a PIT, a notification about the distance shall appear. There are let's say 3 notifications: At a distance of 1 mile, 0.5 miles and 0.1 mile. When the user is more or less exactly at the PIT, no more notifications are shown. The user is supposed to drive a car or another vehicle.
I'm currently using Geofences to detect whether the user has entered a radius of 1 mile. If so, I check the distance of his current location to the PIT. If it's about 0.5 or 0.1 miles away, a notification is fired. Therefore, I check the current location frequently (right now every 10 seconds). If the user is like at the PIT or rather very close, the Geofence is exited and done.
The code is working fine and this approach is the first thing that came to my mind while reading the Android Developer's tutorials etc. But is there another approach that is MORE EFFICIENT?
Although this is (currently) meeting my needs, I have two major concerns:
It seems to drain the battery quite a lot. Since the user is most likely to be in a car where he can charge his phone during usage, this might be less of a problem.
I read the number of PITs from a file on the SD card. In my example I have just a few PITs. But the user is able to modify the source data so that he can add as many as he wants to. Google says that only 100 active Geofences are supported per user. But what if my user has more than 100 PITs? Since I'm using a Geofence to sense whether I have to fire the first notification or not - this is a severe problem. So is there an alternative?
I have a few suggestions :
1) To lower the amount of gps fixes, you could calculate a sleep time. The idea is to do frequent gps fixes when near a 'border' and few when far away. This could be further enhanced by taking the speed parameter returned by the GPS into account.
If for instance the user is 20 miles from the nearest border while driving 20mph, you can easily wait 30 minutes before turning on the gps again, just to give a simple example.
2) I have run in to the same problem. My solution was simply to select only the POI's within X miles. This way ensuring never to risk hitting the limit of 100. When the user has moved (X-1) miles from his initial position, the geofences are rebuild using the new location.
If you think there is a high risk of having such a high density of points that the above strategy still might fall, I would consider making your own proximity checking entirely based on gps instead of geofences.

record user's location / movement throughout the day

I am developing an app which can record user's location througout the day so app can find out the approx lifestyle of user. app has to collect data in the background at some interval so i need a best strategy to invoke a location update request to LocationManager of android. But it must be optimized in terms of battery and balanced in terms of accuracy.
Right now the flow in my mind is,
iterate through the location providers, give higher priority to NETWORK (as it consumes less power), o this for each,
get the last known location
get the current loction
chek if current is better than last
if yes make this the best estimate, otherwise get location from other provider
i know two parameters which can decide when to invoke location update request,
minimum interval
minimum distance
first i would give them some default value but these must be updated later by using the location history of user and considering other factors in mind like
reduce the frequency of update request if battery is < 75% and further reduce it when
battery is < 50%
increase frequency of update request when user is moving fast (Activity Recognition Class
from google location services can help here)
if we predict the time windows in which user does not move (from history), decrease the
frquency of location updates
use GPS minimal time because it consumes more battery
So these are the pieces that came to my mind but it looks like a mess right now because it is not well structured. So if somebody can help me to add something more in this or can suggest some better strategy (battery must be optimized) i would be very thankful and it was long so please control your emotions if you think i have wasted your time. Thanks
In order to get a good accuracy, Google provides an algorithm that provides, in my opinion, good results. You can find it there : reference
GPS take so time to have a fix, I would say about a minutes (depends on the device).
I would suggest you to look at the Passive Mode, which allows you to receive position without making a fix by using other applications requests.
passive: A special location provider for receiving locations without actually initiating a location fix. This provider can be used to passively receive location updates when other applications or services request them without actually requesting the locations yourself. This provider will return locations generated by other providers. Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS is not enabled this provider might only return coarse fixes.
gps tutorial
Hope it helps !

Is location provider really a battery drain?

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.

Does anyone know whether the Android addProximityAlert on the LocationManager is battery intensive

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.

Categories

Resources