Welcome to Part 2 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.
Android Location Providers
Providers and provider characteristics
We learned it Part 1 that there are two primary location providers, GPS and Network-based, but Jim says new providers may come along as a result of new technology.
Providers are able to describe themselves. This is done by using the LocationProvider class.
Jim introduces some of the major methods in this abstract superclass:
- getPowerRequirement()
- getAccuracy()
- requiresCell()
- requiresNetwork()
- requiresSatellite()
- supportsAltitude()
- supportsBearing()
- supportsSpeed()
Selecting providers by behavior
This lesson explores the Criteria class, which is used to specify desire provider behavior. The primary focus is on what we need, not how to get it.
Jim introduces the most important methods in this class:
- setAltitudeRequired(boolean)
- setBearingRequired(boolean)
- setSpeedRequired(boolean)
- setAccuracy(int)
- setSpeedAccuracy(int)
- setVerticalAccuracy(int)
- setPowerRequirement(int)
- setCostAllowed(boolean)
With this class we can match behavior to providers, and there are 3 ways to do this:
- Determine if a provider meets the criteria
- Select the list of providers that meet the criteria
- Request location updates using a provider that meets the criteria
The last two of these approaches are the most common.
Demo: Selecting providers by behavior
We see how to setup the criteria for a couple of different scenarios: a high accuracy provider, and a low power provider.
Jim reminds us to ensure that we have all the necessary permissions first, otherwise we won’t see some or all of the providers that we need.
For each scenario we only need about a dozen lines of simple code, and the code of so similar for each scenario that Jim actually copy-pastes from function to the other and then makes the necessary tweaks.
Provider availability and influences
Jim stresses that we should always check whether the location provider is enabled, by using LocationManager.isProviderEnabled because we won’t get any errors of we try to listen to a location provider that isn’t enabled.
Jim also says the network provider has a number of issues to be concerned about, such as:
- When Wi-fi is off, accuracy is severely reduced
- Airplane mode is on
We can determine whether Wi-Fi is on by using the ConnectivityManager.
Jim also recommends using AIRPLANE_MODE_ON to determine whether our user has enabled Airplane mode.
We won’t get any disabled callback if the user switches off Wi-Fi halfway through using our app, so we need to check whether it is still on each time.
Jim introduces the concept of the BroadcastReceiver, which is a way to receive notifications about things that are going on in the device. We can associate a BroadcastReceiver with an IntentFilter.
He recommends watching one of his previous courses Android Programming with Intents if you’re not already familiar with them.
Demo: Provider availability and influences – Part 1
Jim demonstrates the safety first mind set that we must get ourselves into: coding functions with these questions in mind
- confirmNetworkProviderEnabled – is the network provider enabled?
- confirmAirplaneModeOff – are we not in Airplane mode?
- confirmWiFiAvailable – is Wi-Fi on?
In cases where one or more of these conditions is not met, Jim makes use of an AlertUserDialog class which extends DialogFragment.
Jim has also produced a course called Improving User Interface Design with Android Fragments which delves deeper into that area.
After Jim steps through the program in debug mode, we see the alert message “Please disable Airplane mode”.
Demo: Provider availability and influences – Part 2
The previous demo made the safety checks before we started. Next we need to check for changes made after we’ve started, using a BroadcastReceiver.
We begin by adding a new Android component:
- Name: NetworkProviderStatusReceiver
- Kind: “Broadcast Receiver”
The code that we write is in the onReceive method, and it’s all based on Intents. We check for ACTION_AIRPLANE_MODE_CHANGED and CONNECTIVITY_ACTION.
Jim explains that whenever we launch a broadcast receiver, we must associate it with the actions that we’re interested in. These are called intent filters.
He discusses the pros and cons of putting your intent filter in your manifest, versus in code.
Here we put the intent filter in our code, creating a start method to register our receiver, and a stop method to unregister it.
Enabling location-related features
Jim asks how do we deal with getting these features enabled if they’ve been turned off?
There was once a mentality of “the application should have control”, but nowadays all major mobile platforms put the user more in control of their phones and tablets.
We as developers need to make it as easy as possible for the users to turn these features back on. We can do this by automatically displaying the needed feature screens.
This isn’t as difficult as you might think. All of the settings screens are Activities, and we can use startActivity with the appropriate Intent for the feature screen.
Demo: Enabling location-related features
Now we see how to go from a basic alert to loading up the correct screen for them.
Our AlertUserDialog will take an additional parameter telling it which settings screen we need to load up, and it will be called with the following values
Jim shows that once the user has enabled the necessary feature, they can get back to our app by clicking the back button.
Accessing underlying GPS information
Jim introduces us to the NMEA sentences that GPS devices use. This is low level GPS information which is much more detailed than the basics such as latitude and longitude.
In order to get access to these, we can implement the GpsStatus.NmeaListener interface.
The Passive location provider
The passive provider does no explicit location monitoring. So why would we want to use this?
Jim says we can use this to ask Android to receive location information when another source requests it, and then we can find out what the actual provider is using Location.getProvider
Demo: The Passive location provider
Jim writes the code for this, runs it up and clicks “Start Passive Listener”. Then he loads up a weather application and we see that our own application is now listening in to these location messages.
We can also listen to the Google Maps GPS messages.
Continue to Part 3 – Android Location Management and Threading