I ran these commands:
cd frameworks/base
grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \
's/\@SystemApi[\s\n]+(\@\w+[\s\n]+)?\@TestApi/\@SystemApi\1/gs'
grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \
's/\@TestApi[\s\n]+(\@\w+[\s\n]+)?\@SystemApi/\1\@SystemApi/gs'
Bug: 171179806
Test: m checkapi
Change-Id: I772790b783b0a8730b8bf680c9e569a886b8d789
Merged-In: I772790b783b0a8730b8bf680c9e569a886b8d789
798 lines
29 KiB
Java
798 lines
29 KiB
Java
/*
|
|
* Copyright (C) 2012 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 android.location;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.RequiresPermission;
|
|
import android.annotation.SystemApi;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.os.Build;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.os.SystemClock;
|
|
import android.os.WorkSource;
|
|
import android.util.TimeUtils;
|
|
|
|
import com.android.internal.util.Preconditions;
|
|
|
|
|
|
/**
|
|
* A data object that contains quality of service parameters for requests
|
|
* to the {@link LocationManager}.
|
|
*
|
|
* <p>LocationRequest objects are used to request a quality of service
|
|
* for location updates from the Location Manager.
|
|
*
|
|
* <p>For example, if your application wants high accuracy location
|
|
* it should create a location request with {@link #setQuality} set to
|
|
* {@link #ACCURACY_FINE} or {@link #POWER_HIGH}, and it should set
|
|
* {@link #setInterval} to less than one second. This would be
|
|
* appropriate for mapping applications that are showing your location
|
|
* in real-time.
|
|
*
|
|
* <p>At the other extreme, if you want negligible power
|
|
* impact, but to still receive location updates when available, then use
|
|
* {@link #setQuality} with {@link #POWER_NONE}. With this request your
|
|
* application will not trigger (and therefore will not receive any
|
|
* power blame) any location updates, but will receive locations
|
|
* triggered by other applications. This would be appropriate for
|
|
* applications that have no firm requirement for location, but can
|
|
* take advantage when available.
|
|
*
|
|
* <p>In between these two extremes is a very common use-case, where
|
|
* applications definitely want to receive
|
|
* updates at a specified interval, and can receive them faster when
|
|
* available, but still want a low power impact. These applications
|
|
* should consider {@link #POWER_LOW} combined with a faster
|
|
* {@link #setFastestInterval} (such as 1 minute) and a slower
|
|
* {@link #setInterval} (such as 60 minutes). They will only be assigned
|
|
* power blame for the interval set by {@link #setInterval}, but can
|
|
* still receive locations triggered by other applications at a rate up
|
|
* to {@link #setFastestInterval}. This style of request is appropriate for
|
|
* many location aware applications, including background usage. Do be
|
|
* careful to also throttle {@link #setFastestInterval} if you perform
|
|
* heavy-weight work after receiving an update - such as using the network.
|
|
*
|
|
* <p>Activities should strongly consider removing all location
|
|
* request when entering the background, or
|
|
* at least swap the request to a larger interval and lower quality.
|
|
* Future version of the location manager may automatically perform background
|
|
* throttling on behalf of applications.
|
|
*
|
|
* <p>Applications cannot specify the exact location sources that are
|
|
* used by Android's <em>Fusion Engine</em>. In fact, the system
|
|
* may have multiple location sources (providers) running and may
|
|
* fuse the results from several sources into a single Location object.
|
|
*
|
|
* <p>Location requests from applications with
|
|
* {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and not
|
|
* {@link android.Manifest.permission#ACCESS_FINE_LOCATION} will
|
|
* be automatically throttled to a slower interval, and the location
|
|
* object will be obfuscated to only show a coarse level of accuracy.
|
|
*
|
|
* <p>All location requests are considered hints, and you may receive
|
|
* locations that are more accurate, less accurate, and slower
|
|
* than requested.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public final class LocationRequest implements Parcelable {
|
|
/**
|
|
* Used with {@link #setQuality} to request the most accurate locations available.
|
|
*
|
|
* <p>This may be up to 1 meter accuracy, although this is implementation dependent.
|
|
*/
|
|
public static final int ACCURACY_FINE = 100;
|
|
|
|
/**
|
|
* Used with {@link #setQuality} to request "block" level accuracy.
|
|
*
|
|
* <p>Block level accuracy is considered to be about 100 meter accuracy,
|
|
* although this is implementation dependent. Using a coarse accuracy
|
|
* such as this often consumes less power.
|
|
*/
|
|
public static final int ACCURACY_BLOCK = 102;
|
|
|
|
/**
|
|
* Used with {@link #setQuality} to request "city" level accuracy.
|
|
*
|
|
* <p>City level accuracy is considered to be about 10km accuracy,
|
|
* although this is implementation dependent. Using a coarse accuracy
|
|
* such as this often consumes less power.
|
|
*/
|
|
public static final int ACCURACY_CITY = 104;
|
|
|
|
/**
|
|
* Used with {@link #setQuality} to require no direct power impact (passive locations).
|
|
*
|
|
* <p>This location request will not trigger any active location requests,
|
|
* but will receive locations triggered by other applications. Your application
|
|
* will not receive any direct power blame for location work.
|
|
*/
|
|
public static final int POWER_NONE = 200;
|
|
|
|
/**
|
|
* Used with {@link #setQuality} to request low power impact.
|
|
*
|
|
* <p>This location request will avoid high power location work where
|
|
* possible.
|
|
*/
|
|
public static final int POWER_LOW = 201;
|
|
|
|
/**
|
|
* Used with {@link #setQuality} to allow high power consumption for location.
|
|
*
|
|
* <p>This location request will allow high power location work.
|
|
*/
|
|
public static final int POWER_HIGH = 203;
|
|
|
|
private static final long DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
|
private static final double FASTEST_INTERVAL_FACTOR = 6.0; // 6x
|
|
|
|
@UnsupportedAppUsage
|
|
private String mProvider;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private int mQuality;
|
|
@UnsupportedAppUsage
|
|
private long mInterval;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private long mFastestInterval;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private boolean mExplicitFastestInterval;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private long mExpireAt;
|
|
private long mExpireIn;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private int mNumUpdates;
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private float mSmallestDisplacement;
|
|
@UnsupportedAppUsage
|
|
private boolean mHideFromAppOps;
|
|
private boolean mLocationSettingsIgnored;
|
|
private boolean mLowPowerMode;
|
|
@UnsupportedAppUsage
|
|
private @Nullable WorkSource mWorkSource;
|
|
|
|
/**
|
|
* Create a location request with default parameters.
|
|
*
|
|
* <p>Default parameters are for a low power, slowly updated location.
|
|
* It can then be adjusted as required by the applications before passing
|
|
* to the {@link LocationManager}
|
|
*
|
|
* @return a new location request
|
|
*/
|
|
@NonNull
|
|
public static LocationRequest create() {
|
|
return new LocationRequest();
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
@NonNull
|
|
public static LocationRequest createFromDeprecatedProvider(
|
|
@NonNull String provider, long minTime, float minDistance, boolean singleShot) {
|
|
Preconditions.checkArgument(provider != null, "invalid null provider");
|
|
|
|
if (minTime < 0) minTime = 0;
|
|
if (minDistance < 0) minDistance = 0;
|
|
|
|
int quality;
|
|
if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
|
|
quality = POWER_NONE;
|
|
} else if (LocationManager.GPS_PROVIDER.equals(provider)) {
|
|
quality = ACCURACY_FINE;
|
|
} else {
|
|
quality = POWER_LOW;
|
|
}
|
|
|
|
LocationRequest request = new LocationRequest()
|
|
.setProvider(provider)
|
|
.setQuality(quality)
|
|
.setInterval(minTime)
|
|
.setFastestInterval(minTime)
|
|
.setSmallestDisplacement(minDistance);
|
|
if (singleShot) request.setNumUpdates(1);
|
|
return request;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
@NonNull
|
|
public static LocationRequest createFromDeprecatedCriteria(
|
|
@NonNull Criteria criteria, long minTime, float minDistance, boolean singleShot) {
|
|
Preconditions.checkArgument(criteria != null, "invalid null criteria");
|
|
|
|
if (minTime < 0) minTime = 0;
|
|
if (minDistance < 0) minDistance = 0;
|
|
|
|
int quality;
|
|
switch (criteria.getAccuracy()) {
|
|
case Criteria.ACCURACY_COARSE:
|
|
quality = ACCURACY_BLOCK;
|
|
break;
|
|
case Criteria.ACCURACY_FINE:
|
|
quality = ACCURACY_FINE;
|
|
break;
|
|
default: {
|
|
if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) {
|
|
quality = POWER_HIGH;
|
|
} else {
|
|
quality = POWER_LOW;
|
|
}
|
|
}
|
|
}
|
|
|
|
LocationRequest request = new LocationRequest()
|
|
.setQuality(quality)
|
|
.setInterval(minTime)
|
|
.setFastestInterval(minTime)
|
|
.setSmallestDisplacement(minDistance);
|
|
if (singleShot) request.setNumUpdates(1);
|
|
return request;
|
|
}
|
|
|
|
/** @hide */
|
|
public LocationRequest() {
|
|
this(
|
|
/* provider= */ LocationManager.FUSED_PROVIDER,
|
|
/* quality= */ POWER_LOW,
|
|
/* interval= */ DEFAULT_INTERVAL_MS,
|
|
/* fastestInterval= */ (long) (DEFAULT_INTERVAL_MS / FASTEST_INTERVAL_FACTOR),
|
|
/* explicitFastestInterval= */ false,
|
|
/* expireAt= */ Long.MAX_VALUE,
|
|
/* expireIn= */ Long.MAX_VALUE,
|
|
/* numUpdates= */ Integer.MAX_VALUE,
|
|
/* smallestDisplacement= */ 0,
|
|
/* hideFromAppOps= */ false,
|
|
/* locationSettingsIgnored= */ false,
|
|
/* lowPowerMode= */ false,
|
|
/* workSource= */ null);
|
|
}
|
|
|
|
/** @hide */
|
|
public LocationRequest(LocationRequest src) {
|
|
this(
|
|
src.mProvider,
|
|
src.mQuality,
|
|
src.mInterval,
|
|
src.mFastestInterval,
|
|
src.mExplicitFastestInterval,
|
|
src.mExpireAt,
|
|
src.mExpireIn,
|
|
src.mNumUpdates,
|
|
src.mSmallestDisplacement,
|
|
src.mHideFromAppOps,
|
|
src.mLocationSettingsIgnored,
|
|
src.mLowPowerMode,
|
|
src.mWorkSource);
|
|
}
|
|
|
|
private LocationRequest(
|
|
@NonNull String provider,
|
|
int quality,
|
|
long intervalMs,
|
|
long fastestIntervalMs,
|
|
boolean explicitFastestInterval,
|
|
long expireAt,
|
|
long expireInMs,
|
|
int numUpdates,
|
|
float smallestDisplacementM,
|
|
boolean hideFromAppOps,
|
|
boolean locationSettingsIgnored,
|
|
boolean lowPowerMode,
|
|
WorkSource workSource) {
|
|
Preconditions.checkArgument(provider != null, "invalid provider: null");
|
|
checkQuality(quality);
|
|
|
|
mProvider = provider;
|
|
mQuality = quality;
|
|
mInterval = intervalMs;
|
|
mFastestInterval = fastestIntervalMs;
|
|
mExplicitFastestInterval = explicitFastestInterval;
|
|
mExpireAt = expireAt;
|
|
mExpireIn = expireInMs;
|
|
mNumUpdates = numUpdates;
|
|
mSmallestDisplacement = Preconditions.checkArgumentInRange(smallestDisplacementM, 0,
|
|
Float.MAX_VALUE, "smallestDisplacementM");
|
|
mHideFromAppOps = hideFromAppOps;
|
|
mLowPowerMode = lowPowerMode;
|
|
mLocationSettingsIgnored = locationSettingsIgnored;
|
|
mWorkSource = workSource;
|
|
}
|
|
|
|
/**
|
|
* Set the quality of the request.
|
|
*
|
|
* <p>Use with a accuracy constant such as {@link #ACCURACY_FINE}, or a power
|
|
* constant such as {@link #POWER_LOW}. You cannot request both accuracy and
|
|
* power, only one or the other can be specified. The system will then
|
|
* maximize accuracy or minimize power as appropriate.
|
|
*
|
|
* <p>The quality of the request is a strong hint to the system for which
|
|
* location sources to use. For example, {@link #ACCURACY_FINE} is more likely
|
|
* to use GPS, and {@link #POWER_LOW} is more likely to use WIFI & Cell tower
|
|
* positioning, but it also depends on many other factors (such as which sources
|
|
* are available) and is implementation dependent.
|
|
*
|
|
* <p>{@link #setQuality} and {@link #setInterval} are the most important parameters
|
|
* on a location request.
|
|
*
|
|
* @param quality an accuracy or power constant
|
|
* @return the same object, so that setters can be chained
|
|
* @throws IllegalArgumentException if the quality constant is not valid
|
|
*/
|
|
public @NonNull LocationRequest setQuality(int quality) {
|
|
checkQuality(quality);
|
|
mQuality = quality;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the quality of the request.
|
|
*
|
|
* @return an accuracy or power constant
|
|
*/
|
|
public int getQuality() {
|
|
return mQuality;
|
|
}
|
|
|
|
/**
|
|
* Set the desired interval for active location updates, in milliseconds.
|
|
*
|
|
* <p>The location manager will actively try to obtain location updates
|
|
* for your application at this interval, so it has a
|
|
* direct influence on the amount of power used by your application.
|
|
* Choose your interval wisely.
|
|
*
|
|
* <p>This interval is inexact. You may not receive updates at all (if
|
|
* no location sources are available), or you may receive them
|
|
* slower than requested. You may also receive them faster than
|
|
* requested (if other applications are requesting location at a
|
|
* faster interval). The fastest rate that you will receive
|
|
* updates can be controlled with {@link #setFastestInterval}.
|
|
*
|
|
* <p>Applications with only the coarse location permission may have their
|
|
* interval silently throttled.
|
|
*
|
|
* <p>An interval of 0 is allowed, but not recommended, since
|
|
* location updates may be extremely fast on future implementations.
|
|
*
|
|
* <p>{@link #setQuality} and {@link #setInterval} are the most important parameters
|
|
* on a location request.
|
|
*
|
|
* @param millis desired interval in millisecond, inexact
|
|
* @return the same object, so that setters can be chained
|
|
* @throws IllegalArgumentException if the interval is less than zero
|
|
*/
|
|
public @NonNull LocationRequest setInterval(long millis) {
|
|
Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
|
|
mInterval = millis;
|
|
if (!mExplicitFastestInterval) {
|
|
mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the desired interval of this request, in milliseconds.
|
|
*
|
|
* @return desired interval in milliseconds, inexact
|
|
*/
|
|
public long getInterval() {
|
|
return mInterval;
|
|
}
|
|
|
|
|
|
/**
|
|
* Requests the GNSS chipset to run in a low power mode and make strong tradeoffs to
|
|
* substantially restrict power.
|
|
*
|
|
* <p>In this mode, the GNSS chipset will not, on average, run power hungry operations like RF &
|
|
* signal searches for more than one second per interval (specified by
|
|
* {@link #setInterval(long)}).
|
|
*
|
|
* @param enabled Enable or disable low power mode
|
|
* @return the same object, so that setters can be chained
|
|
*/
|
|
public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
|
|
mLowPowerMode = enabled;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns true if low power mode is enabled.
|
|
*/
|
|
public boolean isLowPowerMode() {
|
|
return mLowPowerMode;
|
|
}
|
|
|
|
/**
|
|
* Requests that user location settings be ignored in order to satisfy this request. This API
|
|
* is only for use in extremely rare scenarios where it is appropriate to ignore user location
|
|
* settings, such as a user initiated emergency (dialing 911 for instance).
|
|
*
|
|
* @param locationSettingsIgnored Whether to ignore location settings
|
|
* @return the same object, so that setters can be chained
|
|
*/
|
|
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
|
|
public @NonNull LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
|
|
mLocationSettingsIgnored = locationSettingsIgnored;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Returns true if location settings will be ignored in order to satisfy this request.
|
|
*/
|
|
public boolean isLocationSettingsIgnored() {
|
|
return mLocationSettingsIgnored;
|
|
}
|
|
|
|
/**
|
|
* Explicitly set the fastest interval for location updates, in
|
|
* milliseconds.
|
|
*
|
|
* <p>This controls the fastest rate at which your application will
|
|
* receive location updates, which might be faster than
|
|
* {@link #setInterval} in some situations (for example, if other
|
|
* applications are triggering location updates).
|
|
*
|
|
* <p>This allows your application to passively acquire locations
|
|
* at a rate faster than it actively acquires locations, saving power.
|
|
*
|
|
* <p>Unlike {@link #setInterval}, this parameter is exact. Your
|
|
* application will never receive updates faster than this value.
|
|
*
|
|
* <p>If you don't call this method, a fastest interval
|
|
* will be selected for you. It will be a value faster than your
|
|
* active interval ({@link #setInterval}).
|
|
*
|
|
* <p>An interval of 0 is allowed, but not recommended, since
|
|
* location updates may be extremely fast on future implementations.
|
|
*
|
|
* <p>If the fastest interval set is slower than {@link #setInterval},
|
|
* then your effective fastest interval is {@link #setInterval}.
|
|
*
|
|
* @param millis fastest interval for updates in milliseconds
|
|
* @return the same object, so that setters can be chained
|
|
* @throws IllegalArgumentException if the interval is less than zero
|
|
*/
|
|
public @NonNull LocationRequest setFastestInterval(long millis) {
|
|
Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
|
|
mExplicitFastestInterval = true;
|
|
mFastestInterval = millis;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the fastest interval of this request in milliseconds. The system will never provide
|
|
* location updates faster than the minimum of the fastest interval and {@link #getInterval}.
|
|
*
|
|
* @return fastest interval in milliseconds
|
|
*/
|
|
public long getFastestInterval() {
|
|
return mFastestInterval;
|
|
}
|
|
|
|
/**
|
|
* Set the expiration time of this request in milliseconds of realtime since boot. Values in the
|
|
* past are allowed, but indicate that the request has already expired. The location manager
|
|
* will automatically stop updates after the request expires.
|
|
*
|
|
* @param millis expiration time of request in milliseconds since boot
|
|
* @return the same object, so that setters can be chained
|
|
* @see SystemClock#elapsedRealtime()
|
|
* @deprecated Prefer {@link #setExpireIn(long)}.
|
|
*/
|
|
@Deprecated
|
|
public @NonNull LocationRequest setExpireAt(long millis) {
|
|
mExpireAt = Math.max(millis, 0);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the request expiration time in milliseconds of realtime since boot.
|
|
*
|
|
* @return request expiration time in milliseconds since boot
|
|
* @see SystemClock#elapsedRealtime()
|
|
* @deprecated Prefer {@link #getExpireIn()}.
|
|
*/
|
|
@Deprecated
|
|
public long getExpireAt() {
|
|
return mExpireAt;
|
|
}
|
|
|
|
/**
|
|
* Set the duration of this request in milliseconds of realtime. Values less than 0 are allowed,
|
|
* but indicate that the request has already expired. The location manager will automatically
|
|
* stop updates after the request expires.
|
|
*
|
|
* @param millis duration of request in milliseconds
|
|
* @return the same object, so that setters can be chained
|
|
* @see SystemClock#elapsedRealtime()
|
|
*/
|
|
public @NonNull LocationRequest setExpireIn(long millis) {
|
|
mExpireIn = millis;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the request expiration duration in milliseconds of realtime.
|
|
*
|
|
* @return request expiration duration in milliseconds
|
|
* @see SystemClock#elapsedRealtime()
|
|
*/
|
|
public long getExpireIn() {
|
|
return mExpireIn;
|
|
}
|
|
|
|
/**
|
|
* Returns the realtime at which this request expires, taking into account both
|
|
* {@link #setExpireAt(long)} and {@link #setExpireIn(long)} relative to the given realtime.
|
|
*
|
|
* @hide
|
|
*/
|
|
public long getExpirationRealtimeMs(long startRealtimeMs) {
|
|
long expirationRealtimeMs;
|
|
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
|
|
if (mExpireIn > Long.MAX_VALUE - startRealtimeMs) {
|
|
expirationRealtimeMs = Long.MAX_VALUE;
|
|
} else {
|
|
expirationRealtimeMs = startRealtimeMs + mExpireIn;
|
|
}
|
|
return Math.min(expirationRealtimeMs, mExpireAt);
|
|
}
|
|
|
|
/**
|
|
* Set the number of location updates.
|
|
*
|
|
* <p>By default locations are continuously updated until the request is explicitly
|
|
* removed, however you can optionally request a set number of updates.
|
|
* For example, if your application only needs a single fresh location,
|
|
* then call this method with a value of 1 before passing the request
|
|
* to the location manager.
|
|
*
|
|
* @param numUpdates the number of location updates requested
|
|
* @return the same object, so that setters can be chained
|
|
* @throws IllegalArgumentException if numUpdates is 0 or less
|
|
*/
|
|
public @NonNull LocationRequest setNumUpdates(int numUpdates) {
|
|
if (numUpdates <= 0) {
|
|
throw new IllegalArgumentException(
|
|
"invalid numUpdates: " + numUpdates);
|
|
}
|
|
mNumUpdates = numUpdates;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get the number of updates requested.
|
|
*
|
|
* <p>By default this is {@link Integer#MAX_VALUE}, which indicates that
|
|
* locations are updated until the request is explicitly removed.
|
|
*
|
|
* @return number of updates
|
|
*/
|
|
public int getNumUpdates() {
|
|
return mNumUpdates;
|
|
}
|
|
|
|
/** @hide */
|
|
public void decrementNumUpdates() {
|
|
if (mNumUpdates != Integer.MAX_VALUE) {
|
|
mNumUpdates--;
|
|
}
|
|
if (mNumUpdates < 0) {
|
|
mNumUpdates = 0;
|
|
}
|
|
}
|
|
|
|
/** Sets the provider to use for this location request. */
|
|
public @NonNull LocationRequest setProvider(@NonNull String provider) {
|
|
Preconditions.checkArgument(provider != null, "invalid provider: null");
|
|
mProvider = provider;
|
|
return this;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
public @NonNull String getProvider() {
|
|
return mProvider;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
public @NonNull LocationRequest setSmallestDisplacement(float smallestDisplacementM) {
|
|
mSmallestDisplacement = Preconditions.checkArgumentInRange(smallestDisplacementM, 0,
|
|
Float.MAX_VALUE, "smallestDisplacementM");
|
|
return this;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
public float getSmallestDisplacement() {
|
|
return mSmallestDisplacement;
|
|
}
|
|
|
|
/**
|
|
* Sets the WorkSource to use for power blaming of this location request.
|
|
*
|
|
* <p>No permissions are required to make this call, however the LocationManager
|
|
* will throw a SecurityException when requesting location updates if the caller
|
|
* doesn't have the {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
|
|
*
|
|
* @param workSource WorkSource defining power blame for this location request.
|
|
* @hide
|
|
*/
|
|
@SystemApi
|
|
public void setWorkSource(@Nullable WorkSource workSource) {
|
|
mWorkSource = workSource;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
public @Nullable WorkSource getWorkSource() {
|
|
return mWorkSource;
|
|
}
|
|
|
|
/**
|
|
* Sets whether or not this location request should be hidden from AppOps.
|
|
*
|
|
* <p>Hiding a location request from AppOps will remove user visibility in the UI as to this
|
|
* request's existence. It does not affect power blaming in the Battery page.
|
|
*
|
|
* <p>No permissions are required to make this call, however the LocationManager
|
|
* will throw a SecurityException when requesting location updates if the caller
|
|
* doesn't have the {@link android.Manifest.permission#UPDATE_APP_OPS_STATS} permission.
|
|
*
|
|
* @param hideFromAppOps If true AppOps won't keep track of this location request.
|
|
* @hide
|
|
* @see android.app.AppOpsManager
|
|
*/
|
|
@SystemApi
|
|
public void setHideFromAppOps(boolean hideFromAppOps) {
|
|
mHideFromAppOps = hideFromAppOps;
|
|
}
|
|
|
|
/** @hide */
|
|
@SystemApi
|
|
public boolean getHideFromAppOps() {
|
|
return mHideFromAppOps;
|
|
}
|
|
|
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
|
private static void checkQuality(int quality) {
|
|
switch (quality) {
|
|
case ACCURACY_FINE:
|
|
case ACCURACY_BLOCK:
|
|
case ACCURACY_CITY:
|
|
case POWER_NONE:
|
|
case POWER_LOW:
|
|
case POWER_HIGH:
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("invalid quality: " + quality);
|
|
}
|
|
}
|
|
|
|
public static final @NonNull Parcelable.Creator<LocationRequest> CREATOR =
|
|
new Parcelable.Creator<LocationRequest>() {
|
|
@Override
|
|
public LocationRequest createFromParcel(Parcel in) {
|
|
return new LocationRequest(
|
|
/* provider= */ in.readString(),
|
|
/* quality= */ in.readInt(),
|
|
/* interval= */ in.readLong(),
|
|
/* fastestInterval= */ in.readLong(),
|
|
/* explicitFastestInterval= */ in.readBoolean(),
|
|
/* expireAt= */ in.readLong(),
|
|
/* expireIn= */ in.readLong(),
|
|
/* numUpdates= */ in.readInt(),
|
|
/* smallestDisplacement= */ in.readFloat(),
|
|
/* hideFromAppOps= */ in.readBoolean(),
|
|
/* locationSettingsIgnored= */ in.readBoolean(),
|
|
/* lowPowerMode= */ in.readBoolean(),
|
|
/* workSource= */ in.readTypedObject(WorkSource.CREATOR));
|
|
}
|
|
|
|
@Override
|
|
public LocationRequest[] newArray(int size) {
|
|
return new LocationRequest[size];
|
|
}
|
|
};
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel parcel, int flags) {
|
|
parcel.writeString(mProvider);
|
|
parcel.writeInt(mQuality);
|
|
parcel.writeLong(mInterval);
|
|
parcel.writeLong(mFastestInterval);
|
|
parcel.writeBoolean(mExplicitFastestInterval);
|
|
parcel.writeLong(mExpireAt);
|
|
parcel.writeLong(mExpireIn);
|
|
parcel.writeInt(mNumUpdates);
|
|
parcel.writeFloat(mSmallestDisplacement);
|
|
parcel.writeBoolean(mHideFromAppOps);
|
|
parcel.writeBoolean(mLocationSettingsIgnored);
|
|
parcel.writeBoolean(mLowPowerMode);
|
|
parcel.writeTypedObject(mWorkSource, 0);
|
|
}
|
|
|
|
/** @hide */
|
|
public static String qualityToString(int quality) {
|
|
switch (quality) {
|
|
case ACCURACY_FINE:
|
|
return "ACCURACY_FINE";
|
|
case ACCURACY_BLOCK:
|
|
return "ACCURACY_BLOCK";
|
|
case ACCURACY_CITY:
|
|
return "ACCURACY_CITY";
|
|
case POWER_NONE:
|
|
return "POWER_NONE";
|
|
case POWER_LOW:
|
|
return "POWER_LOW";
|
|
case POWER_HIGH:
|
|
return "POWER_HIGH";
|
|
default:
|
|
return "???";
|
|
}
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder s = new StringBuilder();
|
|
s.append("Request[");
|
|
s.append(qualityToString(mQuality));
|
|
s.append(" ").append(mProvider);
|
|
if (mQuality != POWER_NONE) {
|
|
s.append(" interval=");
|
|
TimeUtils.formatDuration(mInterval, s);
|
|
if (mExplicitFastestInterval) {
|
|
s.append(" fastestInterval=");
|
|
TimeUtils.formatDuration(mFastestInterval, s);
|
|
}
|
|
}
|
|
if (mExpireAt != Long.MAX_VALUE) {
|
|
s.append(" expireAt=").append(TimeUtils.formatRealtime(mExpireAt));
|
|
}
|
|
if (mExpireIn != Long.MAX_VALUE) {
|
|
s.append(" expireIn=");
|
|
TimeUtils.formatDuration(mExpireIn, s);
|
|
}
|
|
if (mNumUpdates != Integer.MAX_VALUE) {
|
|
s.append(" num=").append(mNumUpdates);
|
|
}
|
|
if (mLowPowerMode) {
|
|
s.append(" lowPowerMode");
|
|
}
|
|
if (mLocationSettingsIgnored) {
|
|
s.append(" locationSettingsIgnored");
|
|
}
|
|
s.append(']');
|
|
return s.toString();
|
|
}
|
|
}
|