java.lang.Object
↳androidx.core.location.LocationCompat
Gradle dependencies
compile group: 'androidx.core', name: 'core', version: '1.9.0-alpha04'
- groupId: androidx.core
- artifactId: core
- version: 1.9.0-alpha04
Artifact androidx.core:core:1.9.0-alpha04 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_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 | 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 | 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 | 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 | 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).
Methods
public static long
getElapsedRealtimeNanos(Location location)
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 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 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 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.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import android.location.Location;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.SystemClock;
import androidx.annotation.DoNotInline;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
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";
@Nullable
private static Method sSetIsFromMockProviderMethod;
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.
*/
public static long getElapsedRealtimeNanos(@NonNull Location location) {
if (VERSION.SDK_INT >= 17) {
return Api17Impl.getElapsedRealtimeNanos(location);
} else {
return MILLISECONDS.toNanos(getElapsedRealtimeMillis(location));
}
}
/**
* 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) {
if (VERSION.SDK_INT >= 17) {
return NANOSECONDS.toMillis(Api17Impl.getElapsedRealtimeNanos(location));
} else {
long timeDeltaMs = System.currentTimeMillis() - location.getTime();
long elapsedRealtimeMs = SystemClock.elapsedRealtime();
if (timeDeltaMs < 0) {
// don't return an elapsed realtime from the future
return elapsedRealtimeMs;
} else if (timeDeltaMs > elapsedRealtimeMs) {
// don't return an elapsed realtime from before boot
return 0;
} else {
return elapsedRealtimeMs - timeDeltaMs;
}
}
}
/**
* 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 {
Bundle extras = location.getExtras();
if (extras == null) {
return false;
}
return extras.containsKey(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 {
Bundle extras = location.getExtras();
if (extras == null) {
location.setExtras(new Bundle());
extras = location.getExtras();
}
extras.putFloat(EXTRA_VERTICAL_ACCURACY, verticalAccuracyM);
}
}
/**
* 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 {
Bundle extras = location.getExtras();
if (extras == null) {
return false;
}
return extras.containsKey(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 {
Bundle extras = location.getExtras();
if (extras == null) {
location.setExtras(new Bundle());
extras = location.getExtras();
}
extras.putFloat(EXTRA_SPEED_ACCURACY, speedAccuracyMps);
}
}
/**
* 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 {
Bundle extras = location.getExtras();
if (extras == null) {
return false;
}
return extras.containsKey(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 {
Bundle extras = location.getExtras();
if (extras == null) {
location.setExtras(new Bundle());
extras = location.getExtras();
}
extras.putFloat(EXTRA_BEARING_ACCURACY, bearingAccuracyD);
}
}
/**
* 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
*/
public static boolean isMock(@NonNull Location location) {
if (VERSION.SDK_INT >= 18) {
return Api18Impl.isMock(location);
} else {
Bundle extras = location.getExtras();
if (extras == null) {
return false;
}
return extras.getBoolean(EXTRA_IS_MOCK, false);
}
}
/**
* 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.
*/
public static void setMock(@NonNull Location location, boolean mock) {
if (VERSION.SDK_INT >= 18) {
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);
}
} else {
Bundle extras = location.getExtras();
if (extras == null) {
if (mock) {
extras = new Bundle();
extras.putBoolean(EXTRA_IS_MOCK, true);
location.setExtras(extras);
}
} else {
if (mock) {
extras.putBoolean(EXTRA_IS_MOCK, true);
} else {
extras.remove(EXTRA_IS_MOCK);
if (extras.isEmpty()) {
location.setExtras(null);
}
}
}
}
}
@RequiresApi(26)
private static class Api26Impl {
private Api26Impl() {}
@DoNotInline
static boolean hasVerticalAccuracy(Location location) {
return location.hasVerticalAccuracy();
}
@DoNotInline
static float getVerticalAccuracyMeters(Location location) {
return location.getVerticalAccuracyMeters();
}
@DoNotInline
static void setVerticalAccuracyMeters(Location location, float verticalAccuracyM) {
location.setVerticalAccuracyMeters(verticalAccuracyM);
}
@DoNotInline
static boolean hasSpeedAccuracy(Location location) {
return location.hasSpeedAccuracy();
}
@DoNotInline
static float getSpeedAccuracyMetersPerSecond(Location location) {
return location.getSpeedAccuracyMetersPerSecond();
}
@DoNotInline
static void setSpeedAccuracyMetersPerSecond(Location location, float speedAccuracyMps) {
location.setSpeedAccuracyMetersPerSecond(speedAccuracyMps);
}
@DoNotInline
static boolean hasBearingAccuracy(Location location) {
return location.hasBearingAccuracy();
}
@DoNotInline
static float getBearingAccuracyDegrees(Location location) {
return location.getBearingAccuracyDegrees();
}
@DoNotInline
static void setBearingAccuracyDegrees(Location location, float bearingAccuracyD) {
location.setBearingAccuracyDegrees(bearingAccuracyD);
}
}
@RequiresApi(18)
private static class Api18Impl {
private Api18Impl() {}
@DoNotInline
static boolean isMock(Location location) {
return location.isFromMockProvider();
}
}
@RequiresApi(17)
private static class Api17Impl {
private Api17Impl() {}
@DoNotInline
static long getElapsedRealtimeNanos(Location location) {
return location.getElapsedRealtimeNanos();
}
}
private static Method getSetIsFromMockProviderMethod() throws NoSuchMethodException {
if (sSetIsFromMockProviderMethod == null) {
sSetIsFromMockProviderMethod = Location.class.getDeclaredMethod("setIsFromMockProvider",
boolean.class);
sSetIsFromMockProviderMethod.setAccessible(true);
}
return sSetIsFromMockProviderMethod;
}
}