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 17 package android.location; 18 19 import android.annotation.SystemApi; 20 import android.annotation.TestApi; 21 import android.compat.annotation.UnsupportedAppUsage; 22 import android.os.Build; 23 import android.os.Bundle; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.os.SystemClock; 27 import android.util.Printer; 28 import android.util.TimeUtils; 29 30 import java.text.DecimalFormat; 31 import java.util.StringTokenizer; 32 33 /** 34 * A data class representing a geographic location. 35 * 36 * <p>A location can consist of a latitude, longitude, timestamp, 37 * and other information such as bearing, altitude and velocity. 38 * 39 * <p>All locations generated by the {@link LocationManager} are 40 * guaranteed to have a valid latitude, longitude, and timestamp 41 * (both UTC time and elapsed real-time since boot), all other 42 * parameters are optional. 43 */ 44 public class Location implements Parcelable { 45 /** 46 * Constant used to specify formatting of a latitude or longitude 47 * in the form "[+-]DDD.DDDDD where D indicates degrees. 48 */ 49 public static final int FORMAT_DEGREES = 0; 50 51 /** 52 * Constant used to specify formatting of a latitude or longitude 53 * in the form "[+-]DDD:MM.MMMMM" where D indicates degrees and 54 * M indicates minutes of arc (1 minute = 1/60th of a degree). 55 */ 56 public static final int FORMAT_MINUTES = 1; 57 58 /** 59 * Constant used to specify formatting of a latitude or longitude 60 * in the form "DDD:MM:SS.SSSSS" where D indicates degrees, M 61 * indicates minutes of arc, and S indicates seconds of arc (1 62 * minute = 1/60th of a degree, 1 second = 1/3600th of a degree). 63 */ 64 public static final int FORMAT_SECONDS = 2; 65 66 /** 67 * Bundle key for a version of the location containing no GPS data. 68 * Allows location providers to flag locations as being safe to 69 * feed to LocationFudger. 70 * 71 * @hide 72 * @deprecated As of Android R, this extra is longer in use, since it is not necessary to keep 73 * gps locations separate from other locations for coarsening. Providers that do not need to 74 * support platforms below Android R should not use this constant. 75 */ 76 @TestApi 77 @SystemApi 78 @Deprecated 79 public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation"; 80 81 /** 82 * Bit mask for mFieldsMask indicating the presence of mAltitude. 83 */ 84 private static final int HAS_ALTITUDE_MASK = 1; 85 /** 86 * Bit mask for mFieldsMask indicating the presence of mSpeed. 87 */ 88 private static final int HAS_SPEED_MASK = 2; 89 /** 90 * Bit mask for mFieldsMask indicating the presence of mBearing. 91 */ 92 private static final int HAS_BEARING_MASK = 4; 93 /** 94 * Bit mask for mFieldsMask indicating the presence of mHorizontalAccuracy. 95 */ 96 private static final int HAS_HORIZONTAL_ACCURACY_MASK = 8; 97 /** 98 * Bit mask for mFieldsMask indicating location is from a mock provider. 99 */ 100 private static final int HAS_MOCK_PROVIDER_MASK = 16; 101 /** 102 * Bit mask for mFieldsMask indicating the presence of mVerticalAccuracy. 103 */ 104 private static final int HAS_VERTICAL_ACCURACY_MASK = 32; 105 /** 106 * Bit mask for mFieldsMask indicating the presence of mSpeedAccuracy. 107 */ 108 private static final int HAS_SPEED_ACCURACY_MASK = 64; 109 /** 110 * Bit mask for mFieldsMask indicating the presence of mBearingAccuracy. 111 */ 112 private static final int HAS_BEARING_ACCURACY_MASK = 128; 113 /** 114 * Bit mask for mFieldsMask indicating the presence of mElapsedRealtimeUncertaintyNanos. 115 */ 116 private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256; 117 118 // Cached data to make bearing/distance computations more efficient for the case 119 // where distanceTo and bearingTo are called in sequence. Assume this typically happens 120 // on the same thread for caching purposes. 121 private static ThreadLocal<BearingDistanceCache> sBearingDistanceCache 122 = new ThreadLocal<BearingDistanceCache>() { 123 @Override 124 protected BearingDistanceCache initialValue() { 125 return new BearingDistanceCache(); 126 } 127 }; 128 129 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 130 private String mProvider; 131 private long mTime = 0; 132 @UnsupportedAppUsage 133 private long mElapsedRealtimeNanos = 0; 134 // Estimate of the relative precision of the alignment of this SystemClock 135 // timestamp, with the reported measurements in nanoseconds (68% confidence). 136 private double mElapsedRealtimeUncertaintyNanos = 0.0f; 137 private double mLatitude = 0.0; 138 private double mLongitude = 0.0; 139 private double mAltitude = 0.0f; 140 private float mSpeed = 0.0f; 141 private float mBearing = 0.0f; 142 private float mHorizontalAccuracyMeters = 0.0f; 143 private float mVerticalAccuracyMeters = 0.0f; 144 private float mSpeedAccuracyMetersPerSecond = 0.0f; 145 private float mBearingAccuracyDegrees = 0.0f; 146 147 private Bundle mExtras = null; 148 149 // A bitmask of fields present in this object (see HAS_* constants defined above). 150 private int mFieldsMask = 0; 151 152 /** 153 * Construct a new Location with a named provider. 154 * 155 * <p>By default time, latitude and longitude are 0, and the location 156 * has no bearing, altitude, speed, accuracy or extras. 157 * 158 * @param provider the source that provides the location. It can be of type 159 * {@link LocationManager#GPS_PROVIDER}, {@link LocationManager#NETWORK_PROVIDER}, 160 * or {@link LocationManager#PASSIVE_PROVIDER}. You can also define your own 161 * provider string, in which case an empty string is a valid provider. 162 */ Location(String provider)163 public Location(String provider) { 164 mProvider = provider; 165 } 166 167 /** 168 * Construct a new Location object that is copied from an existing one. 169 */ Location(Location l)170 public Location(Location l) { 171 set(l); 172 } 173 174 /** 175 * Sets the contents of the location to the values from the given location. 176 */ set(Location l)177 public void set(Location l) { 178 mProvider = l.mProvider; 179 mTime = l.mTime; 180 mElapsedRealtimeNanos = l.mElapsedRealtimeNanos; 181 mElapsedRealtimeUncertaintyNanos = l.mElapsedRealtimeUncertaintyNanos; 182 mFieldsMask = l.mFieldsMask; 183 mLatitude = l.mLatitude; 184 mLongitude = l.mLongitude; 185 mAltitude = l.mAltitude; 186 mSpeed = l.mSpeed; 187 mBearing = l.mBearing; 188 mHorizontalAccuracyMeters = l.mHorizontalAccuracyMeters; 189 mVerticalAccuracyMeters = l.mVerticalAccuracyMeters; 190 mSpeedAccuracyMetersPerSecond = l.mSpeedAccuracyMetersPerSecond; 191 mBearingAccuracyDegrees = l.mBearingAccuracyDegrees; 192 mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras); 193 } 194 195 /** 196 * Clears the contents of the location. 197 */ reset()198 public void reset() { 199 mProvider = null; 200 mTime = 0; 201 mElapsedRealtimeNanos = 0; 202 mElapsedRealtimeUncertaintyNanos = 0.0; 203 mFieldsMask = 0; 204 mLatitude = 0; 205 mLongitude = 0; 206 mAltitude = 0; 207 mSpeed = 0; 208 mBearing = 0; 209 mHorizontalAccuracyMeters = 0; 210 mVerticalAccuracyMeters = 0; 211 mSpeedAccuracyMetersPerSecond = 0; 212 mBearingAccuracyDegrees = 0; 213 mExtras = null; 214 } 215 216 /** 217 * Converts a coordinate to a String representation. The outputType 218 * may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS. 219 * The coordinate must be a valid double between -180.0 and 180.0. 220 * This conversion is performed in a method that is dependent on the 221 * default locale, and so is not guaranteed to round-trip with 222 * {@link #convert(String)}. 223 * 224 * @throws IllegalArgumentException if coordinate is less than 225 * -180.0, greater than 180.0, or is not a number. 226 * @throws IllegalArgumentException if outputType is not one of 227 * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS. 228 */ convert(double coordinate, int outputType)229 public static String convert(double coordinate, int outputType) { 230 if (coordinate < -180.0 || coordinate > 180.0 || 231 Double.isNaN(coordinate)) { 232 throw new IllegalArgumentException("coordinate=" + coordinate); 233 } 234 if ((outputType != FORMAT_DEGREES) && 235 (outputType != FORMAT_MINUTES) && 236 (outputType != FORMAT_SECONDS)) { 237 throw new IllegalArgumentException("outputType=" + outputType); 238 } 239 240 StringBuilder sb = new StringBuilder(); 241 242 // Handle negative values 243 if (coordinate < 0) { 244 sb.append('-'); 245 coordinate = -coordinate; 246 } 247 248 DecimalFormat df = new DecimalFormat("###.#####"); 249 if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) { 250 int degrees = (int) Math.floor(coordinate); 251 sb.append(degrees); 252 sb.append(':'); 253 coordinate -= degrees; 254 coordinate *= 60.0; 255 if (outputType == FORMAT_SECONDS) { 256 int minutes = (int) Math.floor(coordinate); 257 sb.append(minutes); 258 sb.append(':'); 259 coordinate -= minutes; 260 coordinate *= 60.0; 261 } 262 } 263 sb.append(df.format(coordinate)); 264 return sb.toString(); 265 } 266 267 /** 268 * Converts a String in one of the formats described by 269 * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a 270 * double. This conversion is performed in a locale agnostic 271 * method, and so is not guaranteed to round-trip with 272 * {@link #convert(double, int)}. 273 * 274 * @throws NullPointerException if coordinate is null 275 * @throws IllegalArgumentException if the coordinate is not 276 * in one of the valid formats. 277 */ convert(String coordinate)278 public static double convert(String coordinate) { 279 // IllegalArgumentException if bad syntax 280 if (coordinate == null) { 281 throw new NullPointerException("coordinate"); 282 } 283 284 boolean negative = false; 285 if (coordinate.charAt(0) == '-') { 286 coordinate = coordinate.substring(1); 287 negative = true; 288 } 289 290 StringTokenizer st = new StringTokenizer(coordinate, ":"); 291 int tokens = st.countTokens(); 292 if (tokens < 1) { 293 throw new IllegalArgumentException("coordinate=" + coordinate); 294 } 295 try { 296 String degrees = st.nextToken(); 297 double val; 298 if (tokens == 1) { 299 val = Double.parseDouble(degrees); 300 return negative ? -val : val; 301 } 302 303 String minutes = st.nextToken(); 304 int deg = Integer.parseInt(degrees); 305 double min; 306 double sec = 0.0; 307 boolean secPresent = false; 308 309 if (st.hasMoreTokens()) { 310 min = Integer.parseInt(minutes); 311 String seconds = st.nextToken(); 312 sec = Double.parseDouble(seconds); 313 secPresent = true; 314 } else { 315 min = Double.parseDouble(minutes); 316 } 317 318 boolean isNegative180 = negative && (deg == 180) && 319 (min == 0) && (sec == 0); 320 321 // deg must be in [0, 179] except for the case of -180 degrees 322 if ((deg < 0.0) || (deg > 179 && !isNegative180)) { 323 throw new IllegalArgumentException("coordinate=" + coordinate); 324 } 325 326 // min must be in [0, 59] if seconds are present, otherwise [0.0, 60.0) 327 if (min < 0 || min >= 60 || (secPresent && (min > 59))) { 328 throw new IllegalArgumentException("coordinate=" + 329 coordinate); 330 } 331 332 // sec must be in [0.0, 60.0) 333 if (sec < 0 || sec >= 60) { 334 throw new IllegalArgumentException("coordinate=" + 335 coordinate); 336 } 337 338 val = deg*3600.0 + min*60.0 + sec; 339 val /= 3600.0; 340 return negative ? -val : val; 341 } catch (NumberFormatException nfe) { 342 throw new IllegalArgumentException("coordinate=" + coordinate); 343 } 344 } 345 computeDistanceAndBearing(double lat1, double lon1, double lat2, double lon2, BearingDistanceCache results)346 private static void computeDistanceAndBearing(double lat1, double lon1, 347 double lat2, double lon2, BearingDistanceCache results) { 348 // Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf 349 // using the "Inverse Formula" (section 4) 350 351 int MAXITERS = 20; 352 // Convert lat/long to radians 353 lat1 *= Math.PI / 180.0; 354 lat2 *= Math.PI / 180.0; 355 lon1 *= Math.PI / 180.0; 356 lon2 *= Math.PI / 180.0; 357 358 double a = 6378137.0; // WGS84 major axis 359 double b = 6356752.3142; // WGS84 semi-major axis 360 double f = (a - b) / a; 361 double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b); 362 363 double L = lon2 - lon1; 364 double A = 0.0; 365 double U1 = Math.atan((1.0 - f) * Math.tan(lat1)); 366 double U2 = Math.atan((1.0 - f) * Math.tan(lat2)); 367 368 double cosU1 = Math.cos(U1); 369 double cosU2 = Math.cos(U2); 370 double sinU1 = Math.sin(U1); 371 double sinU2 = Math.sin(U2); 372 double cosU1cosU2 = cosU1 * cosU2; 373 double sinU1sinU2 = sinU1 * sinU2; 374 375 double sigma = 0.0; 376 double deltaSigma = 0.0; 377 double cosSqAlpha = 0.0; 378 double cos2SM = 0.0; 379 double cosSigma = 0.0; 380 double sinSigma = 0.0; 381 double cosLambda = 0.0; 382 double sinLambda = 0.0; 383 384 double lambda = L; // initial guess 385 for (int iter = 0; iter < MAXITERS; iter++) { 386 double lambdaOrig = lambda; 387 cosLambda = Math.cos(lambda); 388 sinLambda = Math.sin(lambda); 389 double t1 = cosU2 * sinLambda; 390 double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda; 391 double sinSqSigma = t1 * t1 + t2 * t2; // (14) 392 sinSigma = Math.sqrt(sinSqSigma); 393 cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15) 394 sigma = Math.atan2(sinSigma, cosSigma); // (16) 395 double sinAlpha = (sinSigma == 0) ? 0.0 : 396 cosU1cosU2 * sinLambda / sinSigma; // (17) 397 cosSqAlpha = 1.0 - sinAlpha * sinAlpha; 398 cos2SM = (cosSqAlpha == 0) ? 0.0 : 399 cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18) 400 401 double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn 402 A = 1 + (uSquared / 16384.0) * // (3) 403 (4096.0 + uSquared * 404 (-768 + uSquared * (320.0 - 175.0 * uSquared))); 405 double B = (uSquared / 1024.0) * // (4) 406 (256.0 + uSquared * 407 (-128.0 + uSquared * (74.0 - 47.0 * uSquared))); 408 double C = (f / 16.0) * 409 cosSqAlpha * 410 (4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10) 411 double cos2SMSq = cos2SM * cos2SM; 412 deltaSigma = B * sinSigma * // (6) 413 (cos2SM + (B / 4.0) * 414 (cosSigma * (-1.0 + 2.0 * cos2SMSq) - 415 (B / 6.0) * cos2SM * 416 (-3.0 + 4.0 * sinSigma * sinSigma) * 417 (-3.0 + 4.0 * cos2SMSq))); 418 419 lambda = L + 420 (1.0 - C) * f * sinAlpha * 421 (sigma + C * sinSigma * 422 (cos2SM + C * cosSigma * 423 (-1.0 + 2.0 * cos2SM * cos2SM))); // (11) 424 425 double delta = (lambda - lambdaOrig) / lambda; 426 if (Math.abs(delta) < 1.0e-12) { 427 break; 428 } 429 } 430 431 float distance = (float) (b * A * (sigma - deltaSigma)); 432 results.mDistance = distance; 433 float initialBearing = (float) Math.atan2(cosU2 * sinLambda, 434 cosU1 * sinU2 - sinU1 * cosU2 * cosLambda); 435 initialBearing *= 180.0 / Math.PI; 436 results.mInitialBearing = initialBearing; 437 float finalBearing = (float) Math.atan2(cosU1 * sinLambda, 438 -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda); 439 finalBearing *= 180.0 / Math.PI; 440 results.mFinalBearing = finalBearing; 441 results.mLat1 = lat1; 442 results.mLat2 = lat2; 443 results.mLon1 = lon1; 444 results.mLon2 = lon2; 445 } 446 447 /** 448 * Computes the approximate distance in meters between two 449 * locations, and optionally the initial and final bearings of the 450 * shortest path between them. Distance and bearing are defined using the 451 * WGS84 ellipsoid. 452 * 453 * <p> The computed distance is stored in results[0]. If results has length 454 * 2 or greater, the initial bearing is stored in results[1]. If results has 455 * length 3 or greater, the final bearing is stored in results[2]. 456 * 457 * @param startLatitude the starting latitude 458 * @param startLongitude the starting longitude 459 * @param endLatitude the ending latitude 460 * @param endLongitude the ending longitude 461 * @param results an array of floats to hold the results 462 * 463 * @throws IllegalArgumentException if results is null or has length < 1 464 */ distanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)465 public static void distanceBetween(double startLatitude, double startLongitude, 466 double endLatitude, double endLongitude, float[] results) { 467 if (results == null || results.length < 1) { 468 throw new IllegalArgumentException("results is null or has length < 1"); 469 } 470 BearingDistanceCache cache = sBearingDistanceCache.get(); 471 computeDistanceAndBearing(startLatitude, startLongitude, 472 endLatitude, endLongitude, cache); 473 results[0] = cache.mDistance; 474 if (results.length > 1) { 475 results[1] = cache.mInitialBearing; 476 if (results.length > 2) { 477 results[2] = cache.mFinalBearing; 478 } 479 } 480 } 481 482 /** 483 * Returns the approximate distance in meters between this 484 * location and the given location. Distance is defined using 485 * the WGS84 ellipsoid. 486 * 487 * @param dest the destination location 488 * @return the approximate distance in meters 489 */ distanceTo(Location dest)490 public float distanceTo(Location dest) { 491 BearingDistanceCache cache = sBearingDistanceCache.get(); 492 // See if we already have the result 493 if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 || 494 dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) { 495 computeDistanceAndBearing(mLatitude, mLongitude, 496 dest.mLatitude, dest.mLongitude, cache); 497 } 498 return cache.mDistance; 499 } 500 501 /** 502 * Returns the approximate initial bearing in degrees East of true 503 * North when traveling along the shortest path between this 504 * location and the given location. The shortest path is defined 505 * using the WGS84 ellipsoid. Locations that are (nearly) 506 * antipodal may produce meaningless results. 507 * 508 * @param dest the destination location 509 * @return the initial bearing in degrees 510 */ bearingTo(Location dest)511 public float bearingTo(Location dest) { 512 BearingDistanceCache cache = sBearingDistanceCache.get(); 513 // See if we already have the result 514 if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 || 515 dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) { 516 computeDistanceAndBearing(mLatitude, mLongitude, 517 dest.mLatitude, dest.mLongitude, cache); 518 } 519 return cache.mInitialBearing; 520 } 521 522 /** 523 * Returns the name of the provider that generated this fix. 524 * 525 * @return the provider, or null if it has not been set 526 */ getProvider()527 public String getProvider() { 528 return mProvider; 529 } 530 531 /** 532 * Sets the name of the provider that generated this fix. 533 */ setProvider(String provider)534 public void setProvider(String provider) { 535 mProvider = provider; 536 } 537 538 /** 539 * Return the UTC time of this fix, in milliseconds since January 1, 1970. 540 * 541 * <p>Note that the UTC time on a device is not monotonic: it 542 * can jump forwards or backwards unpredictably. So always use 543 * {@link #getElapsedRealtimeNanos} when calculating time deltas. 544 * 545 * <p>On the other hand, {@link #getTime} is useful for presenting 546 * a human readable time to the user, or for carefully comparing 547 * location fixes across reboot or across devices. 548 * 549 * <p>All locations generated by the {@link LocationManager} 550 * are guaranteed to have a valid UTC time, however remember that 551 * the system time may have changed since the location was generated. 552 * 553 * @return time of fix, in milliseconds since January 1, 1970. 554 */ getTime()555 public long getTime() { 556 return mTime; 557 } 558 559 /** 560 * Set the UTC time of this fix, in milliseconds since January 1, 561 * 1970. 562 * 563 * @param time UTC time of this fix, in milliseconds since January 1, 1970 564 */ setTime(long time)565 public void setTime(long time) { 566 mTime = time; 567 } 568 569 /** 570 * Return the time of this fix, in elapsed real-time since system boot. 571 * 572 * <p>This value can be reliably compared to 573 * {@link android.os.SystemClock#elapsedRealtimeNanos}, 574 * to calculate the age of a fix and to compare Location fixes. This 575 * is reliable because elapsed real-time is guaranteed monotonic for 576 * each system boot and continues to increment even when the system 577 * is in deep sleep (unlike {@link #getTime}. 578 * 579 * <p>All locations generated by the {@link LocationManager} 580 * are guaranteed to have a valid elapsed real-time. 581 * 582 * @return elapsed real-time of fix, in nanoseconds since system boot. 583 */ getElapsedRealtimeNanos()584 public long getElapsedRealtimeNanos() { 585 return mElapsedRealtimeNanos; 586 } 587 588 /** @hide */ getElapsedRealtimeAgeNanos(long referenceRealtimeNs)589 public long getElapsedRealtimeAgeNanos(long referenceRealtimeNs) { 590 return referenceRealtimeNs - mElapsedRealtimeNanos; 591 } 592 593 /** @hide */ getElapsedRealtimeAgeNanos()594 public long getElapsedRealtimeAgeNanos() { 595 return getElapsedRealtimeAgeNanos(SystemClock.elapsedRealtimeNanos()); 596 } 597 598 /** 599 * Set the time of this fix, in elapsed real-time since system boot. 600 * 601 * @param time elapsed real-time of fix, in nanoseconds since system boot. 602 */ setElapsedRealtimeNanos(long time)603 public void setElapsedRealtimeNanos(long time) { 604 mElapsedRealtimeNanos = time; 605 } 606 607 /** 608 * Get estimate of the relative precision of the alignment of the 609 * ElapsedRealtimeNanos timestamp, with the reported measurements in 610 * nanoseconds (68% confidence). 611 * 612 * This means that we have 68% confidence that the true timestamp of the 613 * event is within ElapsedReatimeNanos +/- uncertainty. 614 * 615 * Example : 616 * - getElapsedRealtimeNanos() returns 10000000 617 * - getElapsedRealtimeUncertaintyNanos() returns 1000000 (equivalent to 1millisecond) 618 * This means that the event most likely happened between 9000000 and 11000000. 619 * 620 * @return uncertainty of elapsed real-time of fix, in nanoseconds. 621 */ getElapsedRealtimeUncertaintyNanos()622 public double getElapsedRealtimeUncertaintyNanos() { 623 return mElapsedRealtimeUncertaintyNanos; 624 } 625 626 /** 627 * Set estimate of the relative precision of the alignment of the 628 * ElapsedRealtimeNanos timestamp, with the reported measurements in 629 * nanoseconds (68% confidence). 630 * 631 * @param time uncertainty of the elapsed real-time of fix, in nanoseconds. 632 */ setElapsedRealtimeUncertaintyNanos(double time)633 public void setElapsedRealtimeUncertaintyNanos(double time) { 634 mElapsedRealtimeUncertaintyNanos = time; 635 mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK; 636 } 637 638 /** 639 * True if this location has a elapsed realtime accuracy. 640 */ hasElapsedRealtimeUncertaintyNanos()641 public boolean hasElapsedRealtimeUncertaintyNanos() { 642 return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0; 643 } 644 645 646 /** 647 * Get the latitude, in degrees. 648 * 649 * <p>All locations generated by the {@link LocationManager} 650 * will have a valid latitude. 651 */ getLatitude()652 public double getLatitude() { 653 return mLatitude; 654 } 655 656 /** 657 * Set the latitude, in degrees. 658 */ setLatitude(double latitude)659 public void setLatitude(double latitude) { 660 mLatitude = latitude; 661 } 662 663 /** 664 * Get the longitude, in degrees. 665 * 666 * <p>All locations generated by the {@link LocationManager} 667 * will have a valid longitude. 668 */ getLongitude()669 public double getLongitude() { 670 return mLongitude; 671 } 672 673 /** 674 * Set the longitude, in degrees. 675 */ setLongitude(double longitude)676 public void setLongitude(double longitude) { 677 mLongitude = longitude; 678 } 679 680 /** 681 * True if this location has an altitude. 682 */ hasAltitude()683 public boolean hasAltitude() { 684 return (mFieldsMask & HAS_ALTITUDE_MASK) != 0; 685 } 686 687 /** 688 * Get the altitude if available, in meters above the WGS 84 reference 689 * ellipsoid. 690 * 691 * <p>If this location does not have an altitude then 0.0 is returned. 692 */ getAltitude()693 public double getAltitude() { 694 return mAltitude; 695 } 696 697 /** 698 * Set the altitude, in meters above the WGS 84 reference ellipsoid. 699 * 700 * <p>Following this call {@link #hasAltitude} will return true. 701 */ setAltitude(double altitude)702 public void setAltitude(double altitude) { 703 mAltitude = altitude; 704 mFieldsMask |= HAS_ALTITUDE_MASK; 705 } 706 707 /** 708 * Remove the altitude from this location. 709 * 710 * <p>Following this call {@link #hasAltitude} will return false, 711 * and {@link #getAltitude} will return 0.0. 712 * 713 * @deprecated use a new Location object for location updates. 714 */ 715 @Deprecated removeAltitude()716 public void removeAltitude() { 717 mAltitude = 0.0f; 718 mFieldsMask &= ~HAS_ALTITUDE_MASK; 719 } 720 721 /** 722 * True if this location has a speed. 723 */ hasSpeed()724 public boolean hasSpeed() { 725 return (mFieldsMask & HAS_SPEED_MASK) != 0; 726 } 727 728 /** 729 * Get the speed if it is available, in meters/second over ground. 730 * 731 * <p>If this location does not have a speed then 0.0 is returned. 732 */ getSpeed()733 public float getSpeed() { 734 return mSpeed; 735 } 736 737 /** 738 * Set the speed, in meters/second over ground. 739 * 740 * <p>Following this call {@link #hasSpeed} will return true. 741 */ setSpeed(float speed)742 public void setSpeed(float speed) { 743 mSpeed = speed; 744 mFieldsMask |= HAS_SPEED_MASK; 745 } 746 747 /** 748 * Remove the speed from this location. 749 * 750 * <p>Following this call {@link #hasSpeed} will return false, 751 * and {@link #getSpeed} will return 0.0. 752 * 753 * @deprecated use a new Location object for location updates. 754 */ 755 @Deprecated removeSpeed()756 public void removeSpeed() { 757 mSpeed = 0.0f; 758 mFieldsMask &= ~HAS_SPEED_MASK; 759 } 760 761 /** 762 * True if this location has a bearing. 763 */ hasBearing()764 public boolean hasBearing() { 765 return (mFieldsMask & HAS_BEARING_MASK) != 0; 766 } 767 768 /** 769 * Get the bearing, in degrees. 770 * 771 * <p>Bearing is the horizontal direction of travel of this device, 772 * and is not related to the device orientation. It is guaranteed to 773 * be in the range (0.0, 360.0] if the device has a bearing. 774 * 775 * <p>If this location does not have a bearing then 0.0 is returned. 776 */ getBearing()777 public float getBearing() { 778 return mBearing; 779 } 780 781 /** 782 * Set the bearing, in degrees. 783 * 784 * <p>Bearing is the horizontal direction of travel of this device, 785 * and is not related to the device orientation. 786 * 787 * <p>The input will be wrapped into the range (0.0, 360.0]. 788 */ setBearing(float bearing)789 public void setBearing(float bearing) { 790 while (bearing < 0.0f) { 791 bearing += 360.0f; 792 } 793 while (bearing >= 360.0f) { 794 bearing -= 360.0f; 795 } 796 mBearing = bearing; 797 mFieldsMask |= HAS_BEARING_MASK; 798 } 799 800 /** 801 * Remove the bearing from this location. 802 * 803 * <p>Following this call {@link #hasBearing} will return false, 804 * and {@link #getBearing} will return 0.0. 805 * 806 * @deprecated use a new Location object for location updates. 807 */ 808 @Deprecated removeBearing()809 public void removeBearing() { 810 mBearing = 0.0f; 811 mFieldsMask &= ~HAS_BEARING_MASK; 812 } 813 814 /** 815 * True if this location has a horizontal accuracy. 816 * 817 * <p>All locations generated by the {@link LocationManager} have an horizontal accuracy. 818 */ hasAccuracy()819 public boolean hasAccuracy() { 820 return (mFieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0; 821 } 822 823 /** 824 * Get the estimated horizontal accuracy of this location, radial, in meters. 825 * 826 * <p>We define horizontal accuracy as the radius of 68% confidence. In other 827 * words, if you draw a circle centered at this location's 828 * latitude and longitude, and with a radius equal to the accuracy, 829 * then there is a 68% probability that the true location is inside 830 * the circle. 831 * 832 * <p>This accuracy estimation is only concerned with horizontal 833 * accuracy, and does not indicate the accuracy of bearing, 834 * velocity or altitude if those are included in this Location. 835 * 836 * <p>If this location does not have a horizontal accuracy, then 0.0 is returned. 837 * All locations generated by the {@link LocationManager} include horizontal accuracy. 838 */ getAccuracy()839 public float getAccuracy() { 840 return mHorizontalAccuracyMeters; 841 } 842 843 /** 844 * Set the estimated horizontal accuracy of this location, meters. 845 * 846 * <p>See {@link #getAccuracy} for the definition of horizontal accuracy. 847 * 848 * <p>Following this call {@link #hasAccuracy} will return true. 849 */ setAccuracy(float horizontalAccuracy)850 public void setAccuracy(float horizontalAccuracy) { 851 mHorizontalAccuracyMeters = horizontalAccuracy; 852 mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK; 853 } 854 855 /** 856 * Remove the horizontal accuracy from this location. 857 * 858 * <p>Following this call {@link #hasAccuracy} will return false, and 859 * {@link #getAccuracy} will return 0.0. 860 * 861 * @deprecated use a new Location object for location updates. 862 */ 863 @Deprecated removeAccuracy()864 public void removeAccuracy() { 865 mHorizontalAccuracyMeters = 0.0f; 866 mFieldsMask &= ~HAS_HORIZONTAL_ACCURACY_MASK; 867 } 868 869 /** 870 * True if this location has a vertical accuracy. 871 */ hasVerticalAccuracy()872 public boolean hasVerticalAccuracy() { 873 return (mFieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0; 874 } 875 876 /** 877 * Get the estimated vertical accuracy of this location, in meters. 878 * 879 * <p>We define vertical accuracy at 68% confidence. Specifically, as 1-side of the 880 * 2-sided range above and below the estimated altitude reported by {@link #getAltitude()}, 881 * within which there is a 68% probability of finding the true altitude. 882 * 883 * <p>In the case where the underlying distribution is assumed Gaussian normal, this would be 884 * considered 1 standard deviation. 885 * 886 * <p>For example, if {@link #getAltitude()} returns 150, and 887 * {@link #getVerticalAccuracyMeters()} returns 20 then there is a 68% probability 888 * of the true altitude being between 130 and 170 meters. 889 * 890 * <p>If this location does not have a vertical accuracy, then 0.0 is returned. 891 */ getVerticalAccuracyMeters()892 public float getVerticalAccuracyMeters() { 893 return mVerticalAccuracyMeters; 894 } 895 896 /** 897 * Set the estimated vertical accuracy of this location, meters. 898 * 899 * <p>See {@link #getVerticalAccuracyMeters} for the definition of vertical accuracy. 900 * 901 * <p>Following this call {@link #hasVerticalAccuracy} will return true. 902 */ setVerticalAccuracyMeters(float verticalAccuracyMeters)903 public void setVerticalAccuracyMeters(float verticalAccuracyMeters) { 904 mVerticalAccuracyMeters = verticalAccuracyMeters; 905 mFieldsMask |= HAS_VERTICAL_ACCURACY_MASK; 906 } 907 908 /** 909 * Remove the vertical accuracy from this location. 910 * 911 * <p>Following this call {@link #hasVerticalAccuracy} will return false, and 912 * {@link #getVerticalAccuracyMeters} will return 0.0. 913 * 914 * @deprecated use a new Location object for location updates. 915 * @removed 916 */ 917 @Deprecated removeVerticalAccuracy()918 public void removeVerticalAccuracy() { 919 mVerticalAccuracyMeters = 0.0f; 920 mFieldsMask &= ~HAS_VERTICAL_ACCURACY_MASK; 921 } 922 923 /** 924 * True if this location has a speed accuracy. 925 */ hasSpeedAccuracy()926 public boolean hasSpeedAccuracy() { 927 return (mFieldsMask & HAS_SPEED_ACCURACY_MASK) != 0; 928 } 929 930 /** 931 * Get the estimated speed accuracy of this location, in meters per second. 932 * 933 * <p>We define speed accuracy at 68% confidence. Specifically, as 1-side of the 934 * 2-sided range above and below the estimated speed reported by {@link #getSpeed()}, 935 * within which there is a 68% probability of finding the true speed. 936 * 937 * <p>In the case where the underlying 938 * distribution is assumed Gaussian normal, this would be considered 1 standard deviation. 939 * 940 * <p>For example, if {@link #getSpeed()} returns 5, and 941 * {@link #getSpeedAccuracyMetersPerSecond()} returns 1, then there is a 68% probability of 942 * the true speed being between 4 and 6 meters per second. 943 * 944 * <p>Note that the speed and speed accuracy is often better than would be obtained simply from 945 * differencing sequential positions, such as when the Doppler measurements from GNSS satellites 946 * are used. 947 * 948 * <p>If this location does not have a speed accuracy, then 0.0 is returned. 949 */ getSpeedAccuracyMetersPerSecond()950 public float getSpeedAccuracyMetersPerSecond() { 951 return mSpeedAccuracyMetersPerSecond; 952 } 953 954 /** 955 * Set the estimated speed accuracy of this location, meters per second. 956 * 957 * <p>See {@link #getSpeedAccuracyMetersPerSecond} for the definition of speed accuracy. 958 * 959 * <p>Following this call {@link #hasSpeedAccuracy} will return true. 960 */ setSpeedAccuracyMetersPerSecond(float speedAccuracyMeterPerSecond)961 public void setSpeedAccuracyMetersPerSecond(float speedAccuracyMeterPerSecond) { 962 mSpeedAccuracyMetersPerSecond = speedAccuracyMeterPerSecond; 963 mFieldsMask |= HAS_SPEED_ACCURACY_MASK; 964 } 965 966 /** 967 * Remove the speed accuracy from this location. 968 * 969 * <p>Following this call {@link #hasSpeedAccuracy} will return false, and 970 * {@link #getSpeedAccuracyMetersPerSecond} will return 0.0. 971 * 972 * @deprecated use a new Location object for location updates. 973 * @removed 974 */ 975 @Deprecated removeSpeedAccuracy()976 public void removeSpeedAccuracy() { 977 mSpeedAccuracyMetersPerSecond = 0.0f; 978 mFieldsMask &= ~HAS_SPEED_ACCURACY_MASK; 979 } 980 981 /** 982 * True if this location has a bearing accuracy. 983 */ hasBearingAccuracy()984 public boolean hasBearingAccuracy() { 985 return (mFieldsMask & HAS_BEARING_ACCURACY_MASK) != 0; 986 } 987 988 /** 989 * Get the estimated bearing accuracy of this location, in degrees. 990 * 991 * <p>We define bearing accuracy at 68% confidence. Specifically, as 1-side of the 992 * 2-sided range on each side of the estimated bearing reported by {@link #getBearing()}, 993 * within which there is a 68% probability of finding the true bearing. 994 * 995 * <p>In the case where the underlying distribution is assumed Gaussian normal, this would be 996 * considered 1 standard deviation. 997 * 998 * <p>For example, if {@link #getBearing()} returns 60, and 999 * {@link #getBearingAccuracyDegrees()} returns 10, then there is a 68% probability of the 1000 * true bearing being between 50 and 70 degrees. 1001 * 1002 * <p>If this location does not have a bearing accuracy, then 0.0 is returned. 1003 */ getBearingAccuracyDegrees()1004 public float getBearingAccuracyDegrees() { 1005 return mBearingAccuracyDegrees; 1006 } 1007 1008 /** 1009 * Set the estimated bearing accuracy of this location, degrees. 1010 * 1011 * <p>See {@link #getBearingAccuracyDegrees} for the definition of bearing accuracy. 1012 * 1013 * <p>Following this call {@link #hasBearingAccuracy} will return true. 1014 */ setBearingAccuracyDegrees(float bearingAccuracyDegrees)1015 public void setBearingAccuracyDegrees(float bearingAccuracyDegrees) { 1016 mBearingAccuracyDegrees = bearingAccuracyDegrees; 1017 mFieldsMask |= HAS_BEARING_ACCURACY_MASK; 1018 } 1019 1020 /** 1021 * Remove the bearing accuracy from this location. 1022 * 1023 * <p>Following this call {@link #hasBearingAccuracy} will return false, and 1024 * {@link #getBearingAccuracyDegrees} will return 0.0. 1025 * 1026 * @deprecated use a new Location object for location updates. 1027 * @removed 1028 */ 1029 @Deprecated removeBearingAccuracy()1030 public void removeBearingAccuracy() { 1031 mBearingAccuracyDegrees = 0.0f; 1032 mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK; 1033 } 1034 1035 /** 1036 * Return true if this Location object is complete. 1037 * 1038 * <p>A location object is currently considered complete if it has 1039 * a valid provider, accuracy, wall-clock time and elapsed real-time. 1040 * 1041 * <p>All locations supplied by the {@link LocationManager} to 1042 * applications must be complete. 1043 * 1044 * @see #makeComplete 1045 * @hide 1046 */ 1047 @SystemApi isComplete()1048 public boolean isComplete() { 1049 if (mProvider == null) return false; 1050 if (!hasAccuracy()) return false; 1051 if (mTime == 0) return false; 1052 if (mElapsedRealtimeNanos == 0) return false; 1053 return true; 1054 } 1055 1056 /** 1057 * Helper to fill incomplete fields. 1058 * 1059 * <p>Used to assist in backwards compatibility with 1060 * Location objects received from applications. 1061 * 1062 * @see #isComplete 1063 * @hide 1064 */ 1065 @TestApi 1066 @SystemApi makeComplete()1067 public void makeComplete() { 1068 if (mProvider == null) mProvider = "?"; 1069 if (!hasAccuracy()) { 1070 mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK; 1071 mHorizontalAccuracyMeters = 100.0f; 1072 } 1073 if (mTime == 0) mTime = System.currentTimeMillis(); 1074 if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); 1075 } 1076 1077 /** 1078 * Returns additional provider-specific information about the 1079 * location fix as a Bundle. The keys and values are determined 1080 * by the provider. If no additional information is available, 1081 * null is returned. 1082 * 1083 * <p> A number of common key/value pairs are listed 1084 * below. Providers that use any of the keys on this list must 1085 * provide the corresponding value as described below. 1086 * 1087 * <ul> 1088 * <li> satellites - the number of satellites used to derive the fix 1089 * </ul> 1090 */ getExtras()1091 public Bundle getExtras() { 1092 return mExtras; 1093 } 1094 1095 /** 1096 * Sets the extra information associated with this fix to the 1097 * given Bundle. 1098 * 1099 * <p>Note this stores a copy of the given extras, so any changes to extras after calling this 1100 * method won't be reflected in the location bundle. 1101 */ setExtras(Bundle extras)1102 public void setExtras(Bundle extras) { 1103 mExtras = (extras == null) ? null : new Bundle(extras); 1104 } 1105 1106 @Override toString()1107 public String toString() { 1108 StringBuilder s = new StringBuilder(); 1109 s.append("Location["); 1110 s.append(mProvider); 1111 s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude)); 1112 if (hasAccuracy()) s.append(String.format(" hAcc=%.0f", mHorizontalAccuracyMeters)); 1113 else s.append(" hAcc=???"); 1114 if (mTime == 0) { 1115 s.append(" t=?!?"); 1116 } 1117 if (mElapsedRealtimeNanos == 0) { 1118 s.append(" et=?!?"); 1119 } else { 1120 s.append(" et="); 1121 TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s); 1122 } 1123 if (hasElapsedRealtimeUncertaintyNanos()) { 1124 s.append(" etAcc="); 1125 TimeUtils.formatDuration((long) (mElapsedRealtimeUncertaintyNanos / 1000000), s); 1126 } 1127 if (hasAltitude()) s.append(" alt=").append(mAltitude); 1128 if (hasSpeed()) s.append(" vel=").append(mSpeed); 1129 if (hasBearing()) s.append(" bear=").append(mBearing); 1130 if (hasVerticalAccuracy()) s.append(String.format(" vAcc=%.0f", mVerticalAccuracyMeters)); 1131 else s.append(" vAcc=???"); 1132 if (hasSpeedAccuracy()) s.append(String.format(" sAcc=%.0f", mSpeedAccuracyMetersPerSecond)); 1133 else s.append(" sAcc=???"); 1134 if (hasBearingAccuracy()) s.append(String.format(" bAcc=%.0f", mBearingAccuracyDegrees)); 1135 else s.append(" bAcc=???"); 1136 if (isFromMockProvider()) s.append(" mock"); 1137 1138 if (mExtras != null) { 1139 s.append(" {").append(mExtras).append('}'); 1140 } 1141 s.append(']'); 1142 return s.toString(); 1143 } 1144 dump(Printer pw, String prefix)1145 public void dump(Printer pw, String prefix) { 1146 pw.println(prefix + toString()); 1147 } 1148 1149 public static final @android.annotation.NonNull Parcelable.Creator<Location> CREATOR = 1150 new Parcelable.Creator<Location>() { 1151 @Override 1152 public Location createFromParcel(Parcel in) { 1153 String provider = in.readString(); 1154 Location l = new Location(provider); 1155 l.mTime = in.readLong(); 1156 l.mElapsedRealtimeNanos = in.readLong(); 1157 l.mElapsedRealtimeUncertaintyNanos = in.readDouble(); 1158 l.mFieldsMask = in.readInt(); 1159 l.mLatitude = in.readDouble(); 1160 l.mLongitude = in.readDouble(); 1161 l.mAltitude = in.readDouble(); 1162 l.mSpeed = in.readFloat(); 1163 l.mBearing = in.readFloat(); 1164 l.mHorizontalAccuracyMeters = in.readFloat(); 1165 l.mVerticalAccuracyMeters = in.readFloat(); 1166 l.mSpeedAccuracyMetersPerSecond = in.readFloat(); 1167 l.mBearingAccuracyDegrees = in.readFloat(); 1168 l.mExtras = Bundle.setDefusable(in.readBundle(), true); 1169 return l; 1170 } 1171 1172 @Override 1173 public Location[] newArray(int size) { 1174 return new Location[size]; 1175 } 1176 }; 1177 1178 @Override describeContents()1179 public int describeContents() { 1180 return 0; 1181 } 1182 1183 @Override writeToParcel(Parcel parcel, int flags)1184 public void writeToParcel(Parcel parcel, int flags) { 1185 parcel.writeString(mProvider); 1186 parcel.writeLong(mTime); 1187 parcel.writeLong(mElapsedRealtimeNanos); 1188 parcel.writeDouble(mElapsedRealtimeUncertaintyNanos); 1189 parcel.writeInt(mFieldsMask); 1190 parcel.writeDouble(mLatitude); 1191 parcel.writeDouble(mLongitude); 1192 parcel.writeDouble(mAltitude); 1193 parcel.writeFloat(mSpeed); 1194 parcel.writeFloat(mBearing); 1195 parcel.writeFloat(mHorizontalAccuracyMeters); 1196 parcel.writeFloat(mVerticalAccuracyMeters); 1197 parcel.writeFloat(mSpeedAccuracyMetersPerSecond); 1198 parcel.writeFloat(mBearingAccuracyDegrees); 1199 parcel.writeBundle(mExtras); 1200 } 1201 1202 /** 1203 * Returns one of the optional extra {@link Location}s that can be attached 1204 * to this Location. 1205 * 1206 * @param key the key associated with the desired extra Location 1207 * @return the extra Location, or null if unavailable 1208 * @hide 1209 */ getExtraLocation(String key)1210 public Location getExtraLocation(String key) { 1211 if (mExtras != null) { 1212 Parcelable value = mExtras.getParcelable(key); 1213 if (value instanceof Location) { 1214 return (Location) value; 1215 } 1216 } 1217 return null; 1218 } 1219 1220 /** 1221 * Returns true if the Location came from a mock provider. 1222 * 1223 * @return true if this Location came from a mock provider, false otherwise 1224 */ isFromMockProvider()1225 public boolean isFromMockProvider() { 1226 return (mFieldsMask & HAS_MOCK_PROVIDER_MASK) != 0; 1227 } 1228 1229 /** 1230 * Flag this Location as having come from a mock provider or not. 1231 * 1232 * @param isFromMockProvider true if this Location came from a mock provider, false otherwise 1233 * @hide 1234 */ 1235 @SystemApi setIsFromMockProvider(boolean isFromMockProvider)1236 public void setIsFromMockProvider(boolean isFromMockProvider) { 1237 if (isFromMockProvider) { 1238 mFieldsMask |= HAS_MOCK_PROVIDER_MASK; 1239 } else { 1240 mFieldsMask &= ~HAS_MOCK_PROVIDER_MASK; 1241 } 1242 } 1243 1244 /** 1245 * Caches data used to compute distance and bearing (so successive calls to {@link #distanceTo} 1246 * and {@link #bearingTo} don't duplicate work. 1247 */ 1248 private static class BearingDistanceCache { 1249 private double mLat1 = 0.0; 1250 private double mLon1 = 0.0; 1251 private double mLat2 = 0.0; 1252 private double mLon2 = 0.0; 1253 private float mDistance = 0.0f; 1254 private float mInitialBearing = 0.0f; 1255 private float mFinalBearing = 0.0f; 1256 } 1257 } 1258