372 lines
16 KiB
Plaintext
372 lines
16 KiB
Plaintext
page.title=Testing Using Mock Locations
|
|
|
|
trainingnavtop=true
|
|
@jd:body
|
|
|
|
<div id="tb-wrapper">
|
|
<div id="tb">
|
|
|
|
<!-- table of contents -->
|
|
<h2>This lesson teaches you to</h2>
|
|
<ol>
|
|
<li><a href="#TurnOnMockMode">Turn On Mock Mode</a></li>
|
|
<li><a href="#SendMockLocations">Send Mock Locations</a></li>
|
|
<li><a href="#RunProvider">Run the Mock Location Provider App</a></li>
|
|
<li><a href="#TestingTips">Testing Tips</a>
|
|
</ol>
|
|
|
|
<h2>You should also read</h2>
|
|
<ul>
|
|
<li><a href="receive-location-updates.html">Receiving Location Updates</a></li>
|
|
<li><a href="geofencing.html">Creating and Monitoring Geofences</a></li>
|
|
<li><a href="{@docRoot}guide/components/services.html">Services</a></li>
|
|
<li><a href="{@docRoot}guide/components/processes-and-threads.html">Processes and Threads</a>
|
|
</ul>
|
|
|
|
<h2>Example Test App</h2>
|
|
|
|
<div class="download-box">
|
|
<a href="http://developer.android.com/shareables/training/LocationProvider.zip" class="button"
|
|
>Download the sample</a>
|
|
<p class="filename">LocationProvider.zip</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<p>
|
|
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 {@link android.location.Location} objects to
|
|
Location Services, which then sends them to location clients. In mock mode, Location Services
|
|
also uses mock {@link android.location.Location} objects to trigger geofences.
|
|
</p>
|
|
<p>
|
|
Using mock locations has several advantages:
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
Mock locations allow you to create specific mock data, instead of trying to approximate
|
|
data by moving an actual device.
|
|
</li>
|
|
<li>
|
|
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.
|
|
</li>
|
|
<li>
|
|
Since you don't have to generate test locations by moving a device, you can test an app
|
|
using the emulator.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
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 <a href="#TestData">Managing test data</a>.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p class="note">
|
|
<strong>Note:</strong> Mock locations have no effect on the activity recognition algorithm used
|
|
by Location Services. To learn more about activity recognition, see the lesson
|
|
<a href="activity-recognition.html">Recognizing the User's Current Activity</a>.
|
|
</p>
|
|
<!--
|
|
Create a Test App
|
|
-->
|
|
<h2 id="TurnOnMockMode">Turn On Mock Mode</h2>
|
|
<p>
|
|
To send mock locations to Location Services in mock mode, a test app must request the permission
|
|
{@link android.Manifest.permission#ACCESS_MOCK_LOCATION}. In addition, you must enable mock
|
|
locations on the test device using the option <b>Enable mock locations</b>. To learn how to
|
|
enable mock locations on the device, see
|
|
<a href="{@docRoot}tools/device.html#setting-up">Setting up a Device for Development</a>.
|
|
</p>
|
|
<p>
|
|
To turn on mock mode in Location Services, start by connecting a location client to Location
|
|
Services, as described in the lesson
|
|
<a href="retrieve-current.html">Retrieving the Current Location</a>.
|
|
Next, call the method
|
|
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(true)</a></code>.
|
|
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
|
|
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(true)</a></code>:
|
|
</p>
|
|
<pre>
|
|
// 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);
|
|
</pre>
|
|
<p>
|
|
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
|
|
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#disconnect()">LocationClient.disconnect()</a></code>,
|
|
Location Services returns to using its internal location providers. To turn off mock mode while
|
|
the location client is connected, call
|
|
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(false)</a></code>.
|
|
</p>
|
|
<h2 id="SendMockLocations">Send Mock Locations</h2>
|
|
<p>
|
|
Once you have set mock mode, you can create mock {@link android.location.Location} objects and
|
|
send them to Location Services. In turn, Location Services sends these mock
|
|
{@link android.location.Location} objects to connected location clients. Location Services also
|
|
uses the mock {@link android.location.Location} objects to control geofence triggering.
|
|
</p>
|
|
<p>
|
|
To create a new mock {@link android.location.Location}, create a new
|
|
{@link android.location.Location} object using your test data. Always set the provider
|
|
value to {@code flp}, which is the code that Location Services puts into the
|
|
{@link android.location.Location} objects it sends out. The following snippet shows you how
|
|
to create a new mock {@link android.location.Location}:
|
|
</p>
|
|
<pre>
|
|
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);
|
|
</pre>
|
|
<p>
|
|
In mock mode, to send a mock location to Location Services call the method
|
|
<code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockLocation(android.location.Location)">LocationClient.setMockLocation()</a></code>.
|
|
For example:
|
|
</p>
|
|
<pre>
|
|
mLocationClient.setMockLocation(testLocation);
|
|
</pre>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<!--
|
|
Run the Mock Location Provider
|
|
-->
|
|
<h2 id="RunProvider">Run the Mock Location Provider App</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<h3>Overview</h3>
|
|
<p>
|
|
The mock location provider app included with this lesson sends mock
|
|
{@link android.location.Location} objects to Location Services from a background thread running
|
|
in a started {@link android.app.Service}. By using a started service, the provider app is able
|
|
to keep running even if the app's main {@link android.app.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.
|
|
</p>
|
|
<p>
|
|
The {@link android.app.Activity} that starts when you run the provider app allows you to
|
|
send test parameters to the {@link android.app.Service} and control the type of test you want.
|
|
You have the following options:
|
|
</p>
|
|
<dl>
|
|
<dt>
|
|
Pause before test
|
|
</dt>
|
|
<dd>
|
|
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.
|
|
</dd>
|
|
<dt>
|
|
Send interval
|
|
</dt>
|
|
<dd>
|
|
The number of seconds that the provider app waits before it sends another mock location to
|
|
Location Services. See the section <a href="#TestingTips">Testing Tips</a> to learn more
|
|
about setting the send interval.
|
|
</dd>
|
|
<dt>
|
|
Run once
|
|
</dt>
|
|
<dd>
|
|
Switch from normal mode to mock mode, run through the test data once, switch back to
|
|
normal mode, and then kill the {@link android.app.Service}.
|
|
</dd>
|
|
<dt>
|
|
Run continuously
|
|
</dt>
|
|
<dd>
|
|
Switch from normal mode to mock mode, then run through the test data indefinitely. The
|
|
background thread and the started {@link android.app.Service} continue to run, even if the
|
|
main {@link android.app.Activity} is destroyed.
|
|
</dd>
|
|
<dt>
|
|
Stop test
|
|
</dt>
|
|
<dd>
|
|
If a continuous test is in progress, stop it; otherwise, return a warning message. The
|
|
started {@link android.app.Service} switches from mock mode to normal mode and then
|
|
stops itself. This also stops the background thread.
|
|
</dd>
|
|
</dl>
|
|
<p>
|
|
Besides the options, the provider app has two status displays:
|
|
</p>
|
|
<dl>
|
|
<dt>
|
|
App status
|
|
</dt>
|
|
<dd>
|
|
Displays messages related to the lifecycle of the provider app.
|
|
</dd>
|
|
<dt>
|
|
Connection status
|
|
</dt>
|
|
<dd>
|
|
Displays messages related to the state of the location client connection.
|
|
</dd>
|
|
</dl>
|
|
<p>
|
|
While the started {@link android.app.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 {@link android.app.Activity} of the
|
|
provider app returns to the foreground.
|
|
</p>
|
|
<h3>Test using the mock location provider app</h3>
|
|
<p>
|
|
To test mock location data coming from the mock location provider app:
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
Install the mock location provider app on a device that has Google Play services installed.
|
|
Location Services is part of Google Play services.
|
|
</li>
|
|
<li>
|
|
On the device, enable mock locations. To learn how to do this, see the topic
|
|
<a href="{@docRoot}tools/device.html#setting-up">Setting up a Device for Development</a>.
|
|
</li>
|
|
<li>
|
|
Start the provider app from the Launcher, then choose the options you want from the main
|
|
screen.
|
|
</li>
|
|
<li>
|
|
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.
|
|
</li>
|
|
<li>
|
|
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.
|
|
</li>
|
|
<li>
|
|
If the provider app is in the midst of a continuous test, you can switch back to real
|
|
locations by clicking <b>Stop test</b>. This forces the started {@link android.app.Service}
|
|
to turn off mock mode and then stop itself. When the service stops itself, the background
|
|
thread is also destroyed.
|
|
</li>
|
|
|
|
</ol>
|
|
<h2 id="TestingTips">Testing Tips</h2>
|
|
<p>
|
|
The following sections contain tips for creating mock location data and using the data with a
|
|
mock location provider app.
|
|
</p>
|
|
<h3>Choosing a send interval</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<h3>Simulating speed</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<h3>Calculating location data</h3>
|
|
<p>
|
|
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 {@link android.location.Location} class offers two methods for
|
|
calculating the distance between points:
|
|
</p>
|
|
<dl>
|
|
<dt>
|
|
{@link android.location.Location#distanceBetween distanceBetween()}
|
|
</dt>
|
|
<dd>
|
|
A static method that calculates the distance between two points specified by latitude and
|
|
longitude.
|
|
</dd>
|
|
<dt>
|
|
{@link android.location.Location#distanceTo distanceTo()}
|
|
</dt>
|
|
<dd>
|
|
For a given {@link android.location.Location}, returns the distance to another
|
|
{@link android.location.Location}.
|
|
</dd>
|
|
</dl>
|
|
<h3>Geofence testing</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<h3 id="TestData">Managing test data</h3>
|
|
<p>
|
|
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:
|
|
</p>
|
|
<dl>
|
|
<dt>
|
|
XML
|
|
</dt>
|
|
<dd>
|
|
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.
|
|
</dd>
|
|
<dt>
|
|
Server download
|
|
</dt>
|
|
<dd>
|
|
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.
|
|
</dd>
|
|
<dt>
|
|
Recorded data
|
|
</dt>
|
|
<dd>
|
|
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.
|
|
</dd>
|
|
</dl>
|