I'm looking for best techniques for Location Aware notifications.
My first try was to use LocationManager's addProximityAlert but it requires ACCESS_FINE_LOCATION (COARSE_LOCATION gives me a SecurityException) and keeps the GPS always ON and active (at least on Jelly Bean), which drains the battery very quickly. It also doesn't seems to respect the check only once every 4 minutes when the screen is asleep (addProximityAlert).
I'm thinking to work with the PASSIVE_PROVIDER to gather other applications location information, and maybe use a service to ask for COARSE_LOCATION every once in a while (like every 4 minutes when the screen is off, and more frequently when the screen is On and the device is plugged in).
The requirement is to when the user goes nearby some locations, the app will fire a notification.
Anyone have implemented or have suggestions to implement this in a effective and battery efficient way?
I built such an app (hence my question in the Office Hours Q&A about how to measure the power draw of the LocationManager) and meanwhile it's working really well. I initially intended to use the builtin proximity alert, but struggled over the same issue as you and thought that it's not flexible enough.
Instead, I built a service which uses the LocationProvider to poll the location every five minutes using the NETWORK_PROVIDER, calculates the distance to the desired location(s) and if within proximity, fires a notification. In cities with lots of Wifi networks, this gives me an (reported) accuracy of 50 meters.
I also use the PASSIVE_PROVIDER to benefit from other apps' location requests.
If I'm nearby a desired location and the reported accuracy is too coarse to decide whether I'm within the specified proximity range or not, I'm using single GPS location requests as backup. I also use single GPS location requests if the NETWORK_PROVIDER times out. To not have the GPS provider drain the battery while I'm using the subway, it also has a timeout with exponential backoff.
While I'm connected to a Wifi network, I assume that I'm not moving, and disable the location providers during that time.
The last change I made was to use a 15 minute ("inexact repeating") timer for the NETWORK_PROVIDER if I can determine that I will not be able make it to any of the saved locations within 15 minutes (so polling with a 5 minute intervall doesn't make sense). This helps saving power.
I was thinking about using an even longer interval to save even more power, but it's not easy to find a heuristic here that determines whether I would be able to reach one of my saved locations within that time or not, because I can not always assume the same traveling speed (walking, traveling by train or car). But as I'm not able to measure the power draw of the LocationManager caused by my app, I don't know how to evaluate the power comsumption in an every day scenario.
I wouldn't mind if the builtin API would provide all that logic, but I concluded that it does not, so I built this on my own.
Hope this helps you.
I am using the following library to do this. https://code.google.com/p/little-fluffy-location-library/
It is easy to use but it doesn't give much flexibility. You cannot change the update frequency on-the-fly for instance. But its source is available, you can convert it.