summaryrefslogtreecommitdiffstats
path: root/docs/html/training/location/location-testing.jd
blob: 5021fc0453a92b87f01eb455168807d08449c4d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
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>