FileDocCategorySizeDatePackage
Location.javaAPI DocAndroid 5.1 API32037Thu Mar 12 22:22:30 GMT 2015android.location

Location

public class Location extends Object implements android.os.Parcelable
A data class representing a geographic location.

A location can consist of a latitude, longitude, timestamp, and other information such as bearing, altitude and velocity.

All locations generated by the {@link LocationManager} are guaranteed to have a valid latitude, longitude, and timestamp (both UTC time and elapsed real-time since boot), all other parameters are optional.

Fields Summary
public static final int
FORMAT_DEGREES
Constant used to specify formatting of a latitude or longitude in the form "[+-]DDD.DDDDD where D indicates degrees.
public static final int
FORMAT_MINUTES
Constant used to specify formatting of a latitude or longitude in the form "[+-]DDD:MM.MMMMM" where D indicates degrees and M indicates minutes of arc (1 minute = 1/60th of a degree).
public static final int
FORMAT_SECONDS
Constant used to specify formatting of a latitude or longitude in the form "DDD:MM:SS.SSSSS" where D indicates degrees, M indicates minutes of arc, and S indicates seconds of arc (1 minute = 1/60th of a degree, 1 second = 1/3600th of a degree).
public static final String
EXTRA_COARSE_LOCATION
Bundle key for a version of the location that has been fed through LocationFudger. Allows location providers to flag locations as being safe for use with ACCESS_COARSE_LOCATION permission.
public static final String
EXTRA_NO_GPS_LOCATION
Bundle key for a version of the location containing no GPS data. Allows location providers to flag locations as being safe to feed to LocationFudger.
private String
mProvider
private long
mTime
private long
mElapsedRealtimeNanos
private double
mLatitude
private double
mLongitude
private boolean
mHasAltitude
private double
mAltitude
private boolean
mHasSpeed
private float
mSpeed
private boolean
mHasBearing
private float
mBearing
private boolean
mHasAccuracy
private float
mAccuracy
private android.os.Bundle
mExtras
private boolean
mIsFromMockProvider
private double
mLat1
private double
mLon1
private double
mLat2
private double
mLon2
private float
mDistance
private float
mInitialBearing
private final float[]
mResults
public static final Parcelable.Creator
CREATOR
Constructors Summary
public Location(String provider)
Construct a new Location with a named provider.

By default time, latitude and longitude are 0, and the location has no bearing, altitude, speed, accuracy or extras.

param
provider the name of the provider that generated this location


                                               
       
        mProvider = provider;
    
public Location(Location l)
Construct a new Location object that is copied from an existing one.

        set(l);
    
Methods Summary
public floatbearingTo(android.location.Location dest)
Returns the approximate initial bearing in degrees East of true North when traveling along the shortest path between this location and the given location. The shortest path is defined using the WGS84 ellipsoid. Locations that are (nearly) antipodal may produce meaningless results.

param
dest the destination location
return
the initial bearing in degrees

        synchronized (mResults) {
            // See if we already have the result
            if (mLatitude != mLat1 || mLongitude != mLon1 ||
                            dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
                computeDistanceAndBearing(mLatitude, mLongitude,
                    dest.mLatitude, dest.mLongitude, mResults);
                mLat1 = mLatitude;
                mLon1 = mLongitude;
                mLat2 = dest.mLatitude;
                mLon2 = dest.mLongitude;
                mDistance = mResults[0];
                mInitialBearing = mResults[1];
            }
            return mInitialBearing;
        }
    
private static voidcomputeDistanceAndBearing(double lat1, double lon1, double lat2, double lon2, float[] results)

        // Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
        // using the "Inverse Formula" (section 4)

        int MAXITERS = 20;
        // Convert lat/long to radians
        lat1 *= Math.PI / 180.0;
        lat2 *= Math.PI / 180.0;
        lon1 *= Math.PI / 180.0;
        lon2 *= Math.PI / 180.0;

        double a = 6378137.0; // WGS84 major axis
        double b = 6356752.3142; // WGS84 semi-major axis
        double f = (a - b) / a;
        double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);

        double L = lon2 - lon1;
        double A = 0.0;
        double U1 = Math.atan((1.0 - f) * Math.tan(lat1));
        double U2 = Math.atan((1.0 - f) * Math.tan(lat2));

        double cosU1 = Math.cos(U1);
        double cosU2 = Math.cos(U2);
        double sinU1 = Math.sin(U1);
        double sinU2 = Math.sin(U2);
        double cosU1cosU2 = cosU1 * cosU2;
        double sinU1sinU2 = sinU1 * sinU2;

        double sigma = 0.0;
        double deltaSigma = 0.0;
        double cosSqAlpha = 0.0;
        double cos2SM = 0.0;
        double cosSigma = 0.0;
        double sinSigma = 0.0;
        double cosLambda = 0.0;
        double sinLambda = 0.0;

        double lambda = L; // initial guess
        for (int iter = 0; iter < MAXITERS; iter++) {
            double lambdaOrig = lambda;
            cosLambda = Math.cos(lambda);
            sinLambda = Math.sin(lambda);
            double t1 = cosU2 * sinLambda;
            double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
            double sinSqSigma = t1 * t1 + t2 * t2; // (14)
            sinSigma = Math.sqrt(sinSqSigma);
            cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)
            sigma = Math.atan2(sinSigma, cosSigma); // (16)
            double sinAlpha = (sinSigma == 0) ? 0.0 :
                cosU1cosU2 * sinLambda / sinSigma; // (17)
            cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
            cos2SM = (cosSqAlpha == 0) ? 0.0 :
                cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)

            double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn
            A = 1 + (uSquared / 16384.0) * // (3)
                (4096.0 + uSquared *
                 (-768 + uSquared * (320.0 - 175.0 * uSquared)));
            double B = (uSquared / 1024.0) * // (4)
                (256.0 + uSquared *
                 (-128.0 + uSquared * (74.0 - 47.0 * uSquared)));
            double C = (f / 16.0) *
                cosSqAlpha *
                (4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)
            double cos2SMSq = cos2SM * cos2SM;
            deltaSigma = B * sinSigma * // (6)
                (cos2SM + (B / 4.0) *
                 (cosSigma * (-1.0 + 2.0 * cos2SMSq) -
                  (B / 6.0) * cos2SM *
                  (-3.0 + 4.0 * sinSigma * sinSigma) *
                  (-3.0 + 4.0 * cos2SMSq)));

            lambda = L +
                (1.0 - C) * f * sinAlpha *
                (sigma + C * sinSigma *
                 (cos2SM + C * cosSigma *
                  (-1.0 + 2.0 * cos2SM * cos2SM))); // (11)

            double delta = (lambda - lambdaOrig) / lambda;
            if (Math.abs(delta) < 1.0e-12) {
                break;
            }
        }

        float distance = (float) (b * A * (sigma - deltaSigma));
        results[0] = distance;
        if (results.length > 1) {
            float initialBearing = (float) Math.atan2(cosU2 * sinLambda,
                cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
            initialBearing *= 180.0 / Math.PI;
            results[1] = initialBearing;
            if (results.length > 2) {
                float finalBearing = (float) Math.atan2(cosU1 * sinLambda,
                    -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
                finalBearing *= 180.0 / Math.PI;
                results[2] = finalBearing;
            }
        }
    
public static java.lang.Stringconvert(double coordinate, int outputType)
Converts a coordinate to a String representation. The outputType may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS. The coordinate must be a valid double between -180.0 and 180.0.

throws
IllegalArgumentException if coordinate is less than -180.0, greater than 180.0, or is not a number.
throws
IllegalArgumentException if outputType is not one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.

        if (coordinate < -180.0 || coordinate > 180.0 ||
            Double.isNaN(coordinate)) {
            throw new IllegalArgumentException("coordinate=" + coordinate);
        }
        if ((outputType != FORMAT_DEGREES) &&
            (outputType != FORMAT_MINUTES) &&
            (outputType != FORMAT_SECONDS)) {
            throw new IllegalArgumentException("outputType=" + outputType);
        }

        StringBuilder sb = new StringBuilder();

        // Handle negative values
        if (coordinate < 0) {
            sb.append('-");
            coordinate = -coordinate;
        }

        DecimalFormat df = new DecimalFormat("###.#####");
        if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
            int degrees = (int) Math.floor(coordinate);
            sb.append(degrees);
            sb.append(':");
            coordinate -= degrees;
            coordinate *= 60.0;
            if (outputType == FORMAT_SECONDS) {
                int minutes = (int) Math.floor(coordinate);
                sb.append(minutes);
                sb.append(':");
                coordinate -= minutes;
                coordinate *= 60.0;
            }
        }
        sb.append(df.format(coordinate));
        return sb.toString();
    
public static doubleconvert(java.lang.String coordinate)
Converts a String in one of the formats described by FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a double.

throws
NullPointerException if coordinate is null
throws
IllegalArgumentException if the coordinate is not in one of the valid formats.

        // IllegalArgumentException if bad syntax
        if (coordinate == null) {
            throw new NullPointerException("coordinate");
        }

        boolean negative = false;
        if (coordinate.charAt(0) == '-") {
            coordinate = coordinate.substring(1);
            negative = true;
        }

        StringTokenizer st = new StringTokenizer(coordinate, ":");
        int tokens = st.countTokens();
        if (tokens < 1) {
            throw new IllegalArgumentException("coordinate=" + coordinate);
        }
        try {
            String degrees = st.nextToken();
            double val;
            if (tokens == 1) {
                val = Double.parseDouble(degrees);
                return negative ? -val : val;
            }

            String minutes = st.nextToken();
            int deg = Integer.parseInt(degrees);
            double min;
            double sec = 0.0;

            if (st.hasMoreTokens()) {
                min = Integer.parseInt(minutes);
                String seconds = st.nextToken();
                sec = Double.parseDouble(seconds);
            } else {
                min = Double.parseDouble(minutes);
            }

            boolean isNegative180 = negative && (deg == 180) &&
                (min == 0) && (sec == 0);

            // deg must be in [0, 179] except for the case of -180 degrees
            if ((deg < 0.0) || (deg > 179 && !isNegative180)) {
                throw new IllegalArgumentException("coordinate=" + coordinate);
            }
            if (min < 0 || min > 59) {
                throw new IllegalArgumentException("coordinate=" +
                        coordinate);
            }
            if (sec < 0 || sec > 59) {
                throw new IllegalArgumentException("coordinate=" +
                        coordinate);
            }

            val = deg*3600.0 + min*60.0 + sec;
            val /= 3600.0;
            return negative ? -val : val;
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException("coordinate=" + coordinate);
        }
    
public intdescribeContents()


    
       
        return 0;
    
public static voiddistanceBetween(double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
Computes the approximate distance in meters between two locations, and optionally the initial and final bearings of the shortest path between them. Distance and bearing are defined using the WGS84 ellipsoid.

The computed distance is stored in results[0]. If results has length 2 or greater, the initial bearing is stored in results[1]. If results has length 3 or greater, the final bearing is stored in results[2].

param
startLatitude the starting latitude
param
startLongitude the starting longitude
param
endLatitude the ending latitude
param
endLongitude the ending longitude
param
results an array of floats to hold the results
throws
IllegalArgumentException if results is null or has length < 1

        if (results == null || results.length < 1) {
            throw new IllegalArgumentException("results is null or has length < 1");
        }
        computeDistanceAndBearing(startLatitude, startLongitude,
            endLatitude, endLongitude, results);
    
public floatdistanceTo(android.location.Location dest)
Returns the approximate distance in meters between this location and the given location. Distance is defined using the WGS84 ellipsoid.

param
dest the destination location
return
the approximate distance in meters

        // See if we already have the result
        synchronized (mResults) {
            if (mLatitude != mLat1 || mLongitude != mLon1 ||
                dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
                computeDistanceAndBearing(mLatitude, mLongitude,
                    dest.mLatitude, dest.mLongitude, mResults);
                mLat1 = mLatitude;
                mLon1 = mLongitude;
                mLat2 = dest.mLatitude;
                mLon2 = dest.mLongitude;
                mDistance = mResults[0];
                mInitialBearing = mResults[1];
            }
            return mDistance;
        }
    
public voiddump(android.util.Printer pw, java.lang.String prefix)

        pw.println(prefix + toString());
    
public floatgetAccuracy()
Get the estimated accuracy of this location, in meters.

We define accuracy as the radius of 68% confidence. In other words, if you draw a circle centered at this location's latitude and longitude, and with a radius equal to the accuracy, then there is a 68% probability that the true location is inside the circle.

In statistical terms, it is assumed that location errors are random with a normal distribution, so the 68% confidence circle represents one standard deviation. Note that in practice, location errors do not always follow such a simple distribution.

This accuracy estimation is only concerned with horizontal accuracy, and does not indicate the accuracy of bearing, velocity or altitude if those are included in this Location.

If this location does not have an accuracy, then 0.0 is returned. All locations generated by the {@link LocationManager} include an accuracy.

        return mAccuracy;
    
public doublegetAltitude()
Get the altitude if available, in meters above the WGS 84 reference ellipsoid.

If this location does not have an altitude then 0.0 is returned.

        return mAltitude;
    
public floatgetBearing()
Get the bearing, in degrees.

Bearing is the horizontal direction of travel of this device, and is not related to the device orientation. It is guaranteed to be in the range (0.0, 360.0] if the device has a bearing.

If this location does not have a bearing then 0.0 is returned.

        return mBearing;
    
public longgetElapsedRealtimeNanos()
Return the time of this fix, in elapsed real-time since system boot.

This value can be reliably compared to {@link android.os.SystemClock#elapsedRealtimeNanos}, to calculate the age of a fix and to compare Location fixes. This is reliable because elapsed real-time is guaranteed monotonic for each system boot and continues to increment even when the system is in deep sleep (unlike {@link #getTime}.

All locations generated by the {@link LocationManager} are guaranteed to have a valid elapsed real-time.

return
elapsed real-time of fix, in nanoseconds since system boot.

        return mElapsedRealtimeNanos;
    
public android.location.LocationgetExtraLocation(java.lang.String key)
Returns one of the optional extra {@link Location}s that can be attached to this Location.

param
key the key associated with the desired extra Location
return
the extra Location, or null if unavailable
hide

        if (mExtras != null) {
            Parcelable value = mExtras.getParcelable(key);
            if (value instanceof Location) {
                return (Location) value;
            }
        }
        return null;
    
public android.os.BundlegetExtras()
Returns additional provider-specific information about the location fix as a Bundle. The keys and values are determined by the provider. If no additional information is available, null is returned.

A number of common key/value pairs are listed below. Providers that use any of the keys on this list must provide the corresponding value as described below.

  • satellites - the number of satellites used to derive the fix

        return mExtras;
    
public doublegetLatitude()
Get the latitude, in degrees.

All locations generated by the {@link LocationManager} will have a valid latitude.

        return mLatitude;
    
public doublegetLongitude()
Get the longitude, in degrees.

All locations generated by the {@link LocationManager} will have a valid longitude.

        return mLongitude;
    
public java.lang.StringgetProvider()
Returns the name of the provider that generated this fix.

return
the provider, or null if it has not been set

        return mProvider;
    
public floatgetSpeed()
Get the speed if it is available, in meters/second over ground.

If this location does not have a speed then 0.0 is returned.

        return mSpeed;
    
public longgetTime()
Return the UTC time of this fix, in milliseconds since January 1, 1970.

Note that the UTC time on a device is not monotonic: it can jump forwards or backwards unpredictably. So always use {@link #getElapsedRealtimeNanos} when calculating time deltas.

On the other hand, {@link #getTime} is useful for presenting a human readable time to the user, or for carefully comparing location fixes across reboot or across devices.

All locations generated by the {@link LocationManager} are guaranteed to have a valid UTC time, however remember that the system time may have changed since the location was generated.

return
time of fix, in milliseconds since January 1, 1970.

        return mTime;
    
public booleanhasAccuracy()
True if this location has an accuracy.

All locations generated by the {@link LocationManager} have an accuracy.

        return mHasAccuracy;
    
public booleanhasAltitude()
True if this location has an altitude.

        return mHasAltitude;
    
public booleanhasBearing()
True if this location has a bearing.

        return mHasBearing;
    
public booleanhasSpeed()
True if this location has a speed.

        return mHasSpeed;
    
public booleanisComplete()
Return true if this Location object is complete.

A location object is currently considered complete if it has a valid provider, accuracy, wall-clock time and elapsed real-time.

All locations supplied by the {@link LocationManager} to applications must be complete.

see
#makeComplete
hide

        if (mProvider == null) return false;
        if (!mHasAccuracy) return false;
        if (mTime == 0) return false;
        if (mElapsedRealtimeNanos == 0) return false;
        return true;
    
public booleanisFromMockProvider()
Returns true if the Location came from a mock provider.

return
true if this Location came from a mock provider, false otherwise

        return mIsFromMockProvider;
    
public voidmakeComplete()
Helper to fill incomplete fields.

Used to assist in backwards compatibility with Location objects received from applications.

see
#isComplete
hide

        if (mProvider == null) mProvider = "?";
        if (!mHasAccuracy) {
            mHasAccuracy = true;
            mAccuracy = 100.0f;
        }
        if (mTime == 0) mTime = System.currentTimeMillis();
        if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
    
public voidremoveAccuracy()
Remove the accuracy from this location.

Following this call {@link #hasAccuracy} will return false, and {@link #getAccuracy} will return 0.0.

        mAccuracy = 0.0f;
        mHasAccuracy = false;
    
public voidremoveAltitude()
Remove the altitude from this location.

Following this call {@link #hasAltitude} will return false, and {@link #getAltitude} will return 0.0.

        mAltitude = 0.0f;
        mHasAltitude = false;
    
public voidremoveBearing()
Remove the bearing from this location.

Following this call {@link #hasBearing} will return false, and {@link #getBearing} will return 0.0.

        mBearing = 0.0f;
        mHasBearing = false;
    
public voidremoveSpeed()
Remove the speed from this location.

Following this call {@link #hasSpeed} will return false, and {@link #getSpeed} will return 0.0.

        mSpeed = 0.0f;
        mHasSpeed = false;
    
public voidreset()
Clears the contents of the location.

        mProvider = null;
        mTime = 0;
        mElapsedRealtimeNanos = 0;
        mLatitude = 0;
        mLongitude = 0;
        mHasAltitude = false;
        mAltitude = 0;
        mHasSpeed = false;
        mSpeed = 0;
        mHasBearing = false;
        mBearing = 0;
        mHasAccuracy = false;
        mAccuracy = 0;
        mExtras = null;
        mIsFromMockProvider = false;
    
public voidset(android.location.Location l)
Sets the contents of the location to the values from the given location.

        mProvider = l.mProvider;
        mTime = l.mTime;
        mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
        mLatitude = l.mLatitude;
        mLongitude = l.mLongitude;
        mHasAltitude = l.mHasAltitude;
        mAltitude = l.mAltitude;
        mHasSpeed = l.mHasSpeed;
        mSpeed = l.mSpeed;
        mHasBearing = l.mHasBearing;
        mBearing = l.mBearing;
        mHasAccuracy = l.mHasAccuracy;
        mAccuracy = l.mAccuracy;
        mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
        mIsFromMockProvider = l.mIsFromMockProvider;
    
public voidsetAccuracy(float accuracy)
Set the estimated accuracy of this location, meters.

See {@link #getAccuracy} for the definition of accuracy.

Following this call {@link #hasAccuracy} will return true.

        mAccuracy = accuracy;
        mHasAccuracy = true;
    
public voidsetAltitude(double altitude)
Set the altitude, in meters above the WGS 84 reference ellipsoid.

Following this call {@link #hasAltitude} will return true.

        mAltitude = altitude;
        mHasAltitude = true;
    
public voidsetBearing(float bearing)
Set the bearing, in degrees.

Bearing is the horizontal direction of travel of this device, and is not related to the device orientation.

The input will be wrapped into the range (0.0, 360.0].

        while (bearing < 0.0f) {
            bearing += 360.0f;
        }
        while (bearing >= 360.0f) {
            bearing -= 360.0f;
        }
        mBearing = bearing;
        mHasBearing = true;
    
public voidsetElapsedRealtimeNanos(long time)
Set the time of this fix, in elapsed real-time since system boot.

param
time elapsed real-time of fix, in nanoseconds since system boot.

        mElapsedRealtimeNanos = time;
    
public voidsetExtraLocation(java.lang.String key, android.location.Location value)
Attaches an extra {@link Location} to this Location.

param
key the key associated with the Location extra
param
location the Location to attach
hide

        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putParcelable(key, value);
    
public voidsetExtras(android.os.Bundle extras)
Sets the extra information associated with this fix to the given Bundle.

        mExtras = (extras == null) ? null : new Bundle(extras);
    
public voidsetIsFromMockProvider(boolean isFromMockProvider)
Flag this Location as having come from a mock provider or not.

param
isFromMockProvider true if this Location came from a mock provider, false otherwise
hide

        mIsFromMockProvider = isFromMockProvider;
    
public voidsetLatitude(double latitude)
Set the latitude, in degrees.

        mLatitude = latitude;
    
public voidsetLongitude(double longitude)
Set the longitude, in degrees.

        mLongitude = longitude;
    
public voidsetProvider(java.lang.String provider)
Sets the name of the provider that generated this fix.

        mProvider = provider;
    
public voidsetSpeed(float speed)
Set the speed, in meters/second over ground.

Following this call {@link #hasSpeed} will return true.

        mSpeed = speed;
        mHasSpeed = true;
    
public voidsetTime(long time)
Set the UTC time of this fix, in milliseconds since January 1, 1970.

param
time UTC time of this fix, in milliseconds since January 1, 1970

        mTime = time;
    
public java.lang.StringtoString()

        StringBuilder s = new StringBuilder();
        s.append("Location[");
        s.append(mProvider);
        s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
        if (mHasAccuracy) s.append(String.format(" acc=%.0f", mAccuracy));
        else s.append(" acc=???");
        if (mTime == 0) {
            s.append(" t=?!?");
        }
        if (mElapsedRealtimeNanos == 0) {
            s.append(" et=?!?");
        } else {
            s.append(" et=");
            TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
        }
        if (mHasAltitude) s.append(" alt=").append(mAltitude);
        if (mHasSpeed) s.append(" vel=").append(mSpeed);
        if (mHasBearing) s.append(" bear=").append(mBearing);
        if (mIsFromMockProvider) s.append(" mock");

        if (mExtras != null) {
            s.append(" {").append(mExtras).append('}");
        }
        s.append(']");
        return s.toString();
    
public voidwriteToParcel(android.os.Parcel parcel, int flags)

        parcel.writeString(mProvider);
        parcel.writeLong(mTime);
        parcel.writeLong(mElapsedRealtimeNanos);
        parcel.writeDouble(mLatitude);
        parcel.writeDouble(mLongitude);
        parcel.writeInt(mHasAltitude ? 1 : 0);
        parcel.writeDouble(mAltitude);
        parcel.writeInt(mHasSpeed ? 1 : 0);
        parcel.writeFloat(mSpeed);
        parcel.writeInt(mHasBearing ? 1 : 0);
        parcel.writeFloat(mBearing);
        parcel.writeInt(mHasAccuracy ? 1 : 0);
        parcel.writeFloat(mAccuracy);
        parcel.writeBundle(mExtras);
        parcel.writeInt(mIsFromMockProvider? 1 : 0);