diff --git a/core/api/current.txt b/core/api/current.txt index 30dbbdba618df..d4ad8693ce493 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -19533,6 +19533,8 @@ package android.location { method @Nullable public android.os.Bundle getExtras(); method @FloatRange(from=-90.0, to=90.0) public double getLatitude(); method @FloatRange(from=-180.0, to=180.0) public double getLongitude(); + method @FloatRange(from=0.0) public float getMslAltitudeAccuracyMeters(); + method @FloatRange public double getMslAltitudeMeters(); method @Nullable public String getProvider(); method @FloatRange(from=0.0) public float getSpeed(); method @FloatRange(from=0.0) public float getSpeedAccuracyMetersPerSecond(); @@ -19543,6 +19545,8 @@ package android.location { method public boolean hasBearing(); method public boolean hasBearingAccuracy(); method public boolean hasElapsedRealtimeUncertaintyNanos(); + method public boolean hasMslAltitude(); + method public boolean hasMslAltitudeAccuracy(); method public boolean hasSpeed(); method public boolean hasSpeedAccuracy(); method public boolean hasVerticalAccuracy(); @@ -19554,6 +19558,8 @@ package android.location { method public void removeBearing(); method public void removeBearingAccuracy(); method public void removeElapsedRealtimeUncertaintyNanos(); + method public void removeMslAltitude(); + method public void removeMslAltitudeAccuracy(); method public void removeSpeed(); method public void removeSpeedAccuracy(); method public void removeVerticalAccuracy(); @@ -19569,6 +19575,8 @@ package android.location { method public void setLatitude(@FloatRange(from=-90.0, to=90.0) double); method public void setLongitude(@FloatRange(from=-180.0, to=180.0) double); method public void setMock(boolean); + method public void setMslAltitudeAccuracyMeters(@FloatRange(from=0.0) float); + method public void setMslAltitudeMeters(@FloatRange double); method public void setProvider(@Nullable String); method public void setSpeed(@FloatRange(from=0.0) float); method public void setSpeedAccuracyMetersPerSecond(@FloatRange(from=0.0) float); diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 033056cb2a694..55ee3aaaaf779 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -95,6 +95,8 @@ public class Location implements Parcelable { private static final int HAS_SPEED_ACCURACY_MASK = 1 << 6; private static final int HAS_BEARING_ACCURACY_MASK = 1 << 7; private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 1 << 8; + private static final int HAS_MSL_ALTITUDE_MASK = 1 << 9; + private static final int HAS_MSL_ALTITUDE_ACCURACY_MASK = 1 << 10; // Cached data to make bearing/distance computations more efficient for the case // where distanceTo and bearingTo are called in sequence. Assume this typically happens @@ -118,6 +120,8 @@ public class Location implements Parcelable { private float mSpeedAccuracyMetersPerSecond; private float mBearingDegrees; private float mBearingAccuracyDegrees; + private double mMslAltitudeMeters; + private float mMslAltitudeAccuracyMeters; private Bundle mExtras = null; @@ -156,6 +160,8 @@ public class Location implements Parcelable { mSpeedAccuracyMetersPerSecond = location.mSpeedAccuracyMetersPerSecond; mBearingDegrees = location.mBearingDegrees; mBearingAccuracyDegrees = location.mBearingAccuracyDegrees; + mMslAltitudeMeters = location.mMslAltitudeMeters; + mMslAltitudeAccuracyMeters = location.mMslAltitudeAccuracyMeters; mExtras = (location.mExtras == null) ? null : new Bundle(location.mExtras); } @@ -178,6 +184,8 @@ public class Location implements Parcelable { mAltitudeAccuracyMeters = 0; mSpeedAccuracyMetersPerSecond = 0; mBearingAccuracyDegrees = 0; + mMslAltitudeMeters = 0; + mMslAltitudeAccuracyMeters = 0; mExtras = null; } @@ -689,6 +697,75 @@ public class Location implements Parcelable { mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK; } + /** + * Returns the Mean Sea Level altitude of this location in meters. + * + *

This is only valid if {@link #hasMslAltitude()} is true. + */ + public @FloatRange double getMslAltitudeMeters() { + Preconditions.checkState(hasMslAltitude(), + "The Mean Sea Level altitude of this location is not set."); + return mMslAltitudeMeters; + } + + /** + * Sets the Mean Sea Level altitude of this location in meters. + */ + public void setMslAltitudeMeters(@FloatRange double mslAltitudeMeters) { + mMslAltitudeMeters = mslAltitudeMeters; + mFieldsMask |= HAS_MSL_ALTITUDE_MASK; + } + + /** + * Returns true if this location has a Mean Sea Level altitude, false otherwise. + */ + public boolean hasMslAltitude() { + return (mFieldsMask & HAS_MSL_ALTITUDE_MASK) != 0; + } + + /** + * Removes the Mean Sea Level altitude from this location. + */ + public void removeMslAltitude() { + mFieldsMask &= ~HAS_MSL_ALTITUDE_MASK; + } + + /** + * Returns the estimated Mean Sea Level altitude accuracy in meters of this location at the 68th + * percentile confidence level. This means that there is 68% chance that the true Mean Sea Level + * altitude of this location falls within {@link #getMslAltitudeMeters()} +/- this uncertainty. + * + *

This is only valid if {@link #hasMslAltitudeAccuracy()} is true. + */ + public @FloatRange(from = 0.0) float getMslAltitudeAccuracyMeters() { + Preconditions.checkState(hasMslAltitudeAccuracy(), + "The Mean Sea Level altitude accuracy of this location is not set."); + return mMslAltitudeAccuracyMeters; + } + + /** + * Sets the Mean Sea Level altitude accuracy of this location in meters. + */ + public void setMslAltitudeAccuracyMeters( + @FloatRange(from = 0.0) float mslAltitudeAccuracyMeters) { + mMslAltitudeAccuracyMeters = mslAltitudeAccuracyMeters; + mFieldsMask |= HAS_MSL_ALTITUDE_ACCURACY_MASK; + } + + /** + * Returns true if this location has a Mean Sea Level altitude accuracy, false otherwise. + */ + public boolean hasMslAltitudeAccuracy() { + return (mFieldsMask & HAS_MSL_ALTITUDE_ACCURACY_MASK) != 0; + } + + /** + * Removes the Mean Sea Level altitude accuracy from this location. + */ + public void removeMslAltitudeAccuracy() { + mFieldsMask &= ~HAS_MSL_ALTITUDE_ACCURACY_MASK; + } + /** * Returns true if this is a mock location. If this location comes from the Android framework, * this indicates that the location was provided by a test location provider, and thus may not @@ -839,6 +916,14 @@ public class Location implements Parcelable { && hasBearingAccuracy() == location.hasBearingAccuracy() && (!hasBearingAccuracy() || Float.compare(location.mBearingAccuracyDegrees, mBearingAccuracyDegrees) == 0) + && hasMslAltitude() == location.hasMslAltitude() + && (!hasMslAltitude() || Double.compare(location.mMslAltitudeMeters, + mMslAltitudeMeters) + == 0) + && hasMslAltitudeAccuracy() == location.hasMslAltitudeAccuracy() + && (!hasMslAltitudeAccuracy() || Float.compare( + location.mMslAltitudeAccuracyMeters, + mMslAltitudeAccuracyMeters) == 0) && Objects.equals(mProvider, location.mProvider) && areExtrasEqual(mExtras, location.mExtras); } @@ -876,6 +961,12 @@ public class Location implements Parcelable { s.append(" vAcc=").append(mAltitudeAccuracyMeters); } } + if (hasMslAltitude()) { + s.append(" mslAlt=").append(mMslAltitudeMeters); + if (hasMslAltitudeAccuracy()) { + s.append(" mslAltAcc=").append(mMslAltitudeAccuracyMeters); + } + } if (hasSpeed()) { s.append(" vel=").append(mSpeedMetersPerSecond); if (hasSpeedAccuracy()) { @@ -944,6 +1035,12 @@ public class Location implements Parcelable { if (l.hasBearingAccuracy()) { l.mBearingAccuracyDegrees = in.readFloat(); } + if (l.hasMslAltitude()) { + l.mMslAltitudeMeters = in.readDouble(); + } + if (l.hasMslAltitudeAccuracy()) { + l.mMslAltitudeAccuracyMeters = in.readFloat(); + } l.mExtras = Bundle.setDefusable(in.readBundle(), true); return l; } @@ -991,6 +1088,12 @@ public class Location implements Parcelable { if (hasBearingAccuracy()) { parcel.writeFloat(mBearingAccuracyDegrees); } + if (hasMslAltitude()) { + parcel.writeDouble(mMslAltitudeMeters); + } + if (hasMslAltitudeAccuracy()) { + parcel.writeFloat(mMslAltitudeAccuracyMeters); + } parcel.writeBundle(mExtras); }