LocationManager.java revision 3914e4b7d12b014f73085cd6e34b6fd69ea26226
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.location; 18 19import android.app.PendingIntent; 20import android.content.Context; 21import android.content.Intent; 22import android.os.Build; 23import android.os.Bundle; 24import android.os.Looper; 25import android.os.RemoteException; 26import android.os.Handler; 27import android.os.Message; 28import android.util.Log; 29 30 31import java.util.ArrayList; 32import java.util.HashMap; 33import java.util.List; 34 35import com.android.internal.location.ProviderProperties; 36 37/** 38 * This class provides access to the system location services. These 39 * services allow applications to obtain periodic updates of the 40 * device's geographical location, or to fire an application-specified 41 * {@link Intent} when the device enters the proximity of a given 42 * geographical location. 43 * 44 * <p>You do not 45 * instantiate this class directly; instead, retrieve it through 46 * {@link android.content.Context#getSystemService 47 * Context.getSystemService(Context.LOCATION_SERVICE)}. 48 * 49 * <div class="special reference"> 50 * <h3>Developer Guides</h3> 51 * <p>For more information about using location services, read the 52 * <a href="{@docRoot}guide/topics/location/index.html">Location and Maps</a> 53 * developer guide.</p> 54 * </div> 55 */ 56public class LocationManager { 57 private static final String TAG = "LocationManager"; 58 59 private final Context mContext; 60 private final ILocationManager mService; 61 private final HashMap<GpsStatus.Listener, GpsStatusListenerTransport> mGpsStatusListeners = 62 new HashMap<GpsStatus.Listener, GpsStatusListenerTransport>(); 63 private final HashMap<GpsStatus.NmeaListener, GpsStatusListenerTransport> mNmeaListeners = 64 new HashMap<GpsStatus.NmeaListener, GpsStatusListenerTransport>(); 65 private final GpsStatus mGpsStatus = new GpsStatus(); 66 67 /** 68 * Name of the network location provider. This provider determines location based on 69 * availability of cell tower and WiFi access points. Results are retrieved 70 * by means of a network lookup. 71 * 72 * Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION 73 * or android.permission.ACCESS_FINE_LOCATION. 74 * @deprecated use the {@link Criteria} class instead 75 */ 76 @Deprecated 77 public static final String NETWORK_PROVIDER = "network"; 78 79 /** 80 * Name of the GPS location provider. This provider determines location using 81 * satellites. Depending on conditions, this provider may take a while to return 82 * a location fix. 83 * 84 * Requires the permission android.permission.ACCESS_FINE_LOCATION. 85 * 86 * <p> The extras Bundle for the GPS location provider can contain the 87 * following key/value pairs: 88 * 89 * <ul> 90 * <li> satellites - the number of satellites used to derive the fix 91 * </ul> 92 * @deprecated use the {@link Criteria} class instead 93 */ 94 @Deprecated 95 public static final String GPS_PROVIDER = "gps"; 96 97 /** 98 * A special location provider for receiving locations without actually initiating 99 * a location fix. This provider can be used to passively receive location updates 100 * when other applications or services request them without actually requesting 101 * the locations yourself. This provider will return locations generated by other 102 * providers. You can query the {@link Location#getProvider()} method to determine 103 * the origin of the location update. 104 * 105 * Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS 106 * is not enabled this provider might only return coarse fixes. 107 * @deprecated use the {@link Criteria} class instead 108 */ 109 @Deprecated 110 public static final String PASSIVE_PROVIDER = "passive"; 111 112 /** 113 * Name of the Fused location provider.<p> 114 * This provider combines inputs for all possible location sources 115 * to provide the best possible Location fix.<p> 116 * 117 * Requires the permission android.permission.ACCESS_FINE_LOCATION. 118 * @hide 119 */ 120 public static final String FUSED_PROVIDER = "fused"; 121 122 /** 123 * Key used for the Bundle extra holding a boolean indicating whether 124 * a proximity alert is entering (true) or exiting (false).. 125 */ 126 public static final String KEY_PROXIMITY_ENTERING = "entering"; 127 128 /** 129 * Key used for a Bundle extra holding an Integer status value 130 * when a status change is broadcast using a PendingIntent. 131 * @deprecated use the {@link Criteria} class instead 132 */ 133 @Deprecated 134 public static final String KEY_STATUS_CHANGED = "status"; 135 136 /** 137 * Key used for a Bundle extra holding an Boolean status value 138 * when a provider enabled/disabled event is broadcast using a PendingIntent. 139 * @deprecated use the {@link Criteria} class instead 140 */ 141 @Deprecated 142 public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; 143 144 /** 145 * Key used for a Bundle extra holding a Location value 146 * when a location change is broadcast using a PendingIntent. 147 */ 148 public static final String KEY_LOCATION_CHANGED = "location"; 149 150 /** 151 * Broadcast intent action indicating that the GPS has either been 152 * enabled or disabled. An intent extra provides this state as a boolean, 153 * where {@code true} means enabled. 154 * @see #EXTRA_GPS_ENABLED 155 * 156 * {@hide} 157 */ 158 public static final String GPS_ENABLED_CHANGE_ACTION = 159 "android.location.GPS_ENABLED_CHANGE"; 160 161 /** 162 * Broadcast intent action when the configured location providers 163 * change. 164 * @deprecated use the {@link Criteria} class instead 165 */ 166 @Deprecated 167 public static final String PROVIDERS_CHANGED_ACTION = 168 "android.location.PROVIDERS_CHANGED"; 169 170 /** 171 * Broadcast intent action indicating that the GPS has either started or 172 * stopped receiving GPS fixes. An intent extra provides this state as a 173 * boolean, where {@code true} means that the GPS is actively receiving fixes. 174 * @see #EXTRA_GPS_ENABLED 175 * 176 * {@hide} 177 */ 178 public static final String GPS_FIX_CHANGE_ACTION = 179 "android.location.GPS_FIX_CHANGE"; 180 181 /** 182 * The lookup key for a boolean that indicates whether GPS is enabled or 183 * disabled. {@code true} means GPS is enabled. Retrieve it with 184 * {@link android.content.Intent#getBooleanExtra(String,boolean)}. 185 * 186 * {@hide} 187 */ 188 public static final String EXTRA_GPS_ENABLED = "enabled"; 189 190 // Map from LocationListeners to their associated ListenerTransport objects 191 private HashMap<LocationListener,ListenerTransport> mListeners = 192 new HashMap<LocationListener,ListenerTransport>(); 193 194 private class ListenerTransport extends ILocationListener.Stub { 195 private static final int TYPE_LOCATION_CHANGED = 1; 196 private static final int TYPE_STATUS_CHANGED = 2; 197 private static final int TYPE_PROVIDER_ENABLED = 3; 198 private static final int TYPE_PROVIDER_DISABLED = 4; 199 200 private LocationListener mListener; 201 private final Handler mListenerHandler; 202 203 ListenerTransport(LocationListener listener, Looper looper) { 204 mListener = listener; 205 206 if (looper == null) { 207 mListenerHandler = new Handler() { 208 @Override 209 public void handleMessage(Message msg) { 210 _handleMessage(msg); 211 } 212 }; 213 } else { 214 mListenerHandler = new Handler(looper) { 215 @Override 216 public void handleMessage(Message msg) { 217 _handleMessage(msg); 218 } 219 }; 220 } 221 } 222 223 @Override 224 public void onLocationChanged(Location location) { 225 Message msg = Message.obtain(); 226 msg.what = TYPE_LOCATION_CHANGED; 227 msg.obj = location; 228 mListenerHandler.sendMessage(msg); 229 } 230 231 @Override 232 public void onStatusChanged(String provider, int status, Bundle extras) { 233 Message msg = Message.obtain(); 234 msg.what = TYPE_STATUS_CHANGED; 235 Bundle b = new Bundle(); 236 b.putString("provider", provider); 237 b.putInt("status", status); 238 if (extras != null) { 239 b.putBundle("extras", extras); 240 } 241 msg.obj = b; 242 mListenerHandler.sendMessage(msg); 243 } 244 245 @Override 246 public void onProviderEnabled(String provider) { 247 Message msg = Message.obtain(); 248 msg.what = TYPE_PROVIDER_ENABLED; 249 msg.obj = provider; 250 mListenerHandler.sendMessage(msg); 251 } 252 253 @Override 254 public void onProviderDisabled(String provider) { 255 Message msg = Message.obtain(); 256 msg.what = TYPE_PROVIDER_DISABLED; 257 msg.obj = provider; 258 mListenerHandler.sendMessage(msg); 259 } 260 261 private void _handleMessage(Message msg) { 262 switch (msg.what) { 263 case TYPE_LOCATION_CHANGED: 264 Location location = new Location((Location) msg.obj); 265 mListener.onLocationChanged(location); 266 break; 267 case TYPE_STATUS_CHANGED: 268 Bundle b = (Bundle) msg.obj; 269 String provider = b.getString("provider"); 270 int status = b.getInt("status"); 271 Bundle extras = b.getBundle("extras"); 272 mListener.onStatusChanged(provider, status, extras); 273 break; 274 case TYPE_PROVIDER_ENABLED: 275 mListener.onProviderEnabled((String) msg.obj); 276 break; 277 case TYPE_PROVIDER_DISABLED: 278 mListener.onProviderDisabled((String) msg.obj); 279 break; 280 } 281 try { 282 mService.locationCallbackFinished(this); 283 } catch (RemoteException e) { 284 Log.e(TAG, "locationCallbackFinished: RemoteException", e); 285 } 286 } 287 } 288 /** 289 * @hide - hide this constructor because it has a parameter 290 * of type ILocationManager, which is a system private class. The 291 * right way to create an instance of this class is using the 292 * factory Context.getSystemService. 293 */ 294 public LocationManager(Context context, ILocationManager service) { 295 mService = service; 296 mContext = context; 297 } 298 299 private LocationProvider createProvider(String name, ProviderProperties properties) { 300 return new LocationProvider(name, properties); 301 } 302 303 /** 304 * Returns a list of the names of all known location providers. All 305 * providers are returned, including ones that are not permitted to be 306 * accessed by the calling activity or are currently disabled. 307 * 308 * @return list of Strings containing names of the providers 309 * @deprecated use the {@link Criteria} class instead 310 */ 311 @Deprecated 312 public List<String> getAllProviders() { 313 try { 314 return mService.getAllProviders(); 315 } catch (RemoteException e) { 316 Log.e(TAG, "RemoteException", e); 317 } 318 return null; 319 } 320 321 /** 322 * Returns a list of the names of location providers. Only providers that 323 * are permitted to be accessed by the calling activity will be returned. 324 * 325 * @param enabledOnly if true then only the providers which are currently 326 * enabled are returned. 327 * @return list of Strings containing names of the providers 328 * @deprecated The {@link LocationProvider} class is deprecated. So 329 * use the {@link Criteria} class to request location instead of 330 * enumerating providers. 331 */ 332 @Deprecated 333 public List<String> getProviders(boolean enabledOnly) { 334 try { 335 return mService.getProviders(null, enabledOnly); 336 } catch (RemoteException e) { 337 Log.e(TAG, "RemoteException", e); 338 } 339 return null; 340 } 341 342 /** 343 * Returns the information associated with the location provider of the 344 * given name, or null if no provider exists by that name. 345 * 346 * @param name the provider name 347 * @return a LocationProvider, or null 348 * 349 * @throws IllegalArgumentException if name is null or does not exisit 350 * @throws SecurityException if the caller is not permitted to access the 351 * given provider. 352 * @deprecated The {@link LocationProvider} class is deprecated. So 353 * use the {@link Criteria} class to request location instead of 354 * enumerating providers. 355 */ 356 @Deprecated 357 public LocationProvider getProvider(String name) { 358 checkProvider(name); 359 try { 360 ProviderProperties properties = mService.getProviderProperties(name); 361 if (properties == null) { 362 return null; 363 } 364 return createProvider(name, properties); 365 } catch (RemoteException e) { 366 Log.e(TAG, "RemoteException", e); 367 } 368 return null; 369 } 370 371 /** 372 * Returns a list of the names of LocationProviders that satisfy the given 373 * criteria, or null if none do. Only providers that are permitted to be 374 * accessed by the calling activity will be returned. 375 * 376 * @param criteria the criteria that the returned providers must match 377 * @param enabledOnly if true then only the providers which are currently 378 * enabled are returned. 379 * @return list of Strings containing names of the providers 380 * @deprecated The {@link LocationProvider} class is deprecated. So 381 * use the {@link Criteria} class to request location instead of 382 * enumerating providers. 383 */ 384 @Deprecated 385 public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 386 checkCriteria(criteria); 387 try { 388 return mService.getProviders(criteria, enabledOnly); 389 } catch (RemoteException e) { 390 Log.e(TAG, "RemoteException", e); 391 } 392 return null; 393 } 394 395 /** 396 * Returns the name of the provider that best meets the given criteria. Only providers 397 * that are permitted to be accessed by the calling activity will be 398 * returned. If several providers meet the criteria, the one with the best 399 * accuracy is returned. If no provider meets the criteria, 400 * the criteria are loosened in the following sequence: 401 * 402 * <ul> 403 * <li> power requirement 404 * <li> accuracy 405 * <li> bearing 406 * <li> speed 407 * <li> altitude 408 * </ul> 409 * 410 * <p> Note that the requirement on monetary cost is not removed 411 * in this process. 412 * 413 * @param criteria the criteria that need to be matched 414 * @param enabledOnly if true then only a provider that is currently enabled is returned 415 * @return name of the provider that best matches the requirements 416 * @deprecated using an explicit provider doesn't allow fused location 417 */ 418 @Deprecated 419 public String getBestProvider(Criteria criteria, boolean enabledOnly) { 420 checkCriteria(criteria); 421 try { 422 return mService.getBestProvider(criteria, enabledOnly); 423 } catch (RemoteException e) { 424 Log.e(TAG, "RemoteException", e); 425 } 426 return null; 427 } 428 429 /** 430 * Registers the current activity to be notified periodically by 431 * the named provider. Periodically, the supplied LocationListener will 432 * be called with the current Location or with status updates. 433 * 434 * <p> It may take a while to receive the first location update. If 435 * an immediate location is required, applications may use the 436 * {@link #getLastKnownLocation(String)} method. 437 * 438 * <p> In case the provider is disabled by the user, updates will stop, 439 * and the {@link LocationListener#onProviderDisabled(String)} 440 * method will be called. As soon as the provider is enabled again, 441 * the {@link LocationListener#onProviderEnabled(String)} method will 442 * be called and location updates will start again. 443 * 444 * <p> The update interval can be controlled using the minTime parameter. 445 * The elapsed time between location updates will never be less than 446 * minTime, although it can be more depending on the Location Provider 447 * implementation and the update interval requested by other applications. 448 * 449 * <p> Choosing a sensible value for minTime is important to conserve 450 * battery life. Each location update requires power from 451 * GPS, WIFI, Cell and other radios. Select a minTime value as high as 452 * possible while still providing a reasonable user experience. 453 * If your application is not in the foreground and showing 454 * location to the user then your application should avoid using an active 455 * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), 456 * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) 457 * or greater. If your application is in the foreground and showing 458 * location to the user then it is appropriate to select a faster 459 * update interval. 460 * 461 * <p> The minDistance parameter can also be used to control the 462 * frequency of location updates. If it is greater than 0 then the 463 * location provider will only send your application an update when 464 * the location has changed by at least minDistance meters, AND 465 * at least minTime milliseconds have passed. However it is more 466 * difficult for location providers to save power using the minDistance 467 * parameter, so minTime should be the primary tool to conserving battery 468 * life. 469 * 470 * <p> If your application wants to passively observe location 471 * updates triggered by other applications, but not consume 472 * any additional power otherwise, then use the {@link #PASSIVE_PROVIDER} 473 * This provider does not actively turn on or modify active location 474 * providers, so you do not need to be as careful about minTime and 475 * minDistance. However if your application performs heavy work 476 * on a location update (such as network activity) then you should 477 * select non-zero values for minTime and/or minDistance to rate-limit 478 * your update frequency in the case another application enables a 479 * location provider with extremely fast updates. 480 * 481 * <p> The calling thread must be a {@link android.os.Looper} thread such as 482 * the main thread of the calling Activity. 483 * 484 * <p class="note"> Prior to Jellybean, the minTime parameter was 485 * only a hint, and some location provider implementations ignored it. 486 * From Jellybean and onwards it is mandatory for Android compatible 487 * devices to observe both the minTime and minDistance parameters. 488 * 489 * @param provider the name of the provider with which to register 490 * @param minTime minimum time interval between location updates, in milliseconds 491 * @param minDistance minimum distance between location updates, in meters 492 * @param listener a {#link LocationListener} whose 493 * {@link LocationListener#onLocationChanged} method will be called for 494 * each location update 495 * 496 * @throws IllegalArgumentException if provider is null or doesn't exist 497 * on this device 498 * @throws IllegalArgumentException if listener is null 499 * @throws RuntimeException if the calling thread has no Looper 500 * @throws SecurityException if no suitable permission is present for the provider. 501 * @deprecated use the {@link LocationRequest} class instead 502 */ 503 @Deprecated 504 public void requestLocationUpdates(String provider, long minTime, float minDistance, 505 LocationListener listener) { 506 checkProvider(provider); 507 checkListener(listener); 508 509 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 510 provider, minTime, minDistance, false); 511 requestLocationUpdates(request, listener, null, null); 512 } 513 514 /** 515 * Registers the current activity to be notified periodically by 516 * the named provider. Periodically, the supplied LocationListener will 517 * be called with the current Location or with status updates. 518 * 519 * <p> It may take a while to receive the first location update. If 520 * an immediate location is required, applications may use the 521 * {@link #getLastKnownLocation(String)} method. 522 * 523 * <p> In case the provider is disabled by the user, updates will stop, 524 * and the {@link LocationListener#onProviderDisabled(String)} 525 * method will be called. As soon as the provider is enabled again, 526 * the {@link LocationListener#onProviderEnabled(String)} method will 527 * be called and location updates will start again. 528 * 529 * <p> The update interval can be controlled using the minTime parameter. 530 * The elapsed time between location updates will never be less than 531 * minTime, although it can be more depending on the Location Provider 532 * implementation and the update interval requested by other applications. 533 * 534 * <p> Choosing a sensible value for minTime is important to conserve 535 * battery life. Each location update requires power from 536 * GPS, WIFI, Cell and other radios. Select a minTime value as high as 537 * possible while still providing a reasonable user experience. 538 * If your application is not in the foreground and showing 539 * location to the user then your application should avoid using an active 540 * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), 541 * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) 542 * or greater. If your application is in the foreground and showing 543 * location to the user then it is appropriate to select a faster 544 * update interval. 545 * 546 * <p> The minDistance parameter can also be used to control the 547 * frequency of location updates. If it is greater than 0 then the 548 * location provider will only send your application an update when 549 * the location has changed by at least minDistance meters, AND 550 * at least minTime milliseconds have passed. However it is more 551 * difficult for location providers to save power using the minDistance 552 * parameter, so minTime should be the primary tool to conserving battery 553 * life. 554 * 555 * <p> If your application wants to passively observe location 556 * updates triggered by other applications, but not consume 557 * any additional power otherwise, then use the {@link #PASSIVE_PROVIDER} 558 * This provider does not actively turn on or modify active location 559 * providers, so you do not need to be as careful about minTime and 560 * minDistance. However if your application performs heavy work 561 * on a location update (such as network activity) then you should 562 * select non-zero values for minTime and/or minDistance to rate-limit 563 * your update frequency in the case another application enables a 564 * location provider with extremely fast updates. 565 * 566 * <p> The supplied Looper is used to implement the callback mechanism. 567 * 568 * <p class="note"> Prior to Jellybean, the minTime parameter was 569 * only a hint, and some location provider implementations ignored it. 570 * From Jellybean and onwards it is mandatory for Android compatible 571 * devices to observe both the minTime and minDistance parameters. 572 * 573 * @param provider the name of the provider with which to register 574 * @param minTime minimum time interval between location updates, in milliseconds 575 * @param minDistance minimum distance between location updates, in meters 576 * @param listener a {#link LocationListener} whose 577 * {@link LocationListener#onLocationChanged} method will be called for 578 * each location update 579 * @param looper a Looper object whose message queue will be used to 580 * implement the callback mechanism, or null to make callbacks on the 581 * main thread 582 * 583 * @throws IllegalArgumentException if provider is null or doesn't exist 584 * @throws IllegalArgumentException if listener is null 585 * @throws SecurityException if no suitable permission is present for the provider. 586 * @deprecated use the {@link LocationRequest} class instead 587 */ 588 @Deprecated 589 public void requestLocationUpdates(String provider, long minTime, float minDistance, 590 LocationListener listener, Looper looper) { 591 checkProvider(provider); 592 checkListener(listener); 593 594 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 595 provider, minTime, minDistance, false); 596 requestLocationUpdates(request, listener, looper, null); 597 } 598 599 /** 600 * Registers the current activity to be notified periodically based on 601 * the supplied criteria. Periodically, the supplied LocationListener will 602 * be called with the current Location or with status updates. 603 * 604 * <p> It may take a while to receive the first location update. If 605 * an immediate location is required, applications may use the 606 * {@link #getLastKnownLocation(String)} method. 607 * 608 * <p> In case the provider is disabled by the user, updates will stop, 609 * and the {@link LocationListener#onProviderDisabled(String)} 610 * method will be called. As soon as the provider is enabled again, 611 * the {@link LocationListener#onProviderEnabled(String)} method will 612 * be called and location updates will start again. 613 * 614 * <p> The update interval can be controlled using the minTime parameter. 615 * The elapsed time between location updates will never be less than 616 * minTime, although it can be more depending on the Location Provider 617 * implementation and the update interval requested by other applications. 618 * 619 * <p> Choosing a sensible value for minTime is important to conserve 620 * battery life. Each location update requires power from 621 * GPS, WIFI, Cell and other radios. Select a minTime value as high as 622 * possible while still providing a reasonable user experience. 623 * If your application is not in the foreground and showing 624 * location to the user then your application should avoid using an active 625 * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), 626 * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) 627 * or greater. If your application is in the foreground and showing 628 * location to the user then it is appropriate to select a faster 629 * update interval. 630 * 631 * <p> The minDistance parameter can also be used to control the 632 * frequency of location updates. If it is greater than 0 then the 633 * location provider will only send your application an update when 634 * the location has changed by at least minDistance meters, AND 635 * at least minTime milliseconds have passed. However it is more 636 * difficult for location providers to save power using the minDistance 637 * parameter, so minTime should be the primary tool to conserving battery 638 * life. 639 * 640 * <p> The supplied Looper is used to implement the callback mechanism. 641 * 642 * <p class="note"> Prior to Jellybean, the minTime parameter was 643 * only a hint, and some location provider implementations ignored it. 644 * From Jellybean and onwards it is mandatory for Android compatible 645 * devices to observe both the minTime and minDistance parameters. 646 * 647 * @param minTime minimum time interval between location updates, in milliseconds 648 * @param minDistance minimum distance between location updates, in meters 649 * @param criteria contains parameters for the location manager to choose the 650 * appropriate provider and parameters to compute the location 651 * @param listener a {#link LocationListener} whose 652 * {@link LocationListener#onLocationChanged} method will be called for 653 * each location update 654 * @param looper a Looper object whose message queue will be used to 655 * implement the callback mechanism, or null to make callbacks on the 656 * main thread. 657 * 658 * @throws IllegalArgumentException if criteria is null 659 * @throws IllegalArgumentException if listener is null 660 * @throws SecurityException if no suitable permission is present for the provider. 661 * @deprecated use the {@link LocationRequest} class instead 662 */ 663 @Deprecated 664 public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, 665 LocationListener listener, Looper looper) { 666 checkCriteria(criteria); 667 checkListener(listener); 668 669 LocationRequest request = LocationRequest.createFromDeprecatedCriteria( 670 criteria, minTime, minDistance, false); 671 requestLocationUpdates(request, listener, looper, null); 672 } 673 674 /** 675 * Registers the current activity to be notified periodically by 676 * the named provider. Periodically, the supplied PendingIntent will 677 * be broadcast with the current Location or with status updates. 678 * 679 * <p> Location updates are sent with a key of 680 * {@link #KEY_LOCATION_CHANGED} and a {@link android.location.Location} value. 681 * 682 * <p> It may take a while to receive the first location update. If 683 * an immediate location is required, applications may use the 684 * {@link #getLastKnownLocation(String)} method. 685 * 686 * <p> The update interval can be controlled using the minTime parameter. 687 * The elapsed time between location updates will never be less than 688 * minTime, although it can be more depending on the Location Provider 689 * implementation and the update interval requested by other applications. 690 * 691 * <p> Choosing a sensible value for minTime is important to conserve 692 * battery life. Each location update requires power from 693 * GPS, WIFI, Cell and other radios. Select a minTime value as high as 694 * possible while still providing a reasonable user experience. 695 * If your application is not in the foreground and showing 696 * location to the user then your application should avoid using an active 697 * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), 698 * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) 699 * or greater. If your application is in the foreground and showing 700 * location to the user then it is appropriate to select a faster 701 * update interval. 702 * 703 * <p> The minDistance parameter can also be used to control the 704 * frequency of location updates. If it is greater than 0 then the 705 * location provider will only send your application an update when 706 * the location has changed by at least minDistance meters, AND 707 * at least minTime milliseconds have passed. However it is more 708 * difficult for location providers to save power using the minDistance 709 * parameter, so minTime should be the primary tool to conserving battery 710 * life. 711 * 712 * <p> If your application wants to passively observe location 713 * updates triggered by other applications, but not consume 714 * any additional power otherwise, then use the {@link #PASSIVE_PROVIDER} 715 * This provider does not actively turn on or modify active location 716 * providers, so you do not need to be as careful about minTime and 717 * minDistance. However if your application performs heavy work 718 * on a location update (such as network activity) then you should 719 * select non-zero values for minTime and/or minDistance to rate-limit 720 * your update frequency in the case another application enables a 721 * location provider with extremely fast updates. 722 * 723 * <p> If the provider is disabled by the user, updates will stop, 724 * and an intent will be sent with an extra with key 725 * {@link #KEY_PROVIDER_ENABLED} and a boolean value of false. 726 * If the provider is re-enabled, an intent will be sent with an 727 * extra with key {@link #KEY_PROVIDER_ENABLED} and a boolean value of 728 * true and location updates will start again. 729 * 730 * <p> If the provider's status changes, an intent will be sent with 731 * an extra with key {@link #KEY_STATUS_CHANGED} and an integer value 732 * indicating the new status. Any extras associated with the status 733 * update will be sent as well. 734 * 735 * <p class="note"> Prior to Jellybean, the minTime parameter was 736 * only a hint, and some location provider implementations ignored it. 737 * From Jellybean and onwards it is mandatory for Android compatible 738 * devices to observe both the minTime and minDistance parameters. 739 * 740 * @param provider the name of the provider with which to register 741 * @param minTime minimum time interval between location updates, in milliseconds 742 * @param minDistance minimum distance between location updates, in meters 743 * @param intent a {#link PendingIntent} to be sent for each location update 744 * 745 * @throws IllegalArgumentException if provider is null or doesn't exist 746 * on this device 747 * @throws IllegalArgumentException if intent is null 748 * @throws SecurityException if no suitable permission is present for the provider. 749 * @deprecated use the {@link LocationRequest} class instead 750 */ 751 @Deprecated 752 public void requestLocationUpdates(String provider, long minTime, float minDistance, 753 PendingIntent intent) { 754 checkProvider(provider); 755 checkPendingIntent(intent); 756 757 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 758 provider, minTime, minDistance, false); 759 requestLocationUpdates(request, null, null, intent); 760 } 761 762 /** 763 * Registers the current activity to be notified periodically based on 764 * the supplied criteria. Periodically, the supplied PendingIntent will 765 * be broadcast with the current Location or with status updates. 766 * 767 * <p> Location updates are sent with a key of 768 * {@link #KEY_LOCATION_CHANGED} and a {@link android.location.Location} value. 769 * 770 * <p> It may take a while to receive the first location update. If 771 * an immediate location is required, applications may use the 772 * {@link #getLastKnownLocation(String)} method. 773 * 774 * <p> The update interval can be controlled using the minTime parameter. 775 * The elapsed time between location updates will never be less than 776 * minTime, although it can be more depending on the Location Provider 777 * implementation and the update interval requested by other applications. 778 * 779 * <p> Choosing a sensible value for minTime is important to conserve 780 * battery life. Each location update requires power from 781 * GPS, WIFI, Cell and other radios. Select a minTime value as high as 782 * possible while still providing a reasonable user experience. 783 * If your application is not in the foreground and showing 784 * location to the user then your application should avoid using an active 785 * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}), 786 * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes) 787 * or greater. If your application is in the foreground and showing 788 * location to the user then it is appropriate to select a faster 789 * update interval. 790 * 791 * <p> The minDistance parameter can also be used to control the 792 * frequency of location updates. If it is greater than 0 then the 793 * location provider will only send your application an update when 794 * the location has changed by at least minDistance meters, AND 795 * at least minTime milliseconds have passed. However it is more 796 * difficult for location providers to save power using the minDistance 797 * parameter, so minTime should be the primary tool to conserving battery 798 * life. 799 * 800 * <p> If the provider is disabled by the user, updates will stop, 801 * and an intent will be sent with an extra with key 802 * {@link #KEY_PROVIDER_ENABLED} and a boolean value of false. 803 * If the provider is re-enabled, an intent will be sent with an 804 * extra with key {@link #KEY_PROVIDER_ENABLED} and a boolean value of 805 * true and location updates will start again. 806 * 807 * <p> If the provider's status changes, an intent will be sent with 808 * an extra with key {@link #KEY_STATUS_CHANGED} and an integer value 809 * indicating the new status. Any extras associated with the status 810 * update will be sent as well. 811 * 812 * <p class="note"> Prior to Jellybean, the minTime parameter was 813 * only a hint, and some location provider implementations ignored it. 814 * From Jellybean and onwards it is mandatory for Android compatible 815 * devices to observe both the minTime and minDistance parameters. 816 * 817 * @param minTime minimum time interval between location updates, in milliseconds 818 * @param minDistance minimum distance between location updates, in meters 819 * @param criteria contains parameters for the location manager to choose the 820 * appropriate provider and parameters to compute the location 821 * @param intent a {#link PendingIntent} to be sent for each location update 822 * 823 * @throws IllegalArgumentException if criteria is null 824 * @throws IllegalArgumentException if intent is null 825 * @throws SecurityException if no suitable permission is present for the provider. 826 * @deprecated use the {@link LocationRequest} class instead 827 */ 828 @Deprecated 829 public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, 830 PendingIntent intent) { 831 checkCriteria(criteria); 832 checkPendingIntent(intent); 833 834 LocationRequest request = LocationRequest.createFromDeprecatedCriteria( 835 criteria, minTime, minDistance, false); 836 requestLocationUpdates(request, null, null, intent); 837 } 838 839 /** 840 * Requests a single location update from the named provider. 841 * 842 * <p> It may take a while to receive the most recent location. If 843 * an immediate location is required, applications may use the 844 * {@link #getLastKnownLocation(String)} method. 845 * 846 * <p> In case the provider is disabled by the user, the update will not be received, 847 * and the {@link LocationListener#onProviderDisabled(String)} 848 * method will be called. As soon as the provider is enabled again, 849 * the {@link LocationListener#onProviderEnabled(String)} method will 850 * be called and location updates will start again. 851 * 852 * <p> The supplied Looper is used to implement the callback mechanism. 853 * 854 * @param provider the name of the provider with which to register 855 * @param listener a {#link LocationListener} whose 856 * {@link LocationListener#onLocationChanged} method will be called when 857 * the location update is available 858 * @param looper a Looper object whose message queue will be used to 859 * implement the callback mechanism, or null to make callbacks on the 860 * main thread 861 * 862 * @throws IllegalArgumentException if provider is null or doesn't exist 863 * @throws IllegalArgumentException if listener is null 864 * @throws SecurityException if no suitable permission is present for the provider 865 * @deprecated use the {@link LocationRequest} class instead 866 */ 867 @Deprecated 868 public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) { 869 checkProvider(provider); 870 checkListener(listener); 871 872 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 873 provider, 0, 0, true); 874 requestLocationUpdates(request, listener, looper, null); 875 } 876 877 /** 878 * Requests a single location update based on the specified criteria. 879 * 880 * <p> It may take a while to receive the most recent location. If 881 * an immediate location is required, applications may use the 882 * {@link #getLastKnownLocation(String)} method. 883 * 884 * <p> In case the provider is disabled by the user, the update will not be received, 885 * and the {@link LocationListener#onProviderDisabled(String)} 886 * method will be called. As soon as the provider is enabled again, 887 * the {@link LocationListener#onProviderEnabled(String)} method will 888 * be called and location updates will start again. 889 * 890 * <p> The supplied Looper is used to implement the callback mechanism. 891 * 892 * @param criteria contains parameters for the location manager to choose the 893 * appropriate provider and parameters to compute the location 894 * @param listener a {#link LocationListener} whose 895 * {@link LocationListener#onLocationChanged} method will be called when 896 * the location update is available 897 * @param looper a Looper object whose message queue will be used to 898 * implement the callback mechanism, or null to make callbacks on the 899 * main thread 900 * 901 * @throws IllegalArgumentException if criteria is null 902 * @throws IllegalArgumentException if listener is null 903 * @throws SecurityException if no suitable permission is present to access 904 * the location services 905 * @deprecated use the {@link LocationRequest} class instead 906 */ 907 @Deprecated 908 public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) { 909 checkCriteria(criteria); 910 checkListener(listener); 911 912 LocationRequest request = LocationRequest.createFromDeprecatedCriteria( 913 criteria, 0, 0, true); 914 requestLocationUpdates(request, listener, looper, null); 915 } 916 917 /** 918 * Requests a single location update from the named provider. 919 * 920 * <p> It may take a while to receive the most recent location. If 921 * an immediate location is required, applications may use the 922 * {@link #getLastKnownLocation(String)} method. 923 * 924 * <p> Location updates are sent with a key of 925 * {@link #KEY_LOCATION_CHANGED} and a {@link android.location.Location} value. 926 * 927 * <p> In case the provider is disabled by the user, the update will not be received, 928 * and the {@link LocationListener#onProviderDisabled(String)} 929 * method will be called. As soon as the provider is enabled again, 930 * the {@link LocationListener#onProviderEnabled(String)} method will 931 * be called and location updates will start again. 932 * 933 * @param provider the name of the provider with which to register 934 * @param intent a {#link PendingIntent} to be sent for the location update 935 * 936 * @throws IllegalArgumentException if provider is null or doesn't exist 937 * @throws IllegalArgumentException if intent is null 938 * @throws SecurityException if no suitable permission is present for the provider 939 * @deprecated use the {@link LocationRequest} class instead 940 */ 941 @Deprecated 942 public void requestSingleUpdate(String provider, PendingIntent intent) { 943 checkProvider(provider); 944 checkPendingIntent(intent); 945 946 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 947 provider, 0, 0, true); 948 requestLocationUpdates(request, null, null, intent); 949 } 950 951 /** 952 * Requests a single location update based on the specified criteria. 953 * 954 * <p> It may take a while to receive the most recent location. If 955 * an immediate location is required, applications may use the 956 * {@link #getLastKnownLocation(String)} method. 957 * 958 * <p> Location updates are sent with a key of 959 * {@link #KEY_LOCATION_CHANGED} and a {@link android.location.Location} value. 960 * 961 * <p> If the provider is disabled by the user, an update will not be 962 * received, and an intent will be sent with an extra with key 963 * {@link #KEY_PROVIDER_ENABLED} and a boolean value of false. 964 * If the provider is re-enabled, an intent will be sent with an 965 * extra with key {@link #KEY_PROVIDER_ENABLED} and a boolean value of 966 * true and the location update will occur. 967 * 968 * @param criteria contains parameters for the location manager to choose the 969 * appropriate provider and parameters to compute the location 970 * @param intent a {#link PendingIntent} to be sent for the location update 971 * 972 * @throws IllegalArgumentException if provider is null or doesn't exist 973 * @throws IllegalArgumentException if intent is null 974 * @throws SecurityException if no suitable permission is present for the provider 975 * @deprecated use the {@link LocationRequest} class instead 976 */ 977 @Deprecated 978 public void requestSingleUpdate(Criteria criteria, PendingIntent intent) { 979 checkCriteria(criteria); 980 checkPendingIntent(intent); 981 982 LocationRequest request = LocationRequest.createFromDeprecatedCriteria( 983 criteria, 0, 0, true); 984 requestLocationUpdates(request, null, null, intent); 985 } 986 987 public void requestLocationUpdates(LocationRequest request, LocationListener listener, 988 Looper looper) { 989 checkListener(listener); 990 requestLocationUpdates(request, listener, looper, null); 991 } 992 993 public void requestLocationUpdates(LocationRequest request, PendingIntent intent) { 994 checkPendingIntent(intent); 995 requestLocationUpdates(request, null, null, intent); 996 } 997 998 private ListenerTransport wrapListener(LocationListener listener, Looper looper) { 999 if (listener == null) return null; 1000 synchronized (mListeners) { 1001 ListenerTransport transport = mListeners.get(listener); 1002 if (transport == null) { 1003 transport = new ListenerTransport(listener, looper); 1004 } 1005 mListeners.put(listener, transport); 1006 return transport; 1007 } 1008 } 1009 1010 private void requestLocationUpdates(LocationRequest request, LocationListener listener, 1011 Looper looper, PendingIntent intent) { 1012 1013 String packageName = mContext.getPackageName(); 1014 1015 // wrap the listener class 1016 ListenerTransport transport = wrapListener(listener, looper); 1017 1018 try { 1019 mService.requestLocationUpdates(request, transport, intent, packageName); 1020 } catch (RemoteException e) { 1021 Log.e(TAG, "RemoteException", e); 1022 } 1023 } 1024 1025 /** 1026 * Removes any current registration for location updates of the current activity 1027 * with the given LocationListener. Following this call, updates will no longer 1028 * occur for this listener. 1029 * 1030 * @param listener {#link LocationListener} object that no longer needs location updates 1031 * @throws IllegalArgumentException if listener is null 1032 */ 1033 public void removeUpdates(LocationListener listener) { 1034 checkListener(listener); 1035 String packageName = mContext.getPackageName(); 1036 1037 ListenerTransport transport; 1038 synchronized (mListeners) { 1039 transport = mListeners.remove(listener); 1040 } 1041 if (transport == null) return; 1042 1043 try { 1044 mService.removeUpdates(transport, null, packageName); 1045 } catch (RemoteException e) { 1046 Log.e(TAG, "RemoteException", e); 1047 } 1048 } 1049 1050 /** 1051 * Removes any current registration for location updates of the current activity 1052 * with the given PendingIntent. Following this call, updates will no longer 1053 * occur for this intent. 1054 * 1055 * @param intent {#link PendingIntent} object that no longer needs location updates 1056 * @throws IllegalArgumentException if intent is null 1057 */ 1058 public void removeUpdates(PendingIntent intent) { 1059 checkPendingIntent(intent); 1060 String packageName = mContext.getPackageName(); 1061 1062 try { 1063 mService.removeUpdates(null, intent, packageName); 1064 } catch (RemoteException e) { 1065 Log.e(TAG, "RemoteException", e); 1066 } 1067 } 1068 1069 /** 1070 * Sets a proximity alert for the location given by the position 1071 * (latitude, longitude) and the given radius. When the device 1072 * detects that it has entered or exited the area surrounding the 1073 * location, the given PendingIntent will be used to create an Intent 1074 * to be fired. 1075 * 1076 * <p> The fired Intent will have a boolean extra added with key 1077 * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is 1078 * entering the proximity region; if false, it is exiting. 1079 * 1080 * <p> Due to the approximate nature of position estimation, if the 1081 * device passes through the given area briefly, it is possible 1082 * that no Intent will be fired. Similarly, an Intent could be 1083 * fired if the device passes very close to the given area but 1084 * does not actually enter it. 1085 * 1086 * <p> After the number of milliseconds given by the expiration 1087 * parameter, the location manager will delete this proximity 1088 * alert and no longer monitor it. A value of -1 indicates that 1089 * there should be no expiration time. 1090 * 1091 * <p> In case the screen goes to sleep, checks for proximity alerts 1092 * happen only once every 4 minutes. This conserves battery life by 1093 * ensuring that the device isn't perpetually awake. 1094 * 1095 * <p> Internally, this method uses both {@link #NETWORK_PROVIDER} 1096 * and {@link #GPS_PROVIDER}. 1097 * 1098 * @param latitude the latitude of the central point of the 1099 * alert region 1100 * @param longitude the longitude of the central point of the 1101 * alert region 1102 * @param radius the radius of the central point of the 1103 * alert region, in meters 1104 * @param expiration time for this proximity alert, in milliseconds, 1105 * or -1 to indicate no expiration 1106 * @param intent a PendingIntent that will be used to generate an Intent to 1107 * fire when entry to or exit from the alert region is detected 1108 * 1109 * @throws SecurityException if no permission exists for the required 1110 * providers. 1111 * @deprecated use the {@link LocationRequest} class instead 1112 */ 1113 @Deprecated 1114 public void addProximityAlert(double latitude, double longitude, float radius, long expiration, 1115 PendingIntent intent) { 1116 checkPendingIntent(intent); 1117 if (expiration < 0) expiration = Long.MAX_VALUE; 1118 1119 Geofence fence = Geofence.createCircle(latitude, longitude, radius); 1120 LocationRequest request = new LocationRequest().setExpireIn(expiration); 1121 try { 1122 mService.requestGeofence(request, fence, intent, mContext.getPackageName()); 1123 } catch (RemoteException e) { 1124 Log.e(TAG, "RemoteException", e); 1125 } 1126 } 1127 1128 public void requestGeofence(LocationRequest request, Geofence fence, PendingIntent intent) { 1129 checkPendingIntent(intent); 1130 checkGeofence(fence); 1131 1132 try { 1133 mService.requestGeofence(request, fence, intent, mContext.getPackageName()); 1134 } catch (RemoteException e) { 1135 Log.e(TAG, "RemoteException", e); 1136 } 1137 } 1138 1139 /** 1140 * Removes the proximity alert with the given PendingIntent. 1141 * 1142 * @param intent the PendingIntent that no longer needs to be notified of 1143 * proximity alerts 1144 * @deprecated use the {@link LocationRequest} class instead 1145 */ 1146 @Deprecated 1147 public void removeProximityAlert(PendingIntent intent) { 1148 checkPendingIntent(intent); 1149 String packageName = mContext.getPackageName(); 1150 1151 try { 1152 mService.removeGeofence(null, intent, packageName); 1153 } catch (RemoteException e) { 1154 Log.e(TAG, "RemoteException", e); 1155 } 1156 } 1157 1158 public void removeGeofence(Geofence fence, PendingIntent intent) { 1159 checkPendingIntent(intent); 1160 checkGeofence(fence); 1161 String packageName = mContext.getPackageName(); 1162 1163 try { 1164 mService.removeGeofence(fence, intent, packageName); 1165 } catch (RemoteException e) { 1166 Log.e(TAG, "RemoteException", e); 1167 } 1168 } 1169 1170 public void removeAllGeofences(PendingIntent intent) { 1171 checkPendingIntent(intent); 1172 String packageName = mContext.getPackageName(); 1173 1174 try { 1175 mService.removeGeofence(null, intent, packageName); 1176 } catch (RemoteException e) { 1177 Log.e(TAG, "RemoteException", e); 1178 } 1179 } 1180 1181 /** 1182 * Returns the current enabled/disabled status of the given provider. If the 1183 * user has enabled this provider in the Settings menu, true is returned 1184 * otherwise false is returned 1185 * 1186 * @param provider the name of the provider 1187 * @return true if the provider is enabled 1188 * 1189 * @throws SecurityException if no suitable permission is present for the provider. 1190 * @throws IllegalArgumentException if provider is null 1191 * @deprecated use the {@link LocationRequest} class instead 1192 */ 1193 @Deprecated 1194 public boolean isProviderEnabled(String provider) { 1195 checkProvider(provider); 1196 1197 try { 1198 return mService.isProviderEnabled(provider); 1199 } catch (RemoteException e) { 1200 Log.e(TAG, "RemoteException", e); 1201 return false; 1202 } 1203 } 1204 1205 public Location getLastLocation(LocationRequest request) { 1206 try { 1207 return mService.getLastLocation(request); 1208 } catch (RemoteException e) { 1209 Log.e(TAG, "RemoteException", e); 1210 return null; 1211 } 1212 } 1213 1214 1215 /** 1216 * Returns a Location indicating the data from the last known 1217 * location fix obtained from the given provider. This can be done 1218 * without starting the provider. Note that this location could 1219 * be out-of-date, for example if the device was turned off and 1220 * moved to another location. 1221 * 1222 * <p> If the provider is currently disabled, null is returned. 1223 * 1224 * @param provider the name of the provider 1225 * @return the last known location for the provider, or null 1226 * 1227 * @throws SecurityException if no suitable permission is present for the provider. 1228 * @throws IllegalArgumentException if provider is null or doesn't exist 1229 * @deprecated use the {@link LocationRequest} class instead 1230 */ 1231 @Deprecated 1232 public Location getLastKnownLocation(String provider) { 1233 checkProvider(provider); 1234 1235 LocationRequest request = LocationRequest.createFromDeprecatedProvider( 1236 provider, 0, 0, true); 1237 1238 try { 1239 return mService.getLastLocation(request); 1240 } catch (RemoteException e) { 1241 Log.e(TAG, "RemoteException", e); 1242 return null; 1243 } 1244 } 1245 1246 // Mock provider support 1247 1248 /** 1249 * Creates a mock location provider and adds it to the set of active providers. 1250 * 1251 * @param name the provider name 1252 * @param requiresNetwork 1253 * @param requiresSatellite 1254 * @param requiresCell 1255 * @param hasMonetaryCost 1256 * @param supportsAltitude 1257 * @param supportsSpeed 1258 * @param supportsBearing 1259 * @param powerRequirement 1260 * @param accuracy 1261 * 1262 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1263 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1264 * Settings.Secure.ALLOW_MOCK_LOCATION} system setting is not enabled 1265 * @throws IllegalArgumentException if a provider with the given name already exists 1266 * @deprecated use the {@link LocationRequest} class instead 1267 */ 1268 @Deprecated 1269 public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, 1270 boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 1271 boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { 1272 ProviderProperties properties = new ProviderProperties(requiresNetwork, 1273 requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed, 1274 supportsBearing, powerRequirement, accuracy); 1275 if (name.matches(LocationProvider.BAD_CHARS_REGEX)) { 1276 throw new IllegalArgumentException("provider name contains illegal character: " + name); 1277 } 1278 1279 try { 1280 mService.addTestProvider(name, properties); 1281 } catch (RemoteException e) { 1282 Log.e(TAG, "RemoteException", e); 1283 } 1284 } 1285 1286 /** 1287 * Removes the mock location provider with the given name. 1288 * 1289 * @param provider the provider name 1290 * 1291 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1292 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1293 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1294 * @throws IllegalArgumentException if no provider with the given name exists 1295 * @deprecated use the {@link LocationRequest} class instead 1296 */ 1297 @Deprecated 1298 public void removeTestProvider(String provider) { 1299 try { 1300 mService.removeTestProvider(provider); 1301 } catch (RemoteException e) { 1302 Log.e(TAG, "RemoteException", e); 1303 } 1304 } 1305 1306 /** 1307 * Sets a mock location for the given provider. 1308 * <p>This location will be used in place of any actual location from the provider. 1309 * The location object must have a minimum number of fields set to be 1310 * considered a valid LocationProvider Location, as per documentation 1311 * on {@link Location} class. 1312 * 1313 * @param provider the provider name 1314 * @param loc the mock location 1315 * 1316 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1317 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1318 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1319 * @throws IllegalArgumentException if no provider with the given name exists 1320 * @throws IllegalArgumentException if the location is incomplete 1321 * @deprecated use the {@link LocationRequest} class instead 1322 */ 1323 @Deprecated 1324 public void setTestProviderLocation(String provider, Location loc) { 1325 if (!loc.isComplete()) { 1326 IllegalArgumentException e = new IllegalArgumentException( 1327 "Incomplete location object, missing timestamp or accuracy? " + loc); 1328 if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN) { 1329 // just log on old platform (for backwards compatibility) 1330 Log.w(TAG, e); 1331 loc.makeComplete(); 1332 } else { 1333 // really throw it! 1334 throw e; 1335 } 1336 } 1337 1338 try { 1339 mService.setTestProviderLocation(provider, loc); 1340 } catch (RemoteException e) { 1341 Log.e(TAG, "RemoteException", e); 1342 } 1343 } 1344 1345 /** 1346 * Removes any mock location associated with the given provider. 1347 * 1348 * @param provider the provider name 1349 * 1350 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1351 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1352 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1353 * @throws IllegalArgumentException if no provider with the given name exists 1354 * @deprecated use the {@link LocationRequest} class instead 1355 */ 1356 @Deprecated 1357 public void clearTestProviderLocation(String provider) { 1358 try { 1359 mService.clearTestProviderLocation(provider); 1360 } catch (RemoteException e) { 1361 Log.e(TAG, "RemoteException", e); 1362 } 1363 } 1364 1365 /** 1366 * Sets a mock enabled value for the given provider. This value will be used in place 1367 * of any actual value from the provider. 1368 * 1369 * @param provider the provider name 1370 * @param enabled the mock enabled value 1371 * 1372 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1373 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1374 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1375 * @throws IllegalArgumentException if no provider with the given name exists 1376 * @deprecated use the {@link LocationRequest} class instead 1377 */ 1378 @Deprecated 1379 public void setTestProviderEnabled(String provider, boolean enabled) { 1380 try { 1381 mService.setTestProviderEnabled(provider, enabled); 1382 } catch (RemoteException e) { 1383 Log.e(TAG, "RemoteException", e); 1384 } 1385 } 1386 1387 /** 1388 * Removes any mock enabled value associated with the given provider. 1389 * 1390 * @param provider the provider name 1391 * 1392 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1393 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1394 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1395 * @throws IllegalArgumentException if no provider with the given name exists 1396 * @deprecated use the {@link LocationRequest} class instead 1397 */ 1398 @Deprecated 1399 public void clearTestProviderEnabled(String provider) { 1400 try { 1401 mService.clearTestProviderEnabled(provider); 1402 } catch (RemoteException e) { 1403 Log.e(TAG, "RemoteException", e); 1404 } 1405 } 1406 1407 /** 1408 * Sets mock status values for the given provider. These values will be used in place 1409 * of any actual values from the provider. 1410 * 1411 * @param provider the provider name 1412 * @param status the mock status 1413 * @param extras a Bundle containing mock extras 1414 * @param updateTime the mock update time 1415 * 1416 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1417 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1418 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1419 * @throws IllegalArgumentException if no provider with the given name exists 1420 * @deprecated use the {@link LocationRequest} class instead 1421 */ 1422 @Deprecated 1423 public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 1424 try { 1425 mService.setTestProviderStatus(provider, status, extras, updateTime); 1426 } catch (RemoteException e) { 1427 Log.e(TAG, "RemoteException", e); 1428 } 1429 } 1430 1431 /** 1432 * Removes any mock status values associated with the given provider. 1433 * 1434 * @param provider the provider name 1435 * 1436 * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present 1437 * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION 1438 * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled 1439 * @throws IllegalArgumentException if no provider with the given name exists 1440 * @deprecated use the {@link LocationRequest} class instead 1441 */ 1442 @Deprecated 1443 public void clearTestProviderStatus(String provider) { 1444 try { 1445 mService.clearTestProviderStatus(provider); 1446 } catch (RemoteException e) { 1447 Log.e(TAG, "RemoteException", e); 1448 } 1449 } 1450 1451 // GPS-specific support 1452 1453 // This class is used to send GPS status events to the client's main thread. 1454 private class GpsStatusListenerTransport extends IGpsStatusListener.Stub { 1455 1456 private final GpsStatus.Listener mListener; 1457 private final GpsStatus.NmeaListener mNmeaListener; 1458 1459 // This must not equal any of the GpsStatus event IDs 1460 private static final int NMEA_RECEIVED = 1000; 1461 1462 private class Nmea { 1463 long mTimestamp; 1464 String mNmea; 1465 1466 Nmea(long timestamp, String nmea) { 1467 mTimestamp = timestamp; 1468 mNmea = nmea; 1469 } 1470 } 1471 private ArrayList<Nmea> mNmeaBuffer; 1472 1473 GpsStatusListenerTransport(GpsStatus.Listener listener) { 1474 mListener = listener; 1475 mNmeaListener = null; 1476 } 1477 1478 GpsStatusListenerTransport(GpsStatus.NmeaListener listener) { 1479 mNmeaListener = listener; 1480 mListener = null; 1481 mNmeaBuffer = new ArrayList<Nmea>(); 1482 } 1483 1484 @Override 1485 public void onGpsStarted() { 1486 if (mListener != null) { 1487 Message msg = Message.obtain(); 1488 msg.what = GpsStatus.GPS_EVENT_STARTED; 1489 mGpsHandler.sendMessage(msg); 1490 } 1491 } 1492 1493 @Override 1494 public void onGpsStopped() { 1495 if (mListener != null) { 1496 Message msg = Message.obtain(); 1497 msg.what = GpsStatus.GPS_EVENT_STOPPED; 1498 mGpsHandler.sendMessage(msg); 1499 } 1500 } 1501 1502 @Override 1503 public void onFirstFix(int ttff) { 1504 if (mListener != null) { 1505 mGpsStatus.setTimeToFirstFix(ttff); 1506 Message msg = Message.obtain(); 1507 msg.what = GpsStatus.GPS_EVENT_FIRST_FIX; 1508 mGpsHandler.sendMessage(msg); 1509 } 1510 } 1511 1512 @Override 1513 public void onSvStatusChanged(int svCount, int[] prns, float[] snrs, 1514 float[] elevations, float[] azimuths, int ephemerisMask, 1515 int almanacMask, int usedInFixMask) { 1516 if (mListener != null) { 1517 mGpsStatus.setStatus(svCount, prns, snrs, elevations, azimuths, 1518 ephemerisMask, almanacMask, usedInFixMask); 1519 1520 Message msg = Message.obtain(); 1521 msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS; 1522 // remove any SV status messages already in the queue 1523 mGpsHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS); 1524 mGpsHandler.sendMessage(msg); 1525 } 1526 } 1527 1528 @Override 1529 public void onNmeaReceived(long timestamp, String nmea) { 1530 if (mNmeaListener != null) { 1531 synchronized (mNmeaBuffer) { 1532 mNmeaBuffer.add(new Nmea(timestamp, nmea)); 1533 } 1534 Message msg = Message.obtain(); 1535 msg.what = NMEA_RECEIVED; 1536 // remove any NMEA_RECEIVED messages already in the queue 1537 mGpsHandler.removeMessages(NMEA_RECEIVED); 1538 mGpsHandler.sendMessage(msg); 1539 } 1540 } 1541 1542 private final Handler mGpsHandler = new Handler() { 1543 @Override 1544 public void handleMessage(Message msg) { 1545 if (msg.what == NMEA_RECEIVED) { 1546 synchronized (mNmeaBuffer) { 1547 int length = mNmeaBuffer.size(); 1548 for (int i = 0; i < length; i++) { 1549 Nmea nmea = mNmeaBuffer.get(i); 1550 mNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea); 1551 } 1552 mNmeaBuffer.clear(); 1553 } 1554 } else { 1555 // synchronize on mGpsStatus to ensure the data is copied atomically. 1556 synchronized(mGpsStatus) { 1557 mListener.onGpsStatusChanged(msg.what); 1558 } 1559 } 1560 } 1561 }; 1562 } 1563 1564 /** 1565 * Adds a GPS status listener. 1566 * 1567 * @param listener GPS status listener object to register 1568 * 1569 * @return true if the listener was successfully added 1570 * 1571 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 1572 */ 1573 public boolean addGpsStatusListener(GpsStatus.Listener listener) { 1574 boolean result; 1575 1576 if (mGpsStatusListeners.get(listener) != null) { 1577 // listener is already registered 1578 return true; 1579 } 1580 try { 1581 GpsStatusListenerTransport transport = new GpsStatusListenerTransport(listener); 1582 result = mService.addGpsStatusListener(transport); 1583 if (result) { 1584 mGpsStatusListeners.put(listener, transport); 1585 } 1586 } catch (RemoteException e) { 1587 Log.e(TAG, "RemoteException in registerGpsStatusListener: ", e); 1588 result = false; 1589 } 1590 1591 return result; 1592 } 1593 1594 /** 1595 * Removes a GPS status listener. 1596 * 1597 * @param listener GPS status listener object to remove 1598 */ 1599 public void removeGpsStatusListener(GpsStatus.Listener listener) { 1600 try { 1601 GpsStatusListenerTransport transport = mGpsStatusListeners.remove(listener); 1602 if (transport != null) { 1603 mService.removeGpsStatusListener(transport); 1604 } 1605 } catch (RemoteException e) { 1606 Log.e(TAG, "RemoteException in unregisterGpsStatusListener: ", e); 1607 } 1608 } 1609 1610 /** 1611 * Adds an NMEA listener. 1612 * 1613 * @param listener a {#link GpsStatus.NmeaListener} object to register 1614 * 1615 * @return true if the listener was successfully added 1616 * 1617 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 1618 */ 1619 public boolean addNmeaListener(GpsStatus.NmeaListener listener) { 1620 boolean result; 1621 1622 if (mNmeaListeners.get(listener) != null) { 1623 // listener is already registered 1624 return true; 1625 } 1626 try { 1627 GpsStatusListenerTransport transport = new GpsStatusListenerTransport(listener); 1628 result = mService.addGpsStatusListener(transport); 1629 if (result) { 1630 mNmeaListeners.put(listener, transport); 1631 } 1632 } catch (RemoteException e) { 1633 Log.e(TAG, "RemoteException in registerGpsStatusListener: ", e); 1634 result = false; 1635 } 1636 1637 return result; 1638 } 1639 1640 /** 1641 * Removes an NMEA listener. 1642 * 1643 * @param listener a {#link GpsStatus.NmeaListener} object to remove 1644 */ 1645 public void removeNmeaListener(GpsStatus.NmeaListener listener) { 1646 try { 1647 GpsStatusListenerTransport transport = mNmeaListeners.remove(listener); 1648 if (transport != null) { 1649 mService.removeGpsStatusListener(transport); 1650 } 1651 } catch (RemoteException e) { 1652 Log.e(TAG, "RemoteException in unregisterGpsStatusListener: ", e); 1653 } 1654 } 1655 1656 /** 1657 * Retrieves information about the current status of the GPS engine. 1658 * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} 1659 * callback to ensure that the data is copied atomically. 1660 * 1661 * The caller may either pass in a {@link GpsStatus} object to set with the latest 1662 * status information, or pass null to create a new {@link GpsStatus} object. 1663 * 1664 * @param status object containing GPS status details, or null. 1665 * @return status object containing updated GPS status. 1666 */ 1667 public GpsStatus getGpsStatus(GpsStatus status) { 1668 if (status == null) { 1669 status = new GpsStatus(); 1670 } 1671 status.setStatus(mGpsStatus); 1672 return status; 1673 } 1674 1675 /** 1676 * Sends additional commands to a location provider. 1677 * Can be used to support provider specific extensions to the Location Manager API 1678 * 1679 * @param provider name of the location provider. 1680 * @param command name of the command to send to the provider. 1681 * @param extras optional arguments for the command (or null). 1682 * The provider may optionally fill the extras Bundle with results from the command. 1683 * 1684 * @return true if the command succeeds. 1685 * @deprecated use the {@link LocationRequest} class instead 1686 */ 1687 @Deprecated 1688 public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1689 try { 1690 return mService.sendExtraCommand(provider, command, extras); 1691 } catch (RemoteException e) { 1692 Log.e(TAG, "RemoteException in sendExtraCommand: ", e); 1693 return false; 1694 } 1695 } 1696 1697 /** 1698 * Used by NetInitiatedActivity to report user response 1699 * for network initiated GPS fix requests. 1700 * 1701 * {@hide} 1702 */ 1703 public boolean sendNiResponse(int notifId, int userResponse) { 1704 try { 1705 return mService.sendNiResponse(notifId, userResponse); 1706 } catch (RemoteException e) { 1707 Log.e(TAG, "RemoteException in sendNiResponse: ", e); 1708 return false; 1709 } 1710 } 1711 1712 private static void checkProvider(String provider) { 1713 if (provider == null) { 1714 throw new IllegalArgumentException("invalid provider: " + provider); 1715 } 1716 } 1717 1718 private static void checkCriteria(Criteria criteria) { 1719 if (criteria == null) { 1720 throw new IllegalArgumentException("invalid criteria: " + criteria); 1721 } 1722 } 1723 private static void checkListener(LocationListener listener) { 1724 if (listener == null) { 1725 throw new IllegalArgumentException("invalid listener: " + listener); 1726 } 1727 } 1728 1729 private void checkPendingIntent(PendingIntent intent) { 1730 if (intent == null) { 1731 throw new IllegalArgumentException("invalid pending intent: " + intent); 1732 } 1733 if (!intent.isTargetedToPackage()) { 1734 IllegalArgumentException e = new IllegalArgumentException( 1735 "pending intent msut be targeted to package"); 1736 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN) { 1737 throw e; 1738 } else { 1739 Log.w(TAG, e); 1740 } 1741 } 1742 } 1743 1744 private static void checkGeofence(Geofence fence) { 1745 if (fence == null) { 1746 throw new IllegalArgumentException("invalid geofence: " + fence); 1747 } 1748 } 1749} 1750