This lesson teaches you to
You should also read
Example Test App
LocationProvider.zip
To test a location-aware app that uses Location Services, you don't need to move your device
from place to place to generate location data. Instead, you can put Location Services into mock
mode. In this mode, you can send mock Location
objects to
Location Services, which then sends them to location clients. In mock mode, Location Services
also uses mock Location
objects to trigger geofences.
Using mock locations has several advantages:
- Mock locations allow you to create specific mock data, instead of trying to approximate data by moving an actual device.
- Since mock locations come from Location Services, they test every part of your location-handling code. In addition, since you can send the mock data from outside your production app, you don't have to disable or remove test code before you publish.
- Since you don't have to generate test locations by moving a device, you can test an app using the emulator.
The best way to use mock locations is to send them from a separate mock location provider app. This lesson includes a provider app that you can download and use to test your own software. Modify the provider app as necessary to suit your own needs. Some ideas for providing test data to the app are listed in the section Managing test data.
The remainder of this lesson shows you how to turn on mock mode and use a location client to send mock locations to Location Services.
Note: Mock locations have no effect on the activity recognition algorithm used by Location Services. To learn more about activity recognition, see the lesson Recognizing the User's Current Activity.
Turn On Mock Mode
To send mock locations to Location Services in mock mode, a test app must request the permission
ACCESS_MOCK_LOCATION
. In addition, you must enable mock
locations on the test device using the option Enable mock locations. To learn how to
enable mock locations on the device, see
Setting up a Device for Development.
To turn on mock mode in Location Services, start by connecting a location client to Location
Services, as described in the lesson
Retrieving the Current Location.
Next, call the method
LocationClient.setMockMode(true)
.
Once you call this method, Location Services turns off its internal location providers and only
sends out the mock locations you provide it. The following snippet shows you how to call
LocationClient.setMockMode(true)
:
// Define a LocationClient object public LocationClient mLocationClient; ... // Connect to Location Services mLocationClient.connect(); ... // When the location client is connected, set mock mode mLocationClinet.setMockMode(true);
Once you have connected the location client to Location Services, you must keep it connected
until you finish sending out mock locations. Once you call
LocationClient.disconnect()
,
Location Services returns to using its internal location providers. To turn off mock mode while
the location client is connected, call
LocationClient.setMockMode(false)
.
Send Mock Locations
Once you have set mock mode, you can create mock Location
objects and
send them to Location Services. In turn, Location Services sends these mock
Location
objects to connected location clients. Location Services also
uses the mock Location
objects to control geofence triggering.
To create a new mock Location
, create a new
Location
object using your test data. Always set the provider
value to flp
, which is the code that Location Services puts into the
Location
objects it sends out. The following snippet shows you how
to create a new mock Location
:
private static final String PROVIDER = "flp"; private static final double LAT = 37.377166; private static final double LNG = -122.086966; private static final float ACCURACY = 3.0f; ... /* * From input arguments, create a single Location with provider set to * "flp" */ public Location createLocation(double lat, double lng, float accuracy) { // Create a new Location Location newLocation = new Location(PROVIDER); newLocation.setLatitude(lat); newLocation.setLongitude(lng); newLocation.setAccuracy(accuracy); return newLocation; } ... // Example of creating a new Location from test data Location testLocation = createLocation(LAT, LNG, ACCURACY);
In mock mode, to send a mock location to Location Services call the method
LocationClient.setMockLocation()
.
For example:
mLocationClient.setMockLocation(testLocation);
Location Services sets this mock location as the current location, and this location is sent out as the next location update. If this new mock location moves across a geofence boundary, Location Services triggers the geofence.
Run the Mock Location Provider App
This section contains a brief overview of the mock location provider sample app (available for download above) and gives you directions for testing an app using the sample app.
Overview
The mock location provider app included with this lesson sends mock
Location
objects to Location Services from a background thread running
in a started Service
. By using a started service, the provider app is able
to keep running even if the app's main Activity
is destroyed because of
a configuration change or other system event. By using a background thread, the service is able
to perform a long-running test without blocking the UI thread.
The Activity
that starts when you run the provider app allows you to
send test parameters to the Service
and control the type of test you want.
You have the following options:
- Pause before test
- The number of seconds to wait before the provider app starts sending test data to Location Services. This interval allows you to switch from the provider app to the app under test before the testing actually starts.
- Send interval
- The number of seconds that the provider app waits before it sends another mock location to Location Services. See the section Testing Tips to learn more about setting the send interval.
- Run once
-
Switch from normal mode to mock mode, run through the test data once, switch back to
normal mode, and then kill the
Service
. - Run continuously
-
Switch from normal mode to mock mode, then run through the test data indefinitely. The
background thread and the started
Service
continue to run, even if the mainActivity
is destroyed. - Stop test
-
If a continuous test is in progress, stop it; otherwise, return a warning message. The
started
Service
switches from mock mode to normal mode and then stops itself. This also stops the background thread.
Besides the options, the provider app has two status displays:
- App status
- Displays messages related to the lifecycle of the provider app.
- Connection status
- Displays messages related to the state of the location client connection.
While the started Service
is running, it also posts notifications with the
testing status. These notifications allow you to see status updates even if the app is not in
the foreground. When you click on a notification, the main Activity
of the
provider app returns to the foreground.
Test using the mock location provider app
To test mock location data coming from the mock location provider app:
- Install the mock location provider app on a device that has Google Play services installed. Location Services is part of Google Play services.
- On the device, enable mock locations. To learn how to do this, see the topic Setting up a Device for Development.
- Start the provider app from the Launcher, then choose the options you want from the main screen.
- Unless you've removed the pause interval feature, the mock location provider app pauses for a few seconds, and then starts sending mock location data to Location Services.
- Run the app you want to test. While the mock location provider app is running, the app you're testing receives mock locations instead of real locations.
-
If the provider app is in the midst of a continuous test, you can switch back to real
locations by clicking Stop test. This forces the started
Service
to turn off mock mode and then stop itself. When the service stops itself, the background thread is also destroyed.
Testing Tips
The following sections contain tips for creating mock location data and using the data with a mock location provider app.
Choosing a send interval
Each location provider that contributes to the fused location sent out by Location Services has its own minimum update cycle. For example, the GPS provider can't send a new location more often than once per second, and the Wi-Fi provider can't send a new location more often than once every five seconds. These cycle times are handled automatically for real locations, but you should account for them when you send mock locations. For example, you shouldn't send a new mock location more than once per second. If you're testing indoor locations, which rely heavily on the Wi-Fi provider, then you should consider using a send interval of five seconds.
Simulating speed
To simulate the speed of an actual device, shorten or lengthen the distance between two successive locations. For example, changing the location by 88 feet every second simulates car travel, because this change works out to 60 miles an hour. In comparison, changing the location by 1.5 feet every second simulates brisk walking, because this change works out to 3 miles per hour.
Calculating location data
By searching the web, you can find a variety of small programs that calculate a new set of
latitude and longitude coordinates from a starting location and a distance, as well as
references to formulas for calculating the distance between two points based on their latitude
and longitude. In addition, the Location
class offers two methods for
calculating the distance between points:
-
distanceBetween()
- A static method that calculates the distance between two points specified by latitude and longitude.
-
distanceTo()
-
For a given
Location
, returns the distance to anotherLocation
.
Geofence testing
When you test an app that uses geofence detection, use test data that reflects different modes of travel, including walking, cycling, driving, and traveling by train. For a slow mode of travel, make small changes in position between points. Conversely, for a fast mode of travel, make a large change in position between points.
Managing test data
The mock location provider app included with this lesson contains test latitude, longitude, and accuracy values in the form of constants. You may want to consider other ways of organizing data as well:
- XML
- Store location data in XML files that are including in the provider app. By separating the data from the code, you facilitate changes to the data.
- Server download
- Store location data on a server and then have the provider app download it. Since the data is completely separate from the app, you can change the data without having to rebuild the app. You can also change the data on the server and have the changes reflected immediately in the mock locations you're testing.
- Recorded data
- Instead of making up test data, write a utility app that records location data as you move the device. Use the recorded data as your test data, or use the data to guide you in developing test data. For example, record locations as you walk with a device, and then create mock locations that have an appropriate change in latitude and longitude over time.