java.lang.Object
↳androidx.core.location.LocationCompat
Gradle dependencies
compile group: 'androidx.core', name: 'core', version: '1.15.0-alpha02'
- groupId: androidx.core
 - artifactId: core
 - version: 1.15.0-alpha02
 
Artifact androidx.core:core:1.15.0-alpha02 it located at Google repository (https://maven.google.com/)
Androidx artifact mapping:
androidx.core:core com.android.support:support-compat
Overview
Helper for accessing features in .
Summary
| Fields | 
|---|
| public static final java.lang.String | EXTRA_BEARING_ACCURACY Constant used as a key to store bearing accuracy in  for
 Android SDK levels below Oreo (26).  | 
| public static final java.lang.String | EXTRA_IS_MOCK Constant used as a key to store mock location status in  for
 Android SDK levels below JBMR2 (18).  | 
| public static final java.lang.String | EXTRA_MSL_ALTITUDE Constant used as a key to store Mean Sea Level altitude in .  | 
| public static final java.lang.String | EXTRA_MSL_ALTITUDE_ACCURACY Constant used as a key to store Mean Sea Level altitude in .  | 
| public static final java.lang.String | EXTRA_SPEED_ACCURACY Constant used as a key to store speed accuracy in  for
 Android SDK levels below Oreo (26).  | 
| public static final java.lang.String | EXTRA_VERTICAL_ACCURACY Constant used as a key to store vertical accuracy in  for
 Android SDK levels below Oreo (26).  | 
| Methods | 
|---|
| public static float | getBearingAccuracyDegrees(Location location)
 Get the estimated bearing accuracy of this location in degrees.  | 
| public static long | getElapsedRealtimeMillis(Location location)
 Return the time of this fix, in milliseconds of elapsed real-time since system boot.  | 
| public static long | getElapsedRealtimeNanos(Location location)
 Return the time of this fix, in nanoseconds of elapsed real-time since system boot.  | 
| public static float | getMslAltitudeAccuracyMeters(Location location)
 Returns the estimated Mean Sea Level altitude accuracy in meters of the location at the 68th
 percentile confidence level.  | 
| public static double | getMslAltitudeMeters(Location location)
 Returns the Mean Sea Level altitude of the location in meters.  | 
| public static float | getSpeedAccuracyMetersPerSecond(Location location)
 Get the estimated speed accuracy of this location in meters per second.  | 
| public static float | getVerticalAccuracyMeters(Location location)
 Get the estimated vertical accuracy of this location in meters.  | 
| public static boolean | hasBearingAccuracy(Location location)
 Returns true if this location has a bearing accuracy.  | 
| public static boolean | hasMslAltitude(Location location)
 Returns true if the location has a Mean Sea Level altitude, false otherwise.  | 
| public static boolean | hasMslAltitudeAccuracy(Location location)
 Returns true if the location has a Mean Sea Level altitude accuracy, false otherwise.  | 
| public static boolean | hasSpeedAccuracy(Location location)
 Returns true if this location has a speed accuracy.  | 
| public static boolean | hasVerticalAccuracy(Location location)
 Returns true if this location has a vertical accuracy.  | 
| public static boolean | isMock(Location location)
 Returns true if this location is marked as a mock location.  | 
| public static void | removeBearingAccuracy(Location location)
 Removes the bearing accuracy from the location.  | 
| public static void | removeMslAltitude(Location location)
 Removes the Mean Sea Level altitude from the location.  | 
| public static void | removeMslAltitudeAccuracy(Location location)
 Removes the Mean Sea Level altitude accuracy from the location.  | 
| public static void | removeSpeedAccuracy(Location location)
 Removes the speed accuracy from the location.  | 
| public static void | removeVerticalAccuracy(Location location)
 Removes the vertical accuracy from the location.  | 
| public static void | setBearingAccuracyDegrees(Location location, float bearingAccuracyD)
 Set the estimated bearing accuracy of this location in degrees.  | 
| public static void | setMock(Location location, boolean mock)
 Sets whether this location is marked as a mock location.  | 
| public static void | setMslAltitudeAccuracyMeters(Location location, float mslAltitudeAccuracyMeters)
 Sets the Mean Sea Level altitude accuracy of the location in meters.  | 
| public static void | setMslAltitudeMeters(Location location, double mslAltitudeMeters)
 Sets the Mean Sea Level altitude of the location in meters.  | 
| public static void | setSpeedAccuracyMetersPerSecond(Location location, float speedAccuracyMps)
 Set the estimated speed accuracy of this location in meters per second.  | 
| public static void | setVerticalAccuracyMeters(Location location, float verticalAccuracyM)
 Set the estimated vertical accuracy of this location in meters.  | 
| from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | 
Fields
public static final java.lang.String 
EXTRA_IS_MOCKConstant used as a key to store mock location status in  for
 Android SDK levels below JBMR2 (18).
public static final java.lang.String 
EXTRA_VERTICAL_ACCURACYConstant used as a key to store vertical accuracy in  for
 Android SDK levels below Oreo (26).
public static final java.lang.String 
EXTRA_SPEED_ACCURACYConstant used as a key to store speed accuracy in  for
 Android SDK levels below Oreo (26).
public static final java.lang.String 
EXTRA_BEARING_ACCURACYConstant used as a key to store bearing accuracy in  for
 Android SDK levels below Oreo (26).
public static final java.lang.String 
EXTRA_MSL_ALTITUDEConstant used as a key to store Mean Sea Level altitude in .
public static final java.lang.String 
EXTRA_MSL_ALTITUDE_ACCURACYConstant used as a key to store Mean Sea Level altitude in .
Methods
public static long 
getElapsedRealtimeNanos(Location location)
Deprecated: Call  directly.
Return the time of this fix, in nanoseconds of elapsed real-time since system boot.
 
This value can be reliably compared to 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 getTime().
 
All locations generated by the LocationManager are guaranteed to have a valid elapsed
 real-time.
 
NOTE: On API levels below 17, this method will attempt to provide an elapsed realtime
 based on the difference between system time and the location time. This should be taken as a
 best "guess" at what the elapsed realtime might have been, but if the clock used for
 location derivation is different from the system clock, the results may be inaccurate.
public static long 
getElapsedRealtimeMillis(Location location)
Return the time of this fix, in milliseconds of elapsed real-time since system boot.
See also: LocationCompat.getElapsedRealtimeNanos(Location)
public static boolean 
hasVerticalAccuracy(Location location)
Returns true if this location has a vertical accuracy.
See also: 
public static float 
getVerticalAccuracyMeters(Location location)
Get the estimated vertical accuracy of this location in meters.
 
NOTE: On API levels below 26, the concept of vertical accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to read a
 float extra with the key LocationCompat.EXTRA_VERTICAL_ACCURACY and return the result.
See also: 
public static void 
setVerticalAccuracyMeters(Location location, float verticalAccuracyM)
Set the estimated vertical accuracy of this location in meters.
 
NOTE: On API levels below 26, the concept of vertical accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to set a
 float extra with the key LocationCompat.EXTRA_VERTICAL_ACCURACY to include vertical accuracy. Be
 aware that this will overwrite any prior extra value under the same key.
See also: 
public static void 
removeVerticalAccuracy(Location location)
Removes the vertical accuracy from the location.
public static boolean 
hasSpeedAccuracy(Location location)
Returns true if this location has a speed accuracy.
See also: 
public static float 
getSpeedAccuracyMetersPerSecond(Location location)
Get the estimated speed accuracy of this location in meters per second.
 
NOTE: On API levels below 26, the concept of speed accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to read a
 float extra with the key LocationCompat.EXTRA_SPEED_ACCURACY and return the result.
See also: 
public static void 
setSpeedAccuracyMetersPerSecond(Location location, float speedAccuracyMps)
Set the estimated speed accuracy of this location in meters per second.
 
NOTE: On API levels below 26, the concept of speed accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to set a
 float extra with the key LocationCompat.EXTRA_SPEED_ACCURACY to include speed accuracy. Be
 aware that this will overwrite any prior extra value under the same key.
See also: 
public static void 
removeSpeedAccuracy(Location location)
Removes the speed accuracy from the location.
public static boolean 
hasBearingAccuracy(Location location)
Returns true if this location has a bearing accuracy.
See also: 
public static float 
getBearingAccuracyDegrees(Location location)
Get the estimated bearing accuracy of this location in degrees.
 
NOTE: On API levels below 26, the concept of bearing accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to read a
 float extra with the key LocationCompat.EXTRA_BEARING_ACCURACY and return the result.
See also: 
public static void 
setBearingAccuracyDegrees(Location location, float bearingAccuracyD)
Set the estimated bearing accuracy of this location in degrees.
 
NOTE: On API levels below 26, the concept of bearing accuracy does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to set a
 float extra with the key LocationCompat.EXTRA_BEARING_ACCURACY to include bearing accuracy. Be
 aware that this will overwrite any prior extra value under the same key.
See also: 
public static void 
removeBearingAccuracy(Location location)
Removes the bearing accuracy from the location.
public static double 
getMslAltitudeMeters(Location location)
Returns the Mean Sea Level altitude of the location in meters.
 
This is only valid if LocationCompat.hasMslAltitude(Location) is true.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
 order to allow for backwards compatibility and testing however, this method will attempt
 to read a double extra with the key LocationCompat.EXTRA_MSL_ALTITUDE and return the result.
See also: 
public static void 
setMslAltitudeMeters(Location location, double mslAltitudeMeters)
Sets the Mean Sea Level altitude of the location in meters.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
 order to allow for backwards compatibility and testing however, this method will attempt
 to set a double extra with the key LocationCompat.EXTRA_MSL_ALTITUDE to include Mean Sea Level
 altitude. Be aware that this will overwrite any prior extra value under the same key.
See also: 
public static boolean 
hasMslAltitude(Location location)
Returns true if the location has a Mean Sea Level altitude, false otherwise.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
 order to allow for backwards compatibility and testing however, this method will return
 true if an extra value is with the key LocationCompat.EXTRA_MSL_ALTITUDE.
See also: 
public static void 
removeMslAltitude(Location location)
Removes the Mean Sea Level altitude from the location.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
 order to allow for backwards compatibility and testing however, this method will attempt
 to remove any extra value with the key LocationCompat.EXTRA_MSL_ALTITUDE.
See also: 
public static float 
getMslAltitudeAccuracyMeters(Location location)
Returns the estimated Mean Sea Level altitude accuracy in meters of the location at the 68th
 percentile confidence level. This means that there is 68% chance that the true Mean Sea Level
 altitude of the location falls within LocationCompat.getMslAltitudeMeters(Location) +/- this
 uncertainty.
 
This is only valid if LocationCompat.hasMslAltitudeAccuracy(Location) is true.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
 exist. In order to allow for backwards compatibility and testing however, this method will
 attempt to read a float extra with the key LocationCompat.EXTRA_MSL_ALTITUDE_ACCURACY and return
 the result.
See also: 
public static void 
setMslAltitudeAccuracyMeters(Location location, float mslAltitudeAccuracyMeters)
Sets the Mean Sea Level altitude accuracy of the location in meters.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
 exist. In order to allow for backwards compatibility and testing however, this method will
 attempt to set a float extra with the key LocationCompat.EXTRA_MSL_ALTITUDE_ACCURACY to include
 Mean Sea Level altitude accuracy. Be aware that this will overwrite any prior extra value
 under the same key.
See also: 
public static boolean 
hasMslAltitudeAccuracy(Location location)
Returns true if the location has a Mean Sea Level altitude accuracy, false otherwise.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
 exist. In order to allow for backwards compatibility and testing however, this method will
 return true if an extra value is with the key LocationCompat.EXTRA_MSL_ALTITUDE_ACCURACY.
See also: 
public static void 
removeMslAltitudeAccuracy(Location location)
Removes the Mean Sea Level altitude accuracy from the location.
 
NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
 exist. In order to allow for backwards compatibility and testing however, this method will
 attempt to remove any extra value with the key LocationCompat.EXTRA_MSL_ALTITUDE_ACCURACY.
See also: 
public static boolean 
isMock(Location location)
Returns true if this location is marked as 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 be related to the actual location of the device.
 
NOTE: On API levels below 18, the concept of a mock location does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to read a
 boolean extra with the key LocationCompat.EXTRA_IS_MOCK and use the result to determine whether
 this should be considered a mock location.
See also: 
public static void 
setMock(Location location, boolean mock)
Sets whether this location is marked as a mock location.
 
NOTE: On API levels below 18, the concept of a mock location does not exist. In order to
 allow for backwards compatibility and testing however, this method will attempt to set a
 boolean extra with the key LocationCompat.EXTRA_IS_MOCK to mark the location as mock. Be aware that
 this will overwrite any prior extra value under the same key.
Source
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.core.location;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import android.annotation.SuppressLint;
import android.location.Location;
import android.os.Build.VERSION;
import android.os.Bundle;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * Helper for accessing features in {@link android.location.Location}.
 */
public final class LocationCompat {
    /**
     * Constant used as a key to store mock location status in {@link Location#getExtras()} for
     * Android SDK levels below JBMR2 (18).
     */
    @SuppressWarnings("ActionValue") // legacy value
    public static final String EXTRA_IS_MOCK = "mockLocation";
    /**
     * Constant used as a key to store vertical accuracy in {@link Location#getExtras()} for
     * Android SDK levels below Oreo (26).
     */
    @SuppressWarnings("ActionValue") // legacy value
    public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
    /**
     * Constant used as a key to store speed accuracy in {@link Location#getExtras()} for
     * Android SDK levels below Oreo (26).
     */
    @SuppressWarnings("ActionValue") // legacy value
    public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
    /**
     * Constant used as a key to store bearing accuracy in {@link Location#getExtras()} for
     * Android SDK levels below Oreo (26).
     */
    @SuppressWarnings("ActionValue") // legacy value
    public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
    /**
     * Constant used as a key to store Mean Sea Level altitude in {@link Location#getExtras()}.
     */
    public static final String EXTRA_MSL_ALTITUDE = "androidx.core.location.extra.MSL_ALTITUDE";
    /**
     * Constant used as a key to store Mean Sea Level altitude in {@link Location#getExtras()}.
     */
    public static final String EXTRA_MSL_ALTITUDE_ACCURACY =
            "androidx.core.location.extra.MSL_ALTITUDE_ACCURACY";
    @Nullable
    private static Method sSetIsFromMockProviderMethod;
    @Nullable
    private static Field sFieldsMaskField;
    @Nullable
    private static Integer sHasSpeedAccuracyMask;
    @Nullable
    private static Integer sHasBearingAccuracyMask;
    @Nullable
    private static Integer sHasVerticalAccuracyMask;
    private LocationCompat() {
    }
    /**
     * Return the time of this fix, in nanoseconds of elapsed real-time since system boot.
     *
     * <p>This value can be reliably compared to 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 getTime().
     *
     * <p>All locations generated by the LocationManager are guaranteed to have a valid elapsed
     * real-time.
     *
     * <p>NOTE: On API levels below 17, this method will attempt to provide an elapsed realtime
     * based on the difference between system time and the location time. This should be taken as a
     * best "guess" at what the elapsed realtime might have been, but if the clock used for
     * location derivation is different from the system clock, the results may be inaccurate.
     * @deprecated Call {@link Location#getElapsedRealtimeNanos()} directly.
     */
    @Deprecated
    @androidx.annotation.ReplaceWith(expression = "location.getElapsedRealtimeNanos()")
    public static long getElapsedRealtimeNanos(@NonNull Location location) {
        return location.getElapsedRealtimeNanos();
    }
    /**
     * Return the time of this fix, in milliseconds of elapsed real-time since system boot.
     *
     * @see #getElapsedRealtimeNanos(Location)
     */
    public static long getElapsedRealtimeMillis(@NonNull Location location) {
        return NANOSECONDS.toMillis(location.getElapsedRealtimeNanos());
    }
    /**
     * Returns true if this location has a vertical accuracy.
     *
     * @see Location#hasVerticalAccuracy()
     */
    public static boolean hasVerticalAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.hasVerticalAccuracy(location);
        } else {
            return containsExtra(location, EXTRA_VERTICAL_ACCURACY);
        }
    }
    /**
     * Get the estimated vertical accuracy of this location in meters.
     *
     * <p>NOTE: On API levels below 26, the concept of vertical accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to read a
     * float extra with the key {@link #EXTRA_VERTICAL_ACCURACY} and return the result.
     *
     * @see Location#getVerticalAccuracyMeters()
     */
    public static float getVerticalAccuracyMeters(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.getVerticalAccuracyMeters(location);
        } else {
            Bundle extras = location.getExtras();
            if (extras == null) {
                return 0.0f;
            }
            return extras.getFloat(EXTRA_VERTICAL_ACCURACY, 0.0f);
        }
    }
    /**
     * Set the estimated vertical accuracy of this location in meters.
     *
     * <p>NOTE: On API levels below 26, the concept of vertical accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to set a
     * float extra with the key {@link #EXTRA_VERTICAL_ACCURACY} to include vertical accuracy. Be
     * aware that this will overwrite any prior extra value under the same key.
     *
     * @see Location#setVerticalAccuracyMeters(float)
     */
    public static void setVerticalAccuracyMeters(@NonNull Location location,
            float verticalAccuracyM) {
        if (VERSION.SDK_INT >= 26) {
            Api26Impl.setVerticalAccuracyMeters(location, verticalAccuracyM);
        } else {
            getOrCreateExtras(location).putFloat(EXTRA_VERTICAL_ACCURACY, verticalAccuracyM);
        }
    }
    /**
     * Removes the vertical accuracy from the location.
     */
    public static void removeVerticalAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 33) {
            Api33Impl.removeVerticalAccuracy(location);
        } else if (VERSION.SDK_INT >= 29) {
            Api29Impl.removeVerticalAccuracy(location);
        } else if (VERSION.SDK_INT >= 28) {
            Api28Impl.removeVerticalAccuracy(location);
        } else if (VERSION.SDK_INT >= 26) {
            Api26Impl.removeVerticalAccuracy(location);
        } else {
            removeExtra(location, EXTRA_VERTICAL_ACCURACY);
        }
    }
    /**
     * Returns true if this location has a speed accuracy.
     *
     * @see Location#hasSpeedAccuracy()
     */
    public static boolean hasSpeedAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.hasSpeedAccuracy(location);
        } else {
            return containsExtra(location, EXTRA_SPEED_ACCURACY);
        }
    }
    /**
     * Get the estimated speed accuracy of this location in meters per second.
     *
     * <p>NOTE: On API levels below 26, the concept of speed accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to read a
     * float extra with the key {@link #EXTRA_SPEED_ACCURACY} and return the result.
     *
     * @see Location#getSpeedAccuracyMetersPerSecond()
     */
    public static float getSpeedAccuracyMetersPerSecond(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.getSpeedAccuracyMetersPerSecond(location);
        } else {
            Bundle extras = location.getExtras();
            if (extras == null) {
                return 0.0f;
            }
            return extras.getFloat(EXTRA_SPEED_ACCURACY, 0.0f);
        }
    }
    /**
     * Set the estimated speed accuracy of this location in meters per second.
     *
     * <p>NOTE: On API levels below 26, the concept of speed accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to set a
     * float extra with the key {@link #EXTRA_SPEED_ACCURACY} to include speed accuracy. Be
     * aware that this will overwrite any prior extra value under the same key.
     *
     * @see Location#setSpeedAccuracyMetersPerSecond(float)
     */
    public static void setSpeedAccuracyMetersPerSecond(@NonNull Location location,
            float speedAccuracyMps) {
        if (VERSION.SDK_INT >= 26) {
            Api26Impl.setSpeedAccuracyMetersPerSecond(location, speedAccuracyMps);
        } else {
            getOrCreateExtras(location).putFloat(EXTRA_SPEED_ACCURACY, speedAccuracyMps);
        }
    }
    /**
     * Removes the speed accuracy from the location.
     */
    public static void removeSpeedAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 33) {
            Api33Impl.removeSpeedAccuracy(location);
        }  else if (VERSION.SDK_INT >= 29) {
            Api29Impl.removeSpeedAccuracy(location);
        }  else if (VERSION.SDK_INT >= 28) {
            Api28Impl.removeSpeedAccuracy(location);
        } else if (VERSION.SDK_INT >= 26) {
            Api26Impl.removeSpeedAccuracy(location);
        } else {
            removeExtra(location, EXTRA_SPEED_ACCURACY);
        }
    }
    /**
     * Returns true if this location has a bearing accuracy.
     *
     * @see Location#hasBearingAccuracy()
     */
    public static boolean hasBearingAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.hasBearingAccuracy(location);
        } else {
            return containsExtra(location, EXTRA_BEARING_ACCURACY);
        }
    }
    /**
     * Get the estimated bearing accuracy of this location in degrees.
     *
     * <p>NOTE: On API levels below 26, the concept of bearing accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to read a
     * float extra with the key {@link #EXTRA_BEARING_ACCURACY} and return the result.
     *
     * @see Location#getBearingAccuracyDegrees()
     */
    public static float getBearingAccuracyDegrees(@NonNull Location location) {
        if (VERSION.SDK_INT >= 26) {
            return Api26Impl.getBearingAccuracyDegrees(location);
        } else {
            Bundle extras = location.getExtras();
            if (extras == null) {
                return 0.0f;
            }
            return extras.getFloat(EXTRA_BEARING_ACCURACY, 0.0f);
        }
    }
    /**
     * Set the estimated bearing accuracy of this location in degrees.
     *
     * <p>NOTE: On API levels below 26, the concept of bearing accuracy does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to set a
     * float extra with the key {@link #EXTRA_BEARING_ACCURACY} to include bearing accuracy. Be
     * aware that this will overwrite any prior extra value under the same key.
     *
     * @see Location#setBearingAccuracyDegrees(float)
     */
    public static void setBearingAccuracyDegrees(@NonNull Location location,
            float bearingAccuracyD) {
        if (VERSION.SDK_INT >= 26) {
            Api26Impl.setBearingAccuracyDegrees(location, bearingAccuracyD);
        } else {
            getOrCreateExtras(location).putFloat(EXTRA_BEARING_ACCURACY, bearingAccuracyD);
        }
    }
    /**
     * Removes the bearing accuracy from the location.
     */
    public static void removeBearingAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 33) {
            Api33Impl.removeBearingAccuracy(location);
        } else if (VERSION.SDK_INT >= 29) {
            Api29Impl.removeBearingAccuracy(location);
        } else if (VERSION.SDK_INT >= 28) {
            Api28Impl.removeBearingAccuracy(location);
        } else if (VERSION.SDK_INT >= 26) {
            Api26Impl.removeBearingAccuracy(location);
        } else {
            removeExtra(location, EXTRA_BEARING_ACCURACY);
        }
    }
    /**
     * Returns the Mean Sea Level altitude of the location in meters.
     *
     * <p>This is only valid if {@link #hasMslAltitude(Location)} is true.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
     * order to allow for backwards compatibility and testing however, this method will attempt
     * to read a double extra with the key {@link #EXTRA_MSL_ALTITUDE} and return the result.
     *
     * @see Location#getMslAltitudeMeters()
     */
    public static double getMslAltitudeMeters(@NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            return Api34Impl.getMslAltitudeMeters(location);
        }
        return getOrCreateExtras(location).getDouble(EXTRA_MSL_ALTITUDE);
    }
    /**
     * Sets the Mean Sea Level altitude of the location in meters.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
     * order to allow for backwards compatibility and testing however, this method will attempt
     * to set a double extra with the key {@link #EXTRA_MSL_ALTITUDE} to include Mean Sea Level
     * altitude. Be aware that this will overwrite any prior extra value under the same key.
     *
     * @see Location#setMslAltitudeMeters(double)
     */
    public static void setMslAltitudeMeters(@NonNull Location location,
            double mslAltitudeMeters) {
        if (VERSION.SDK_INT >= 34) {
            Api34Impl.setMslAltitudeMeters(location, mslAltitudeMeters);
        } else {
            getOrCreateExtras(location).putDouble(EXTRA_MSL_ALTITUDE, mslAltitudeMeters);
        }
    }
    /**
     * Returns true if the location has a Mean Sea Level altitude, false otherwise.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
     * order to allow for backwards compatibility and testing however, this method will return
     * true if an extra value is with the key {@link #EXTRA_MSL_ALTITUDE}.
     *
     * @see Location#hasMslAltitude()
     */
    public static boolean hasMslAltitude(@NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            return Api34Impl.hasMslAltitude(location);
        }
        return containsExtra(location, EXTRA_MSL_ALTITUDE);
    }
    /**
     * Removes the Mean Sea Level altitude from the location.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
     * order to allow for backwards compatibility and testing however, this method will attempt
     * to remove any extra value with the key {@link #EXTRA_MSL_ALTITUDE}.
     *
     * @see Location#removeMslAltitude()
     */
    public static void removeMslAltitude(@NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            Api34Impl.removeMslAltitude(location);
        } else {
            removeExtra(location, EXTRA_MSL_ALTITUDE);
        }
    }
    /**
     * Returns the estimated Mean Sea Level altitude accuracy in meters of the location at the 68th
     * percentile confidence level. This means that there is 68% chance that the true Mean Sea Level
     * altitude of the location falls within {@link #getMslAltitudeMeters(Location)} +/- this
     * uncertainty.
     *
     * <p>This is only valid if {@link #hasMslAltitudeAccuracy(Location)} is true.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
     * exist. In order to allow for backwards compatibility and testing however, this method will
     * attempt to read a float extra with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY} and return
     * the result.
     *
     * @see Location#getMslAltitudeAccuracyMeters()
     */
    public static @FloatRange(from = 0.0) float getMslAltitudeAccuracyMeters(
            @NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            return Api34Impl.getMslAltitudeAccuracyMeters(location);
        }
        return getOrCreateExtras(location).getFloat(EXTRA_MSL_ALTITUDE_ACCURACY);
    }
    /**
     * Sets the Mean Sea Level altitude accuracy of the location in meters.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
     * exist. In order to allow for backwards compatibility and testing however, this method will
     * attempt to set a float extra with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY} to include
     * Mean Sea Level altitude accuracy. Be aware that this will overwrite any prior extra value
     * under the same key.
     *
     * @see Location#setMslAltitudeAccuracyMeters(float)
     */
    public static void setMslAltitudeAccuracyMeters(@NonNull Location location,
            @FloatRange(from = 0.0) float mslAltitudeAccuracyMeters) {
        if (VERSION.SDK_INT >= 34) {
            Api34Impl.setMslAltitudeAccuracyMeters(location, mslAltitudeAccuracyMeters);
        } else {
            getOrCreateExtras(location).putFloat(EXTRA_MSL_ALTITUDE_ACCURACY,
                    mslAltitudeAccuracyMeters);
        }
    }
    /**
     * Returns true if the location has a Mean Sea Level altitude accuracy, false otherwise.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
     * exist. In order to allow for backwards compatibility and testing however, this method will
     * return true if an extra value is with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY}.
     *
     * @see Location#hasMslAltitudeAccuracy()
     */
    public static boolean hasMslAltitudeAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            return Api34Impl.hasMslAltitudeAccuracy(location);
        }
        return containsExtra(location, EXTRA_MSL_ALTITUDE_ACCURACY);
    }
    /**
     * Removes the Mean Sea Level altitude accuracy from the location.
     *
     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
     * exist. In order to allow for backwards compatibility and testing however, this method will
     * attempt to remove any extra value with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY}.
     *
     * @see Location#removeMslAltitudeAccuracy()
     */
    public static void removeMslAltitudeAccuracy(@NonNull Location location) {
        if (VERSION.SDK_INT >= 34) {
            Api34Impl.removeMslAltitudeAccuracy(location);
        } else {
            removeExtra(location, EXTRA_MSL_ALTITUDE_ACCURACY);
        }
    }
    /**
     * Returns true if this location is marked as 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 be related to the actual location of the device.
     *
     * <p>NOTE: On API levels below 18, the concept of a mock location does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to read a
     * boolean extra with the key {@link #EXTRA_IS_MOCK} and use the result to determine whether
     * this should be considered a mock location.
     *
     * @see android.location.LocationManager#addTestProvider
     */
    @SuppressWarnings("deprecation")
    public static boolean isMock(@NonNull Location location) {
        if (VERSION.SDK_INT >= 31) {
            return Api31Impl.isMock(location);
        } else {
            return location.isFromMockProvider();
        }
    }
    /**
     * Sets whether this location is marked as a mock location.
     *
     * <p>NOTE: On API levels below 18, the concept of a mock location does not exist. In order to
     * allow for backwards compatibility and testing however, this method will attempt to set a
     * boolean extra with the key {@link #EXTRA_IS_MOCK} to mark the location as mock. Be aware that
     * this will overwrite any prior extra value under the same key.
     */
    @SuppressLint("BanUncheckedReflection")
    public static void setMock(@NonNull Location location, boolean mock) {
        try {
                getSetIsFromMockProviderMethod().invoke(location, mock);
            } catch (NoSuchMethodException e) {
                Error error = new NoSuchMethodError();
                error.initCause(e);
                throw error;
            } catch (IllegalAccessException e) {
                Error error = new IllegalAccessError();
                error.initCause(e);
                throw error;
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
    }
    @RequiresApi(34)
    private static class Api34Impl {
        private Api34Impl() {
        }
        static double getMslAltitudeMeters(Location location) {
            return location.getMslAltitudeMeters();
        }
        static void setMslAltitudeMeters(Location location, double mslAltitudeMeters) {
            location.setMslAltitudeMeters(mslAltitudeMeters);
        }
        static boolean hasMslAltitude(Location location) {
            return location.hasMslAltitude();
        }
        static void removeMslAltitude(Location location) {
            location.removeMslAltitude();
        }
        static float getMslAltitudeAccuracyMeters(Location location) {
            return location.getMslAltitudeAccuracyMeters();
        }
        static void setMslAltitudeAccuracyMeters(Location location,
                float mslAltitudeAccuracyMeters) {
            location.setMslAltitudeAccuracyMeters(mslAltitudeAccuracyMeters);
        }
        static boolean hasMslAltitudeAccuracy(Location location) {
            return location.hasMslAltitudeAccuracy();
        }
        static void removeMslAltitudeAccuracy(Location location) {
            location.removeMslAltitudeAccuracy();
        }
    }
    @RequiresApi(33)
    private static class Api33Impl {
        private Api33Impl() {}
        static void removeVerticalAccuracy(Location location) {
            location.removeVerticalAccuracy();
        }
        static void removeSpeedAccuracy(Location location) {
            location.removeSpeedAccuracy();
        }
        static void removeBearingAccuracy(Location location) {
            location.removeBearingAccuracy();
        }
    }
    @RequiresApi(29)
    private static class Api29Impl {
        private Api29Impl() {}
        static void removeVerticalAccuracy(Location location) {
            if (!location.hasVerticalAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            double elapsedRealtimeUncertaintyNs = location.getElapsedRealtimeUncertaintyNanos();
            Api28Impl.removeVerticalAccuracy(location);
            location.setElapsedRealtimeUncertaintyNanos(elapsedRealtimeUncertaintyNs);
        }
        static void removeSpeedAccuracy(Location location) {
            if (!location.hasSpeedAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            double elapsedRealtimeUncertaintyNs = location.getElapsedRealtimeUncertaintyNanos();
            Api28Impl.removeSpeedAccuracy(location);
            location.setElapsedRealtimeUncertaintyNanos(elapsedRealtimeUncertaintyNs);
        }
        static void removeBearingAccuracy(Location location) {
            if (!location.hasBearingAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            double elapsedRealtimeUncertaintyNs = location.getElapsedRealtimeUncertaintyNanos();
            Api28Impl.removeBearingAccuracy(location);
            location.setElapsedRealtimeUncertaintyNanos(elapsedRealtimeUncertaintyNs);
        }
    }
    @RequiresApi(28)
    private static class Api28Impl {
        private Api28Impl() {}
        static void removeVerticalAccuracy(Location location) {
            if (!location.hasVerticalAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            // (which unfortunately means a new Bundle will be created)
            String provider = location.getProvider();
            long time = location.getTime();
            long elapsedRealtimeNs = location.getElapsedRealtimeNanos();
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            boolean hasAltitude = location.hasAltitude();
            double altitude = location.getAltitude();
            boolean hasSpeed = location.hasSpeed();
            float speed = location.getSpeed();
            boolean hasBearing = location.hasBearing();
            float bearing = location.getBearing();
            boolean hasAccuracy = location.hasAccuracy();
            float accuracy = location.getAccuracy();
            boolean hasSpeedAccuracy = location.hasSpeedAccuracy();
            float speedAccuracy = location.getSpeedAccuracyMetersPerSecond();
            boolean hasBearingAccuracy = location.hasBearingAccuracy();
            float bearingAccuracy = location.getBearingAccuracyDegrees();
            Bundle extras = location.getExtras();
            location.reset();
            location.setProvider(provider);
            location.setTime(time);
            location.setElapsedRealtimeNanos(elapsedRealtimeNs);
            location.setLatitude(latitude);
            location.setLongitude(longitude);
            if (hasAltitude) {
                location.setAltitude(altitude);
            }
            if (hasSpeed) {
                location.setSpeed(speed);
            }
            if (hasBearing) {
                location.setBearing(bearing);
            }
            if (hasAccuracy) {
                location.setAccuracy(accuracy);
            }
            if (hasSpeedAccuracy) {
                location.setSpeedAccuracyMetersPerSecond(speedAccuracy);
            }
            if (hasBearingAccuracy) {
                location.setBearingAccuracyDegrees(bearingAccuracy);
            }
            if (extras != null) {
                location.setExtras(extras);
            }
        }
        static void removeSpeedAccuracy(Location location) {
            if (!location.hasSpeedAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            // (which unfortunately means a new Bundle will be created)
            String provider = location.getProvider();
            long time = location.getTime();
            long elapsedRealtimeNs = location.getElapsedRealtimeNanos();
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            boolean hasAltitude = location.hasAltitude();
            double altitude = location.getAltitude();
            boolean hasSpeed = location.hasSpeed();
            float speed = location.getSpeed();
            boolean hasBearing = location.hasBearing();
            float bearing = location.getBearing();
            boolean hasAccuracy = location.hasAccuracy();
            float accuracy = location.getAccuracy();
            boolean hasVerticalAccuracy = location.hasVerticalAccuracy();
            float verticalAccuracy = location.getVerticalAccuracyMeters();
            boolean hasBearingAccuracy = location.hasBearingAccuracy();
            float bearingAccuracy = location.getBearingAccuracyDegrees();
            Bundle extras = location.getExtras();
            location.reset();
            location.setProvider(provider);
            location.setTime(time);
            location.setElapsedRealtimeNanos(elapsedRealtimeNs);
            location.setLatitude(latitude);
            location.setLongitude(longitude);
            if (hasAltitude) {
                location.setAltitude(altitude);
            }
            if (hasSpeed) {
                location.setSpeed(speed);
            }
            if (hasBearing) {
                location.setBearing(bearing);
            }
            if (hasAccuracy) {
                location.setAccuracy(accuracy);
            }
            if (hasVerticalAccuracy) {
                location.setVerticalAccuracyMeters(verticalAccuracy);
            }
            if (hasBearingAccuracy) {
                location.setBearingAccuracyDegrees(bearingAccuracy);
            }
            if (extras != null) {
                location.setExtras(extras);
            }
        }
        static void removeBearingAccuracy(Location location) {
            if (!location.hasBearingAccuracy()) {
                return;
            }
            // reflection of non-SDK APIs doesn't work on P+, fallback to resetting the location
            // (which unfortunately means a new Bundle will be created)
            String provider = location.getProvider();
            long time = location.getTime();
            long elapsedRealtimeNs = location.getElapsedRealtimeNanos();
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            boolean hasAltitude = location.hasAltitude();
            double altitude = location.getAltitude();
            boolean hasSpeed = location.hasSpeed();
            float speed = location.getSpeed();
            boolean hasBearing = location.hasBearing();
            float bearing = location.getBearing();
            boolean hasAccuracy = location.hasAccuracy();
            float accuracy = location.getAccuracy();
            boolean hasVerticalAccuracy = location.hasVerticalAccuracy();
            float verticalAccuracy = location.getVerticalAccuracyMeters();
            boolean hasSpeedAccuracy = location.hasSpeedAccuracy();
            float speedAccuracy = location.getSpeedAccuracyMetersPerSecond();
            Bundle extras = location.getExtras();
            location.reset();
            location.setProvider(provider);
            location.setTime(time);
            location.setElapsedRealtimeNanos(elapsedRealtimeNs);
            location.setLatitude(latitude);
            location.setLongitude(longitude);
            if (hasAltitude) {
                location.setAltitude(altitude);
            }
            if (hasSpeed) {
                location.setSpeed(speed);
            }
            if (hasBearing) {
                location.setBearing(bearing);
            }
            if (hasAccuracy) {
                location.setAccuracy(accuracy);
            }
            if (hasVerticalAccuracy) {
                location.setVerticalAccuracyMeters(verticalAccuracy);
            }
            if (hasSpeedAccuracy) {
                location.setBearingAccuracyDegrees(speedAccuracy);
            }
            if (extras != null) {
                location.setExtras(extras);
            }
        }
    }
    @RequiresApi(26)
    private static class Api26Impl {
        private Api26Impl() {
        }
        static boolean hasVerticalAccuracy(Location location) {
            return location.hasVerticalAccuracy();
        }
        static float getVerticalAccuracyMeters(Location location) {
            return location.getVerticalAccuracyMeters();
        }
        static void setVerticalAccuracyMeters(Location location, float verticalAccuracyM) {
            location.setVerticalAccuracyMeters(verticalAccuracyM);
        }
        static void removeVerticalAccuracy(Location location) {
            try {
                byte fieldsMask = getFieldsMaskField().getByte(location);
                fieldsMask = (byte) (fieldsMask & ~getHasVerticalAccuracyMask());
                getFieldsMaskField().setByte(location, fieldsMask);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                Error error = new IllegalAccessError();
                error.initCause(e);
                throw error;
            }
        }
        static boolean hasSpeedAccuracy(Location location) {
            return location.hasSpeedAccuracy();
        }
        static float getSpeedAccuracyMetersPerSecond(Location location) {
            return location.getSpeedAccuracyMetersPerSecond();
        }
        static void setSpeedAccuracyMetersPerSecond(Location location, float speedAccuracyMps) {
            location.setSpeedAccuracyMetersPerSecond(speedAccuracyMps);
        }
        static void removeSpeedAccuracy(Location location) {
            try {
                byte fieldsMask = getFieldsMaskField().getByte(location);
                fieldsMask = (byte) (fieldsMask & ~getHasSpeedAccuracyMask());
                getFieldsMaskField().setByte(location, fieldsMask);
            } catch (NoSuchFieldException e) {
                Error error = new NoSuchFieldError();
                error.initCause(e);
                throw error;
            } catch (IllegalAccessException e) {
                Error error = new IllegalAccessError();
                error.initCause(e);
                throw error;
            }
        }
        static boolean hasBearingAccuracy(Location location) {
            return location.hasBearingAccuracy();
        }
        static float getBearingAccuracyDegrees(Location location) {
            return location.getBearingAccuracyDegrees();
        }
        static void setBearingAccuracyDegrees(Location location, float bearingAccuracyD) {
            location.setBearingAccuracyDegrees(bearingAccuracyD);
        }
        static void removeBearingAccuracy(Location location) {
            try {
                byte fieldsMask = getFieldsMaskField().getByte(location);
                fieldsMask = (byte) (fieldsMask & ~getHasBearingAccuracyMask());
                getFieldsMaskField().setByte(location, fieldsMask);
            } catch (NoSuchFieldException e) {
                Error error = new NoSuchFieldError();
                error.initCause(e);
                throw error;
            } catch (IllegalAccessException e) {
                Error error = new IllegalAccessError();
                error.initCause(e);
                throw error;
            }
        }
    }
    private static Method getSetIsFromMockProviderMethod() throws NoSuchMethodException {
        if (sSetIsFromMockProviderMethod == null) {
            sSetIsFromMockProviderMethod = Location.class.getDeclaredMethod("setIsFromMockProvider",
                    boolean.class);
            sSetIsFromMockProviderMethod.setAccessible(true);
        }
        return sSetIsFromMockProviderMethod;
    }
    @SuppressLint("BlockedPrivateApi")
    static Field getFieldsMaskField() throws NoSuchFieldException {
        if (sFieldsMaskField == null) {
            sFieldsMaskField = Location.class.getDeclaredField("mFieldsMask");
            sFieldsMaskField.setAccessible(true);
        }
        return sFieldsMaskField;
    }
    @SuppressLint("SoonBlockedPrivateApi")
    static int getHasSpeedAccuracyMask() throws NoSuchFieldException,
            IllegalAccessException {
        if (sHasSpeedAccuracyMask == null) {
            Field hasSpeedAccuracyMaskField = Location.class.getDeclaredField(
                    "HAS_SPEED_ACCURACY_MASK");
            hasSpeedAccuracyMaskField.setAccessible(true);
            sHasSpeedAccuracyMask = hasSpeedAccuracyMaskField.getInt(null);
        }
        return sHasSpeedAccuracyMask;
    }
    @SuppressLint("SoonBlockedPrivateApi")
    static int getHasBearingAccuracyMask()
            throws NoSuchFieldException, IllegalAccessException {
        if (sHasBearingAccuracyMask == null) {
            Field hasBearingAccuracyMaskField = Location.class.getDeclaredField(
                    "HAS_BEARING_ACCURACY_MASK");
            hasBearingAccuracyMaskField.setAccessible(true);
            sHasBearingAccuracyMask = hasBearingAccuracyMaskField.getInt(null);
        }
        return sHasBearingAccuracyMask;
    }
    @SuppressLint("SoonBlockedPrivateApi")
    static int getHasVerticalAccuracyMask()
            throws NoSuchFieldException, IllegalAccessException {
        if (sHasVerticalAccuracyMask == null) {
            Field hasVerticalAccuracyMaskField = Location.class.getDeclaredField(
                    "HAS_VERTICAL_ACCURACY_MASK");
            hasVerticalAccuracyMaskField.setAccessible(true);
            sHasVerticalAccuracyMask = hasVerticalAccuracyMaskField.getInt(null);
        }
        return sHasVerticalAccuracyMask;
    }
    private static Bundle getOrCreateExtras(@NonNull Location location) {
        Bundle extras = location.getExtras();
        if (extras == null) {
            location.setExtras(new Bundle());
            extras = location.getExtras();
        }
        return extras;
    }
    private static boolean containsExtra(@NonNull Location location, String key) {
        Bundle extras = location.getExtras();
        return extras != null && extras.containsKey(key);
    }
    private static void removeExtra(@NonNull Location location, String key) {
        Bundle extras = location.getExtras();
        if (extras != null) {
            extras.remove(key);
            if (extras.isEmpty()) {
                location.setExtras(null);
            }
        }
    }
    @RequiresApi(31)
    static class Api31Impl {
        private Api31Impl() {
            // This class is not instantiable.
        }
        static boolean isMock(Location location) {
            return location.isMock();
        }
    }
}