Location Services: Part 1
(Location and Geocoding)
Overview of Location-Based Services
•
Location-based services use real-time location data from
a mobile device or smartphone to provide information,
entertainment, or security.
•
Location-Based services are available on most
smartphones, and a majority of smartphone owners use
location-based services.
•
Many popular applications integrate location-based
services. Examples include
–
–
–
–
GasBuddy
IMDb
Starbucks
Navigation
©SoftMoore Consulting
−
−
−
−
TripAdvisor
Google Maps
The Weather Channel
Facebook Places
Slide 2
Location Providers
•
GPS is more accurate, but
– it only works outdoors
– it uses more battery power
– it doesn't return the location quickly
•
Android’s Network Location Provider determines user
location using cell towers and Wi-Fi signals. It is less
accurate than GPS, but
– it works indoors and outdoors
– it uses less battery power
– it responds faster
©SoftMoore Consulting
Slide 3
Challenges in Determining User Location
•
Multitude of location sources
GPS, Cell-ID, and Wi-Fi can each provide a clue to users location.
Determining which to use and trust is a matter of trade-offs in
accuracy, speed, and battery-efficiency.
•
User movement
Because the user location changes, you should account for
movement by re-estimating user location every so often.
•
Varying accuracy
Location estimates from each location source are not consistent in
their accuracy. A location obtained 10 seconds ago from one
source might be more accurate than the newest location from
another or same source.
©SoftMoore Consulting
Slide 4
Location-Based Services in Android
•
Android provides two location frameworks
– in package android.location
– in package com.google.android.gms.location
(part of Google Play services)
•
The framework provided by Google Play services is the
preferred way to add location-based services to an
application.
– simpler API
– more power efficient
− greater accuracy
− more versatile
Note that some classes in package android.location
are still used by the Google Play services API.
©SoftMoore Consulting
Slide 5
Download Google Repository
(Android SDK Manager)
©SoftMoore Consulting
Slide 6
Set Up Google Play Services
(https://developers.google.com/android/guides/setup)
•
Make sure that Google Repository is installed, as shown
in the previous slide.
•
•
Create an application using Android Studio.
In Android Studio under “Gradle Scripts”, edit the
build.gradle file for “Module: app” (not the
build.gradle file for the project). Under dependencies
(near the bottom), add the following line near the end:
compile 'com.google.android.gms:play-services-location:10.2.0'
• Save the changes and click “Sync Project with Gradle
Files” in the toolbar, or click on menu item
Tools Android Sync Project with Gradle Files.
©SoftMoore Consulting
Slide 7
Set Up Google Play Services
(continued)
•
Add the following metadata to the application manifest.
<application
...
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
<activity
...
</activity>
</application>
©SoftMoore Consulting
Slide 8
Key Interfaces for Google Play Services
(in package com.google.android.gms.common.api)
• GoogleApiClient
– main entry point for Google Play services integration
– uses the builder pattern to construct an instance
– selected methods include
abstract void connect()
abstract void disconnect()
abstract void isConnected()
• GoogleApiClient.ConnectionCallbacks
– provides callbacks that are called when the client is connected or
disconnected from the service
– abstract methods:
void onConnected(Bundle connectionHint)
void onConnectionSuspended(int cause)
©SoftMoore Consulting
Slide 9
Key Interfaces for Google Play Services
(continued)
• GoogleApiClient.OnConnectionFailedListener
– provides callbacks for scenarios that result in a failed attempt to
connect the client to the service
– abstract method:
void onConnectionFailed(ConnectionResult result)
©SoftMoore Consulting
Slide 10
Requesting User Permissions
•
In order to receive location updates, user permission
must be declared in the Android manifest.
– ACCESS_COARSE_LOCATION to access locations provided by cell
tower/Wi-Fi triangulation
– ACCESS_FINE_LOCATION to access locations provided by GPS
• Both permissions are classified as dangerous and
therefore applications must check at runtime whether or
not they have been granted.
•
The ACCESS_FINE_LOCATION permission includes
permission for both location providers.
©SoftMoore Consulting
Slide 11
Requesting User Permissions
(continued)
•
Example
<manifest ... >
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
...
</manifest>
©SoftMoore Consulting
Slide 12
Steps in Connecting to Google Play Services
•
•
•
•
•
•
Request permission in the manifest and at runtime.
Import classes/interfaces.
Declare that the activity implements callback interfaces.
Declare/build GoogleApiClient object.
Implement callback interfaces.
Implement methods onStart(), onStop(), and possibly
other lifecycle methods such as onPause() and
onResume() to gracefully handle connections to Google
Play Services
©SoftMoore Consulting
Slide 13
Example: Connecting to Google Play Services
import
import
import
import
...
com.google.android.gms.common.ConnectionResult;
com.google.android.gms.common.api.GoogleApiClient;
com.google. ... GoogleApiClient.ConnectionCallbacks;
com.google. ... GoogleApiClient.OnConnectionFailedListener;
public class MainActivity extends AppCompatActivity
implements ConnectionCallbacks, OnConnectionFailedListener
{
private GoogleApiClient googleApiClient;
...
@Override
protected void onCreate(Bundle savedInstanceState)
{
...
buildGoogleApiClient();
checkAccessLocationPermission();
}
(continued on next page)
©SoftMoore Consulting
Slide 14
Example: Connecting to Google Play Services
(continued)
protected synchronized void buildGoogleApiClient()
{
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
add location
}
services API
@Override
public void onConnected(Bundle connectionHint)
{
Log.i(LOG_TAG, "googleApiClient is connected ");
}
(continued on next page)
©SoftMoore Consulting
Slide 15
Example: Connecting to Google Play Services
(continued)
@Override
public void onConnectionSuspended(int cause)
{
// The connection to Google Play services was lost.
// Attempt to re-establish the connection.
Log.i(LOG_TAG, "Connection suspended");
googleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult result)
{
// Refer to the javadoc for ConnectionResult
// for possible error codes.
Log.i(LOG_TAG, "Connection failed: error code = "
+ result.getErrorCode());
}
(continued on next page)
©SoftMoore Consulting
Slide 16
Example: Connecting to Google Play Services
(continued)
@Override
protected void onStart()
{
super.onStart();
googleApiClient.connect();
}
@Override
protected void onStop()
{
super.onStop();
if (googleApiClient.isConnected())
googleApiClient.disconnect();
}
...
(continued on next page)
©SoftMoore Consulting
Slide 17
Example: Connecting to Google Play Services
(continued)
// in method checkAccessLocationPermission()
if (permissionCheck == PackageManager.PERMISSION_GRANTED)
{
isPermissionGranted = true;
googleApiClient.connect();
}
// in method onRequestPermissionsResult()
if (requestCode == REQUEST_ACCESS_LOCATION)
{
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
isPermissionGranted = true;
googleApiClient.connect();
}
...
}
Call googleApiClient.connect() if permission is granted.
©SoftMoore Consulting
Slide 18
Testing Google Play Services
To test an application using the Google Play services SDK,
you must use either
•
A compatible Android device that runs Android 2.3 or
higher and includes Google Play Store
• An Android emulator (virtual device) that runs the Google
APIs platform based on Android 4.2.2 or higher
©SoftMoore Consulting
Slide 19
Key Location Classes and Interfaces
In package android.location
• Class Location
– represents a geographic location sensed at a particular time
•
Class Address
– represents an address as a set of strings describing a location.
•
Class Geocoder
– translates between locations and addresses
©SoftMoore Consulting
Slide 20
Key Location Classes and Interfaces
(continued)
In package com.google.android.gms.location
• Class LocationServices
– main entry point for location services integration
•
Interface FusedLocationProviderApi
– main entry point for interacting with the fused location provider
•
Interface LocationListener
– receives notifications when the location has changed
•
Class LocationRequest
– contains quality-of-service parameters for requests to the
FusedLocationProviderApi
©SoftMoore Consulting
Slide 21
Class Location
•
A location consists of
– a latitude
– a longitude
– a UTC timestamp
•
A location can optionally contain information on altitude,
speed, and bearing.
•
Information specific to a particular provider or class of
providers may be communicated to the application using
method getExtras(), which returns a Bundle of
key/value pairs. Each provider will only provide those
entries for which information is available.
©SoftMoore Consulting
Slide 22
Selected Methods in Class Location
(package android.location.Location)
•
double getLatitude()
– Returns the latitude of this fix.
•
double getLongitude()
– Returns the longitude of this fix.
•
long getTime()
– Returns the UTC time of this fix in milliseconds since January 1,
1970.
•
float bearingTo(Location dest)
– Returns the approximate bearing in degrees East of true North.
•
float distanceTo(Location dest)
– Returns the approximate distance in meters between this location
and the given location.
©SoftMoore Consulting
Slide 23
Selected Methods in Class Location
(continued)
•
double getAltitude()
– Returns the altitude if available, in meters.
•
float getBearing()
– Get the bearing, in degrees.
•
float getSpeed()
– Get the speed if it is available, in meters/second over ground.
•
Bundle getExtras()
– Returns additional provider-specific information about the
location fix as a Bundle.
©SoftMoore Consulting
Slide 24
The Fused Location Provider
•
The location APIs in Google Play services contains a
fused location provider
•
The fused location provider manages the underlying
location technology and provides a simple API that
– allows you to specify requirements at a high level, like high
accuracy or low power
– optimizes the device’s use of battery power
©SoftMoore Consulting
Slide 25
Obtaining the Last Known Location
•
Class LocationServices contains a static reference to
a FusedLocationProviderApi object named
LocationServices.FusedLocationApi
•
Using this object, call
getLastLocation(GoogleApiClient client)
to obtain the best and most recent location currently
available.
•
Example (e.g., in a button’s onClick() method)
FusedLocationProviderApi locationProvider
= LocationServices.FusedLocationApi;
Location lastLocation
= locationProvider.getLastLocation(googleApiClient);
©SoftMoore Consulting
Slide 26
Geocoding
•
Geocoding is the process of transforming a street
address or other description of a location into a (latitude,
longitude) coordinate.
•
Reverse geocoding is the process of transforming a
(latitude, longitude) coordinate into a (partial) address.
©SoftMoore Consulting
Slide 27
Class Geocoder
•
Class Geocoder (in package android.location)
handles geocoding and reverse geocoding.
•
The Geocoder class requires a backend service that is
not included in the core android framework.
– may not work on the emulator
•
The Geocoder query methods will return an empty list if
there no backend service in the platform.
•
Use the isPresent() method to determine whether a
Geocoder implementation exists.
©SoftMoore Consulting
Slide 28
Example: Translating a Location to an Address
(Reverse Geocoding)
private Address getAddress(Location location)
{
Address address = null;
try
{
Geocoder geocoder = new Geocoder(this);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
int maxResults = 1;
List<Address> addresses = geocoder.getFromLocation
(latitude, longitude, maxResults);
if (addresses.size() > 0)
address = addresses.get(0);
}
(continued on next page)
©SoftMoore Consulting
Slide 29
Example: Translating a Location to an Address
(continued)
catch (IOException ex)
{
Log.e(LOG_TAG, ex.getMessage());
}
return address;
}
©SoftMoore Consulting
Slide 30
Translating an Address to a Location
(Geocoding)
•
Create a string with the address
String addressStr =
"171 Moultrie Street, Charleston, SC, 29409";
•
Create a Geocoder instance
Geocoder geocoder = new Geocoder(this);
• Call the Geocoder method getFromLocationName()
List<Address> addresses =
geocoder.getFromLocationName(addressStr, 1);
•
Retrieve the latitude and longitude from the first address
Address address = addresses.get(0);
// call address.getLatitude() and
// address.getLongitude() as needed
©SoftMoore Consulting
Slide 31
Example: Obtaining the Last Known Location
public class MainActivity extends AppCompatActivity
implements ConnectionCallbacks, OnConnectionFailedListener
{
...
private TextView latTextView;
private TextView longTextView;
private TextView addrTextView;
...
}
(continued on next page)
©SoftMoore Consulting
Slide 32
Example: Obtaining the Last Known Location
@Override
protected void onCreate(Bundle savedInstanceState)
{
...
latTextView = (TextView) findViewById(R.id.latitude_text);
longTextView = (TextView) findViewById(R.id.longitude_text);
addrTextView = (TextView) findViewById(R.id.address_text);
final Button getLocationButton = (Button)
findViewById(R.id.getLocationButton);
getLocationButton.setOnClickListener(new View.OnClickListener()
{
...
// details on next page
});
buildGoogleApiClient();
checkAccessLocationPermission();
}
©SoftMoore Consulting
(continued on next page)
Slide 33
Example: Obtaining the Last Known Location
(continued)
// in the button's onClick() listener
Address address = null;
try
{
FusedLocationProviderApi locationProvider =
LocationServices.FusedLocationApi;
lastLocation =
locationProvider.getLastLocation(googleApiClient);
if (lastLocation != null)
{
String latStr = Double.toString(lastLocation.getLatitude());
String longStr =
Double.toString(lastLocation.getLongitude());
latTextView.setText(latStr);
longTextView.setText(longStr);
address = getAddress(lastLocation);
}
(continued on next page)
©SoftMoore Consulting
Slide 34
Example: Obtaining the Last Known Location
(continued)
}
catch (SecurityException ex)
{
String errorMsg = getString(R.string.no_permission);
Log.e(LOG_TAG, errorMsg, ex);
}
StringBuilder addressLines = new StringBuilder();
if (address != null)
{
int maxIndex = address.getMaxAddressLineIndex();
for (int i = 0; i <= maxIndex; ++i)
addressLines.append(address.getAddressLine(i))
.append("\n");
}
(continued on next page)
©SoftMoore Consulting
Slide 35
Example: Obtaining the Last Known Location
(continued)
else
{
String addressNotAvailable =
getString(R.string.address_not_available);
addressLines.append(addressNotAvailable);
}
addrTextView.setText(addressLines.toString());
©SoftMoore Consulting
Slide 36
Obtaining the Last Known Location
Last location
Address of this location
(obtained using geocoding)
©SoftMoore Consulting
Slide 37
Interface LocationListener
•
Interface LocationListener is used for receiving
notifications from the FusedLocationProvider when
the location has changed.
•
The interface specifies one abstract callback method that
is called when the location changes.
void onLocationChanged(Location location)
Note that there are two Android interfaces named
LocationListener, one in package android.location,
and one that is part of Google Play Services in package
com.google.android.gms.location. This section
refers to the interface defined in Google Play Services.
©SoftMoore Consulting
Slide 38
Receiving Location Updates
•
Connect to Google Play services as described earlier in
this section.
•
Set up a location request specifying quality-of-service
parameters for the FusedLocationProviderApi.
Examples include
– priority (accuracy versus power)
– desired interval for updates
• Implement the LocationListener callback.
• Request location updates
– usually part of the onConnected() method
©SoftMoore Consulting
Slide 39
Example: Set Up LocationRequest
private static final int INTERVAL = 10000;
private static final int FASTEST_INTERVAL = 5000;
// 10 seconds
// 5 seconds
protected void createLocationRequest()
{
locationRequest = new LocationRequest();
// Set desired interval for location updates (inexact)
locationRequest.setInterval(INTERVAL);
// Explicitly set the fastest interval for location updates
locationRequest.setFastestInterval(FASTEST_INTERVAL);
// request the most accurate locations available
locationRequest.setPriority(
LocationRequest.PRIORITY_HIGH_ACCURACY);
}
©SoftMoore Consulting
Slide 40
Example: Receiving Location Updates
public class MainActivity extends AppCompatActivity
implements ConnectionCallbacks, OnConnectionFailedListener,
LocationListener
{
protected GoogleApiClient googleApiClient;
protected LocationRequest locationRequest; initialize to last
protected Location location;
location as described
...
earlier in this section
@Override
public void onCreate(Bundle savedInstanceState)
{
...
buildGoogleApiClient();
createLocationRequest();
}
(continued on next page)
©SoftMoore Consulting
Slide 41
Example: Receiving Location Updates
(continued)
@Override
public void onConnected(Bundle connectionHint)
{
... // initialize location as described earlier
updateUI();
startLocationUpdates();
}
protected void startLocationUpdates()
{
FusedLocationProviderApi locationProvider
= LocationServices.FusedLocationApi;
locationProvider.requestLocationUpdates(googleApiClient,
locationRequest, this);
}
(continued on next page)
©SoftMoore Consulting
Slide 42
Example: Receiving Location Updates
(continued)
@Override
public void onLocationChanged(Location location)
{
LocationListener
this.location = location;
callback method
updateUI();
}
@Override
public void onResume()
{
super.onResume();
if (googleApiClient.isConnected())
startLocationUpdates();
}
...
// other lifecycle methods
©SoftMoore Consulting
Slide 43
Example: Using LocationListener
(continued)
©SoftMoore Consulting
Slide 44
Location Services on the Emulator
•
A virtual device (emulator) does not have GPS or real
location providers, so it uses a “mock” GPS provider that
always returns the same position unless it is changed
manually.
•
The location on the emulator can be changed using the
location tab for the emulator’s extended controls
(click ... on the emulator control panel)
©SoftMoore Consulting
Slide 45
Setting a Mock Location on an Emulator
Using the Emulator’s Extended Controls
©SoftMoore Consulting
Slide 46
Using the Emulator’s Extended Controls
•
The Emulator Control panel can send simulated location
data in three different ways:
– Manually send longitude/latitude coordinates to the device.
– Loading a GPX file describing a route for playback to the device.
– Loading a KML file describing individual place marks for
sequenced playback to the device.
•
See the following for details of GPX and KML files:
– GPX: The GPS Exchange Format
http://www.topografix.com/gpx.asp
– KML Tutorial
http://code.google.com/apis/kml/documentation/kml_tut.html
©SoftMoore Consulting
Slide 47
Relevant Links
•
Making Your App Location-Aware
https://developer.android.com/training/location/index.html
•
Set Up Google Play Services
https://developers.google.com/android/guides/setup
• Getting the Last Known Location
https://developer.android.com/training/location/retrieve-current.html
•
Receiving Location Updates
https://developer.android.com/training/location/receive-location-updates.html
• Displaying a Location Address
https://developer.android.com/training/location/display-address.html
©SoftMoore Consulting
Slide 48
© Copyright 2026 Paperzz