Welcome to Part 4 of this review of the Pluralsight course Android Location-Based Apps by Jim Wilson
Jim has over 30 years of software engineering experience, with the past 15 years heavily focused on creating mobile device and location-based solutions. He has co-founded multiple software-related startups and has served in a consulting role at several more.
After nearly a decade as a Microsoft Device Application Development MVP, Jim now focuses on developing Android and iOS device applications. Jim’s passion is mentoring software developers. He blogs at hedgehogjim.wordpress.com.
Also in this series:
Part 4 – Controlling Android Location Frequency
Controlling Android Location Frequency
Reducing frequency of location updates
Jim warns against trying to poll for location too frequently, advising that apps should receive location information as little as possible.
Why is this? Every location update consumes quite a lot of power, and it also requires quite a lot of programming effort to handle all of the updates.
The LocationManager can be configured to limit updates either based on time, or distance.
We can pass in a parameter for the minimum time between updates, expressed in milliseconds. Jim says there aren’t any providers that provide updates more than once a second, so in practice any number under 1000 will have the same result.
We also learn that GPS devices tend to be fairly inaccurate on first use but then get increasingly accurate as they are used more. So, although there can be substantial power savings as a result of the provider powering down, it may come at the cost of location accuracy.
Also the timings for the updates involve many more factors than just the specified number of milliseconds. A first GPS request can take around 30 seconds to respond.
The alternative to configure it so that we only receive an update after we have moved a certain number of metres.
Unlike a time based setup, the provider will rarely power down between requests, because it needs to be active to determine the distance moved. The main benefit of a distance based setup is we don’t need to write significant amounts of code to calculate how far we have moved because the provider does those calculations for us.
Jim discusses the LocationManager improvements made for API 16 (Android 4.1).
Ways to receive location updates
Throughout the course so far, Jim has mostly covered the callback interface mechanism for receiving updates.
This interface allows our app to have the most control over what happens, and has the lowest system overhead. It’s not all good news though, because it can be complicated to program.
The alternative mechanism in Android is known as pending intents. This can be simpler to work with, and allows our programs to manage location information like any other intent. The trade-off is it has a higher system overhead because of the Intent Filter matching involved.
Both of these mechanisms offer the same functionality. They are just different programming models.
Location and Pending Intents
Pending Intent are the standard mechanism for accessing components.
Jim says they are nothing to do with locations specifically, rather they’re just a standard delegation mechanism in Android.
Again he recommends his course Android Programming with Intents if you aren’t already familiar with working with Pending Intents. There is a module in that course dedicated to Pending Intents.
However there is a quick overview of Pending Intents here. There are 3 steps:
- Create an Intent
- Use one of the static get methods (e.g. getService or getActivity) to wrap it in a PendingIntent
- Pass the PendingIntent to the component of platform feature of interest
When a PendingIntent is sent, it takes care of any startup that’s required.
So what does this have to do with location updates? They can dramatically simplify certain location scenarios. Jim gives a couple of examples:
- Background tracking
- Multiple interested parties
Using location with Pending Intents
This is a straightforward process:
- Define a custom action
- Implement a Service/Broadcast Receiver with an Intent Filter for that action
- Create an Intent with that action
- Create a PendingIntent that wraps the Intent
- Call LocationManager.requestLocationUpdates with the Pending Intents
- Call LocationManager.removeUpdates when no longer desired
In this lesson Jim shows a sample of code illustrating to these steps. And the next lesson is a demo discussing each of these in detail.
When to avoid location with Pending Intents
We learn that we should avoid using with high frequency updates, because there is too much overhead involved. In these situations we should use the callback mechanism instead.
We also want to avoid using with Activity as Pending Intent target, as it causes the Activity’s onCreate to be called every time.
Jim says that, if we make this mistake, to the user the application feels like the undead – they keep closing the Activity, but more location events fire and the Activity keeps coming back to life again!
We can use if the Activity has a launchmode set to singleInstance, but there are some issues that go with this as well.
In general we should limit our use of Pending Intents to Services and Broadcast Receivers.
The system can alert you when you get near a specific location.
Jim thinks of this as the “are we there yet?” feature.
We can implement this feature using LocationManager.addPromixityAlert
Internally, this uses both a network and a GPS provider.
It is extremely power intensive, so we must use it with caution
To provide a proximity alert we need:
- Latitude and longitude of the location of interest
- The distance from that location (in metres)
- How long to monitor for (in milliseconds). This has one has 2 special codes:
- -1 to monitor until removeProximityAlert is called
- 0: Am I within the proximity right now?
Jim says we need to bare in mind that location accuracy isn’t exact so it could potentially report that it is in and out and back in the proximity radius when the user is on the edge of it.
We need to design our code to watch for that behavior and deal with it appropriately.