1 page.title=Testing Using Mock Locations 2 3 trainingnavtop=true 4 @jd:body 5 6 <div id="tb-wrapper"> 7 <div id="tb"> 8 9 <!-- table of contents --> 10 <h2>This lesson teaches you to</h2> 11 <ol> 12 <li><a href="#TurnOnMockMode">Turn On Mock Mode</a></li> 13 <li><a href="#SendMockLocations">Send Mock Locations</a></li> 14 <li><a href="RunProvider">Run the Mock Location Provider App</a></li> 15 <li><a href="#TestingTips">Testing Tips</a> 16 </ol> 17 18 <h2>You should also read</h2> 19 <ul> 20 <li><a href="receive-location-updates.html">Receiving Location Updates</a></li> 21 <li><a href="geofencing.html">Creating and Monitoring Geofences</a></li> 22 <li><a href="{@docRoot}guide/components/services.html">Services</a></li> 23 <li><a href="{@docRoot}guide/components/processes-and-threads.html">Processes and Threads</a> 24 </ul> 25 26 <h2>Example Test App</h2> 27 28 <div class="download-box"> 29 <a href="http://developer.android.com/shareables/training/LocationProvider.zip" class="button" 30 >Download the sample</a> 31 <p class="filename">LocationProvider.zip</p> 32 </div> 33 34 </div> 35 </div> 36 <p> 37 To test a location-aware app that uses Location Services, you don't need to move your device 38 from place to place to generate location data. Instead, you can put Location Services into mock 39 mode. In this mode, you can send mock {@link android.location.Location} objects to 40 Location Services, which then sends them to location clients. In mock mode, Location Services 41 also uses mock {@link android.location.Location} objects to trigger geofences. 42 </p> 43 <p> 44 Using mock locations has several advantages: 45 </p> 46 <ul> 47 <li> 48 Mock locations allow you to create specific mock data, instead of trying to approximate 49 data by moving an actual device. 50 </li> 51 <li> 52 Since mock locations come from Location Services, they test every part of your 53 location-handling code. In addition, since you can send the mock data from outside your 54 production app, you don't have to disable or remove test code before you publish. 55 </li> 56 <li> 57 Since you don't have to generate test locations by moving a device, you can test an app 58 using the emulator. 59 </li> 60 </ul> 61 <p> 62 The best way to use mock locations is to send them from a separate mock location provider app. 63 This lesson includes a provider app that you can download and use to test your own software. 64 Modify the provider app as necessary to suit your own needs. Some ideas for providing test data 65 to the app are listed in the section <a href="TestData">Managing test data</a>. 66 </p> 67 <p> 68 The remainder of this lesson shows you how to turn on mock mode and use a location client to 69 send mock locations to Location Services. 70 </p> 71 <p class="note"> 72 <strong>Note:</strong> Mock locations have no effect on the activity recognition algorithm used 73 by Location Services. To learn more about activity recognition, see the lesson 74 <a href="activity-recognition.html">Recognizing the User's Current Activity</a>. 75 </p> 76 <!-- 77 Create a Test App 78 --> 79 <h2 id="TurnOnMockMode">Turn On Mock Mode</h2> 80 <p> 81 To send mock locations to Location Services in mock mode, a test app must request the permission 82 {@link android.Manifest.permission#ACCESS_MOCK_LOCATION}. In addition, you must enable mock 83 locations on the test device using the option <b>Enable mock locations</b>. To learn how to 84 enable mock locations on the device, see 85 <a href="{@docRoot}tools/device.html#setting-up">Setting up a Device for Development</a>. 86 </p> 87 <p> 88 To turn on mock mode in Location Services, start by connecting a location client to Location 89 Services, as described in the lesson 90 <a href="retrieve-current.html">Retrieving the Current Location</a>. 91 Next, call the method 92 <code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(true)</a></code>. 93 Once you call this method, Location Services turns off its internal location providers and only 94 sends out the mock locations you provide it. The following snippet shows you how to call 95 <code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(true)</a></code>: 96 </p> 97 <pre> 98 // Define a LocationClient object 99 public LocationClient mLocationClient; 100 ... 101 // Connect to Location Services 102 mLocationClient.connect(); 103 ... 104 // When the location client is connected, set mock mode 105 mLocationClinet.setMockMode(true); 106 </pre> 107 <p> 108 Once you have connected the location client to Location Services, you must keep it connected 109 until you finish sending out mock locations. Once you call 110 <code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#disconnect()">LocationClient.disconnect()</a></code>, 111 Location Services returns to using its internal location providers. To turn off mock mode while 112 the location client is connected, call 113 <code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockMode(boolean)">LocationClient.setMockMode(false)</a></code>. 114 </p> 115 <h2 id="SendMockLocations">Send Mock Locations</h2> 116 <p> 117 Once you have set mock mode, you can create mock {@link android.location.Location} objects and 118 send them to Location Services. In turn, Location Services sends these mock 119 {@link android.location.Location} objects to connected location clients. Location Services also 120 uses the mock {@link android.location.Location} objects to control geofence triggering. 121 </p> 122 <p> 123 To create a new mock {@link android.location.Location}, create a new 124 {@link android.location.Location} object using your test data. Always set the provider 125 value to {@code flp}, which is the code that Location Services puts into the 126 {@link android.location.Location} objects it sends out. The following snippet shows you how 127 to create a new mock {@link android.location.Location}: 128 </p> 129 <pre> 130 private static final String PROVIDER = "flp"; 131 private static final double LAT = 37.377166; 132 private static final double LNG = -122.086966; 133 private static final float ACCURACY = 3.0f; 134 ... 135 /* 136 * From input arguments, create a single Location with provider set to 137 * "flp" 138 */ 139 public Location createLocation(double lat, double lng, float accuracy) { 140 // Create a new Location 141 Location newLocation = new Location(PROVIDER); 142 newLocation.setLatitude(lat); 143 newLocation.setLongitude(lng); 144 newLocation.setAccuracy(accuracy); 145 return newLocation; 146 } 147 ... 148 // Example of creating a new Location from test data 149 Location testLocation = createLocation(LAT, LNG, ACCURACY); 150 </pre> 151 <p> 152 In mock mode, to send a mock location to Location Services call the method 153 <code><a href="{@docRoot}reference/com/google/android/gms/location/LocationClient.html#setMockLocation(android.location.Location)">LocationClient.setMockLocation()</a></code>. 154 For example: 155 </p> 156 <pre> 157 mLocationClient.setMockLocation(testLocation); 158 </pre> 159 <p> 160 Location Services sets this mock location as the current location, and this location is sent 161 out as the next location update. If this new mock location moves across a geofence boundary, 162 Location Services triggers the geofence. 163 </p> 164 <!-- 165 Run the Mock Location Provider 166 --> 167 <h2 id="RunProvider">Run the Mock Location Provider App</h2> 168 <p> 169 This section contains a brief overview of the mock location provider sample app 170 (available for download above) and gives you directions for testing an app using the sample app. 171 </p> 172 <h3>Overview</h3> 173 <p> 174 The mock location provider app included with this lesson sends mock 175 {@link android.location.Location} objects to Location Services from a background thread running 176 in a started {@link android.app.Service}. By using a started service, the provider app is able 177 to keep running even if the app's main {@link android.app.Activity} is destroyed because of 178 a configuration change or other system event. By using a background thread, the service is able 179 to perform a long-running test without blocking the UI thread. 180 </p> 181 <p> 182 The {@link android.app.Activity} that starts when you run the provider app allows you to 183 send test parameters to the {@link android.app.Service} and control the type of test you want. 184 You have the following options: 185 </p> 186 <dl> 187 <dt> 188 Pause before test 189 </dt> 190 <dd> 191 The number of seconds to wait before the provider app starts sending test data to Location 192 Services. This interval allows you to switch from the provider app to the app under test 193 before the testing actually starts. 194 </dd> 195 <dt> 196 Send interval 197 </dt> 198 <dd> 199 The number of seconds that the provider app waits before it sends another mock location to 200 Location Services. See the section <a href="#TestingTips">Testing Tips</a> to learn more 201 about setting the send interval. 202 </dd> 203 <dt> 204 Run once 205 </dt> 206 <dd> 207 Switch from normal mode to mock mode, run through the test data once, switch back to 208 normal mode, and then kill the {@link android.app.Service}. 209 </dd> 210 <dt> 211 Run continuously 212 </dt> 213 <dd> 214 Switch from normal mode to mock mode, then run through the test data indefinitely. The 215 background thread and the started {@link android.app.Service} continue to run, even if the 216 main {@link android.app.Activity} is destroyed. 217 </dd> 218 <dt> 219 Stop test 220 </dt> 221 <dd> 222 If a continuous test is in progress, stop it; otherwise, return a warning message. The 223 started {@link android.app.Service} switches from mock mode to normal mode and then 224 stops itself. This also stops the background thread. 225 </dd> 226 </dl> 227 <p> 228 Besides the options, the provider app has two status displays: 229 </p> 230 <dl> 231 <dt> 232 App status 233 </dt> 234 <dd> 235 Displays messages related to the lifecycle of the provider app. 236 </dd> 237 <dt> 238 Connection status 239 </dt> 240 <dd> 241 Displays messages related to the state of the location client connection. 242 </dd> 243 </dl> 244 <p> 245 While the started {@link android.app.Service} is running, it also posts notifications with the 246 testing status. These notifications allow you to see status updates even if the app is not in 247 the foreground. When you click on a notification, the main {@link android.app.Activity} of the 248 provider app returns to the foreground. 249 </p> 250 <h3>Test using the mock location provider app</h3> 251 <p> 252 To test mock location data coming from the mock location provider app: 253 </p> 254 <ol> 255 <li> 256 Install the mock location provider app on a device that has Google Play services installed. 257 Location Services is part of Google Play services. 258 </li> 259 <li> 260 On the device, enable mock locations. To learn how to do this, see the topic 261 <a href="{@docRoot}tools/device.html#setting-up">Setting up a Device for Development</a>. 262 </li> 263 <li> 264 Start the provider app from the Launcher, then choose the options you want from the main 265 screen. 266 </li> 267 <li> 268 Unless you've removed the pause interval feature, the mock location provider app 269 pauses for a few seconds, and then starts sending mock location data to Location 270 Services. 271 </li> 272 <li> 273 Run the app you want to test. While the mock location provider app is running, the app 274 you're testing receives mock locations instead of real locations. 275 </li> 276 <li> 277 If the provider app is in the midst of a continuous test, you can switch back to real 278 locations by clicking <b>Stop test</b>. This forces the started {@link android.app.Service} 279 to turn off mock mode and then stop itself. When the service stops itself, the background 280 thread is also destroyed. 281 </li> 282 283 </ol> 284 <h2 id="TestingTips">Testing Tips</h2> 285 <p> 286 The following sections contain tips for creating mock location data and using the data with a 287 mock location provider app. 288 </p> 289 <h3>Choosing a send interval</h3> 290 <p> 291 Each location provider that contributes to the fused location sent out by Location Services has 292 its own minimum update cycle. For example, the GPS provider can't send a new location more often 293 than once per second, and the Wi-Fi provider can't send a new location more often than once 294 every five seconds. These cycle times are handled automatically for real locations, but you 295 should account for them when you send mock locations. For example, you shouldn't send a new mock 296 location more than once per second. If you're testing indoor locations, which rely heavily on 297 the Wi-Fi provider, then you should consider using a send interval of five seconds. 298 </p> 299 <h3>Simulating speed</h3> 300 <p> 301 To simulate the speed of an actual device, shorten or lengthen the distance between two 302 successive locations. For example, changing the location by 88 feet every second simulates 303 car travel, because this change works out to 60 miles an hour. In comparison, changing the 304 location by 1.5 feet every second simulates brisk walking, because this change works out to 305 3 miles per hour. 306 </p> 307 <h3>Calculating location data</h3> 308 <p> 309 By searching the web, you can find a variety of small programs that calculate a new set of 310 latitude and longitude coordinates from a starting location and a distance, as well as 311 references to formulas for calculating the distance between two points based on their latitude 312 and longitude. In addition, the {@link android.location.Location} class offers two methods for 313 calculating the distance between points: 314 </p> 315 <dl> 316 <dt> 317 {@link android.location.Location#distanceBetween distanceBetween()} 318 </dt> 319 <dd> 320 A static method that calculates the distance between two points specified by latitude and 321 longitude. 322 </dd> 323 <dt> 324 {@link android.location.Location#distanceTo distanceTo()} 325 </dt> 326 <dd> 327 For a given {@link android.location.Location}, returns the distance to another 328 {@link android.location.Location}. 329 </dd> 330 </dl> 331 <h3>Geofence testing</h3> 332 <p> 333 When you test an app that uses geofence detection, use test data that reflects different modes 334 of travel, including walking, cycling, driving, and traveling by train. For a slow mode of 335 travel, make small changes in position between points. Conversely, for a fast mode of travel, 336 make a large change in position between points. 337 </p> 338 <h3 id="TestData">Managing test data</h3> 339 <p> 340 The mock location provider app included with this lesson contains test latitude, longitude, 341 and accuracy values in the form of constants. You may want to consider other ways of organizing 342 data as well: 343 </p> 344 <dl> 345 <dt> 346 XML 347 </dt> 348 <dd> 349 Store location data in XML files that are including in the provider app. By separating the 350 data from the code, you facilitate changes to the data. 351 </dd> 352 <dt> 353 Server download 354 </dt> 355 <dd> 356 Store location data on a server and then have the provider app download it. Since the data 357 is completely separate from the app, you can change the data without having to rebuild the 358 app. You can also change the data on the server and have the changes reflected immediately 359 in the mock locations you're testing. 360 </dd> 361 <dt> 362 Recorded data 363 </dt> 364 <dd> 365 Instead of making up test data, write a utility app that records location data as you move 366 the device. Use the recorded data as your test data, or use the data to guide you in 367 developing test data. For example, record locations as you walk with a device, and then 368 create mock locations that have an appropriate change in latitude and longitude over 369 time. 370 </dd> 371 </dl> 372