/* * 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 static android.Manifest.permission.LOCATION_BYPASS; import static java.lang.Math.max; import static java.lang.Math.min; import android.Manifest; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.pm.PackageManager; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.WorkSource; import android.util.TimeUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * An encapsulation of various parameters for requesting location via {@link LocationManager}. */ public final class LocationRequest implements Parcelable { /** * For apps targeting Android S and above, all LocationRequest objects marked as low power will * throw exceptions if the caller does not have the LOCATION_HARDWARE permission, instead of * silently dropping the low power part of the request. * * @hide */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) public static final long LOW_POWER_EXCEPTIONS = 168936375L; /** * Represents a passive only request. Such a request will not trigger any active locations or * power usage itself, but may receive locations generated in response to other requests. * * @see LocationRequest#getIntervalMillis() */ public static final long PASSIVE_INTERVAL = Long.MAX_VALUE; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({QUALITY_LOW_POWER, QUALITY_BALANCED_POWER_ACCURACY, QUALITY_HIGH_ACCURACY}) public @interface Quality {} /** * A quality constant indicating a location provider may choose to satisfy this request by * providing very accurate locations at the expense of potentially increased power usage. Each * location provider may interpret this field differently, but as an example, the network * provider may choose to return only wifi based locations rather than cell based locations in * order to have greater accuracy when this flag is present. */ public static final int QUALITY_HIGH_ACCURACY = 100; /** * A quality constant indicating a location provider may choose to satisfy this request by * equally balancing power and accuracy constraints. Each location provider may interpret this * field differently, but location providers will generally use their default behavior when this * flag is present. */ public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; /** * A quality constant indicating a location provider may choose to satisfy this request by * providing less accurate locations in order to save power. Each location provider may * interpret this field differently, but as an example, the network provider may choose to * return cell based locations rather than wifi based locations in order to save power when this * flag is present. */ public static final int QUALITY_LOW_POWER = 104; /** * Used with {@link #setQuality} to request the most accurate locations available. * *
This may be up to 1 meter accuracy, although this is implementation dependent. * * @hide * @deprecated Use {@link #QUALITY_HIGH_ACCURACY} instead. */ @Deprecated @SystemApi public static final int ACCURACY_FINE = QUALITY_HIGH_ACCURACY; /** * Used with {@link #setQuality} to request "block" level accuracy. * *
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. * * @hide * @deprecated Use {@link #QUALITY_BALANCED_POWER_ACCURACY} instead. */ @Deprecated @SystemApi public static final int ACCURACY_BLOCK = QUALITY_BALANCED_POWER_ACCURACY; /** * Used with {@link #setQuality} to request "city" level accuracy. * *
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. * * @hide * @deprecated Use {@link #QUALITY_LOW_POWER} instead. */ @Deprecated @SystemApi public static final int ACCURACY_CITY = QUALITY_LOW_POWER; /** * Used with {@link #setQuality} to require no direct power impact (passive locations). * *
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. * * @hide * @deprecated Use {@link #PASSIVE_INTERVAL} instead. */ @SystemApi @Deprecated public static final int POWER_NONE = 200; /** * Used with {@link #setQuality} to request low power impact. * *
This location request will avoid high power location work where * possible. * * @hide * @deprecated Use {@link #QUALITY_LOW_POWER} instead. */ @Deprecated @SystemApi public static final int POWER_LOW = 201; /** * Used with {@link #setQuality} to allow high power consumption for location. * *
This location request will allow high power location work. * * @hide * @deprecated Use {@link #QUALITY_HIGH_ACCURACY} instead. */ @Deprecated @SystemApi public static final int POWER_HIGH = 203; private static final long IMPLICIT_MIN_UPDATE_INTERVAL = -1; private static final double IMPLICIT_MIN_UPDATE_INTERVAL_FACTOR = 1D / 6D; private @Nullable String mProvider; private @Quality int mQuality; private long mIntervalMillis; private long mMinUpdateIntervalMillis; private long mExpireAtRealtimeMillis; private long mDurationMillis; private int mMaxUpdates; private float mMinUpdateDistanceMeters; private final long mMaxUpdateDelayMillis; private boolean mHideFromAppOps; private final boolean mAdasGnssBypass; private boolean mBypass; private boolean mLowPower; private @Nullable WorkSource mWorkSource; /** * @hide * @deprecated Use the Builder to construct new LocationRequests. */ @SystemApi @Deprecated @NonNull public static LocationRequest create() { // 60 minutes is the default legacy interval return new LocationRequest.Builder(60 * 60 * 1000).build(); } /** * @hide * @deprecated Use the Builder to construct new LocationRequests. */ @SystemApi @Deprecated @NonNull public static LocationRequest createFromDeprecatedProvider(@NonNull String provider, long intervalMillis, float minUpdateDistanceMeters, boolean singleShot) { Preconditions.checkArgument(provider != null, "invalid null provider"); if (intervalMillis < 0) { intervalMillis = 0; } else if (intervalMillis == PASSIVE_INTERVAL) { intervalMillis = Long.MAX_VALUE - 1; } if (minUpdateDistanceMeters < 0) { minUpdateDistanceMeters = 0; } int quality; if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { quality = POWER_NONE; } else if (LocationManager.GPS_PROVIDER.equals(provider)) { quality = QUALITY_HIGH_ACCURACY; } else { quality = QUALITY_BALANCED_POWER_ACCURACY; } return new LocationRequest.Builder(intervalMillis) .setMinUpdateIntervalMillis(intervalMillis) .setMinUpdateDistanceMeters(minUpdateDistanceMeters) .setMaxUpdates(singleShot ? 1 : Integer.MAX_VALUE) .build() .setProvider(provider) .setQuality(quality); } /** * @hide * @deprecated Use the Builder to construct new LocationRequests. */ @SystemApi @Deprecated @NonNull public static LocationRequest createFromDeprecatedCriteria(@NonNull Criteria criteria, long intervalMillis, float minUpdateDistanceMeters, boolean singleShot) { Preconditions.checkArgument(criteria != null, "invalid null criteria"); if (intervalMillis < 0) { intervalMillis = 0; } else if (intervalMillis == PASSIVE_INTERVAL) { intervalMillis = Long.MAX_VALUE - 1; } if (minUpdateDistanceMeters < 0) { minUpdateDistanceMeters = 0; } return new LocationRequest.Builder(intervalMillis) .setQuality(criteria) .setMinUpdateIntervalMillis(intervalMillis) .setMinUpdateDistanceMeters(minUpdateDistanceMeters) .setMaxUpdates(singleShot ? 1 : Integer.MAX_VALUE) .build(); } private LocationRequest( @Nullable String provider, long intervalMillis, @Quality int quality, long expireAtRealtimeMillis, long durationMillis, int maxUpdates, long minUpdateIntervalMillis, float minUpdateDistanceMeters, long maxUpdateDelayMillis, boolean hiddenFromAppOps, boolean adasGnssBypass, boolean bypass, boolean lowPower, WorkSource workSource) { mProvider = provider; mIntervalMillis = intervalMillis; mQuality = quality; mMinUpdateIntervalMillis = minUpdateIntervalMillis; mExpireAtRealtimeMillis = expireAtRealtimeMillis; mDurationMillis = durationMillis; mMaxUpdates = maxUpdates; mMinUpdateDistanceMeters = minUpdateDistanceMeters; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mHideFromAppOps = hiddenFromAppOps; mAdasGnssBypass = adasGnssBypass; mBypass = bypass; mLowPower = lowPower; mWorkSource = Objects.requireNonNull(workSource); } /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @SystemApi @Deprecated public @NonNull LocationRequest setProvider(@NonNull String provider) { Preconditions.checkArgument(provider != null); mProvider = provider; return this; } /** * @hide * @deprecated Providers are no longer an explicit part of a location request. */ @SystemApi @Deprecated public @NonNull String getProvider() { return mProvider != null ? mProvider : LocationManager.FUSED_PROVIDER; } /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @SystemApi @Deprecated public @NonNull LocationRequest setQuality(int quality) { switch (quality) { case POWER_HIGH: // fall through case QUALITY_HIGH_ACCURACY: mQuality = QUALITY_HIGH_ACCURACY; break; case QUALITY_BALANCED_POWER_ACCURACY: mQuality = QUALITY_BALANCED_POWER_ACCURACY; break; case POWER_LOW: // fall through case QUALITY_LOW_POWER: mQuality = QUALITY_LOW_POWER; break; case POWER_NONE: mIntervalMillis = PASSIVE_INTERVAL; break; default: throw new IllegalArgumentException("invalid quality: " + quality); } return this; } /** * Returns the quality hint for this location request. The quality hint informs the provider how * it should attempt to manage any accuracy vs power tradeoffs while attempting to satisfy this * location request. * * @return the desired quality tradeoffs between accuracy and power */ public @Quality int getQuality() { return mQuality; } /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @SystemApi @Deprecated public @NonNull LocationRequest setInterval(long millis) { Preconditions.checkArgument(millis >= 0); // legacy clients don't know about the passive interval if (millis == PASSIVE_INTERVAL) { millis = Long.MAX_VALUE - 1; } mIntervalMillis = millis; if (mMinUpdateIntervalMillis > mIntervalMillis) { mMinUpdateIntervalMillis = mIntervalMillis; } return this; } /** * @hide * @deprecated Use {@link #getIntervalMillis()} instead. */ @SystemApi @Deprecated public long getInterval() { return getIntervalMillis(); } /** * Returns the desired interval of location updates, or {@link #PASSIVE_INTERVAL} if this is a * passive, no power request. A passive request will not actively generate location updates * (and thus will not be power blamed for location), but may receive location updates generated * as a result of other location requests. A passive request must always have an explicit * minimum update interval set. * *
Locations may be available at a faster interval than specified here, see
* {@link #getMinUpdateIntervalMillis()} for the behavior in that case.
*
* @return the desired interval of location updates
*/
public @IntRange(from = 0) long getIntervalMillis() {
return mIntervalMillis;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setFastestInterval(long millis) {
Preconditions.checkArgument(millis >= 0);
mMinUpdateIntervalMillis = millis;
return this;
}
/**
* @hide
* @deprecated Use {@link #getMinUpdateIntervalMillis()} instead.
*/
@SystemApi
@Deprecated
public long getFastestInterval() {
return getMinUpdateIntervalMillis();
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setExpireAt(long millis) {
mExpireAtRealtimeMillis = max(millis, 0);
return this;
}
/**
* @hide
* @deprecated Prefer {@link #getDurationMillis()} where possible.
*/
@SystemApi
@Deprecated
public long getExpireAt() {
return mExpireAtRealtimeMillis;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setExpireIn(long millis) {
mDurationMillis = millis;
return this;
}
/**
* @hide
* @deprecated Use {@link #getDurationMillis()} instead.
*/
@SystemApi
@Deprecated
public long getExpireIn() {
return getDurationMillis();
}
/**
* Returns the duration for which location will be provided before the request is automatically
* removed. A duration of Long.MAX_VALUE
represents an unlimited duration.
*
* @return the duration for which location will be provided
*/
public @IntRange(from = 1) long getDurationMillis() {
return mDurationMillis;
}
/**
* @hide
*/
public long getExpirationRealtimeMs(long startRealtimeMs) {
long expirationRealtimeMs;
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
if (mDurationMillis > Long.MAX_VALUE - startRealtimeMs) {
expirationRealtimeMs = Long.MAX_VALUE;
} else {
expirationRealtimeMs = startRealtimeMs + mDurationMillis;
}
return min(expirationRealtimeMs, mExpireAtRealtimeMillis);
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setNumUpdates(int numUpdates) {
if (numUpdates <= 0) {
throw new IllegalArgumentException(
"invalid numUpdates: " + numUpdates);
}
mMaxUpdates = numUpdates;
return this;
}
/**
* @hide
* @deprecated Use {@link #getMaxUpdates()} instead.
*/
@SystemApi
@Deprecated
public int getNumUpdates() {
return getMaxUpdates();
}
/**
* Returns the maximum number of location updates for this request before the request is
* automatically removed. A max updates value of Integer.MAX_VALUE
represents an
* unlimited number of updates.
*/
public @IntRange(from = 1, to = Integer.MAX_VALUE) int getMaxUpdates() {
return mMaxUpdates;
}
/**
* Returns the minimum update interval. If location updates are available faster than the
* request interval then locations will only be updated if the minimum update interval has
* expired since the last location update.
*
*
Note: Some allowance for jitter is already built into the
* minimum update interval, so you need not worry about updates blocked simply because they
* arrived a fraction of a second earlier than expected.
*
* @return the minimum update interval
*/
public @IntRange(from = 0) long getMinUpdateIntervalMillis() {
if (mMinUpdateIntervalMillis == IMPLICIT_MIN_UPDATE_INTERVAL) {
return (long) (mIntervalMillis * IMPLICIT_MIN_UPDATE_INTERVAL_FACTOR);
} else {
// the min is only necessary in case someone use a deprecated function to mess with the
// interval or min update interval
return min(mMinUpdateIntervalMillis, mIntervalMillis);
}
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setSmallestDisplacement(float minDisplacementMeters) {
mMinUpdateDistanceMeters = Preconditions.checkArgumentInRange(minDisplacementMeters, 0,
Float.MAX_VALUE, "minDisplacementMeters");
return this;
}
/**
* @hide
* @deprecated Use {@link #getMinUpdateDistanceMeters()} instead.
*/
@SystemApi
@Deprecated
public float getSmallestDisplacement() {
return getMinUpdateDistanceMeters();
}
/**
* Returns the minimum distance between location updates. If a potential location update is
* closer to the last location update than the minimum update distance, then the potential
* location update will not occur. A value of 0 meters implies that no location update will ever
* be rejected due to failing this constraint.
*
* @return the minimum distance between location updates
*/
public @FloatRange(from = 0, to = Float.MAX_VALUE) float getMinUpdateDistanceMeters() {
return mMinUpdateDistanceMeters;
}
/**
* Returns the maximum time any location update may be delayed, and thus grouped with following
* updates to enable location batching. If the maximum update delay is equal to or greater than
* twice the interval, then location providers may provide batched results. The maximum batch
* size is the maximum update delay divided by the interval. Not all devices or location
* providers support batching, and use of this parameter does not guarantee that the client will
* see batched results, or that batched results will always be of the maximum size.
*
* When available, batching can provide substantial power savings to the device, and clients are
* encouraged to take advantage where appropriate for the use case.
*
* @see LocationListener#onLocationChanged(java.util.List)
* @return the maximum time by which a location update may be delayed
*/
public @IntRange(from = 0) long getMaxUpdateDelayMillis() {
return mMaxUpdateDelayMillis;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public void setHideFromAppOps(boolean hiddenFromAppOps) {
mHideFromAppOps = hiddenFromAppOps;
}
/**
* @hide
* @deprecated Use {@link #isHiddenFromAppOps()} instead.
*/
@SystemApi
@Deprecated
public boolean getHideFromAppOps() {
return isHiddenFromAppOps();
}
/**
* Returns true if this request should be ignored while updating app ops with location usage.
* This implies that someone else (usually the creator of the location request) is responsible
* for updating app ops.
*
* @return true if this request should be ignored while updating app ops with location usage
*
* @hide
*/
@SystemApi
public boolean isHiddenFromAppOps() {
return mHideFromAppOps;
}
/**
* Returns true if this request may access GNSS even if location settings would normally deny
* this, in order to enable automotive safety features. This field is only respected on
* automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced
* Driving Assistance Systems) application.
*
* @return true if all limiting factors will be ignored to satisfy GNSS request
*
* @hide
*/
@SystemApi
public boolean isAdasGnssBypass() {
return mAdasGnssBypass;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
@RequiresPermission(LOCATION_BYPASS)
public @NonNull LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
mBypass = locationSettingsIgnored;
return this;
}
/**
* Returns true if location settings, throttling, background location limits, and any other
* possible limiting factors will be ignored in order to satisfy this request.
*
* @return true if all limiting factors will be ignored to satisfy this request
*
* @hide
*/
@SystemApi
public boolean isLocationSettingsIgnored() {
return mBypass;
}
/**
* Returns true if any bypass flag is set on this request. For internal use only.
*
* @hide
*/
public boolean isBypass() {
return mAdasGnssBypass || mBypass;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
mLowPower = enabled;
return this;
}
/**
* @hide
* @deprecated Use {@link #isLowPower()} instead.
*/
@Deprecated
@SystemApi
public boolean isLowPowerMode() {
return isLowPower();
}
/**
* Returns true if extreme trade-offs should be made to save power for this request. This
* usually involves specialized hardware modes which can greatly affect the quality of
* locations.
*
* @return true if extreme trade-offs should be made to save power for this request
*
* @hide
*/
@SystemApi
public boolean isLowPower() {
return mLowPower;
}
/**
* @hide
* @deprecated LocationRequests should be treated as immutable.
*/
@SystemApi
@Deprecated
public void setWorkSource(@Nullable WorkSource workSource) {
if (workSource == null) {
workSource = new WorkSource();
}
mWorkSource = workSource;
}
/**
* Returns the work source used for power blame for this request. If empty, the system is free
* to assign power blame as it deems most appropriate.
*
* @return the work source used for power blame for this request
*
* @hide
*/
@SystemApi
public @NonNull WorkSource getWorkSource() {
return mWorkSource;
}
public static final @NonNull Parcelable.Creator Locations may be available at a faster interval than specified here, see
* {@link #setMinUpdateIntervalMillis(long)} for the behavior in that case.
*/
public @NonNull Builder setIntervalMillis(@IntRange(from = 0) long intervalMillis) {
mIntervalMillis = Preconditions.checkArgumentInRange(intervalMillis, 0, Long.MAX_VALUE,
"intervalMillis");
return this;
}
/**
* Sets the request quality. The quality is a hint to providers on how they should weigh
* power vs accuracy tradeoffs. High accuracy locations may cost more power to produce, and
* lower accuracy locations may cost less power to produce. Defaults to
* {@link #QUALITY_BALANCED_POWER_ACCURACY}.
*/
public @NonNull Builder setQuality(@Quality int quality) {
Preconditions.checkArgument(
quality == QUALITY_LOW_POWER || quality == QUALITY_BALANCED_POWER_ACCURACY
|| quality == QUALITY_HIGH_ACCURACY,
"quality must be a defined QUALITY constant, not %d", quality);
mQuality = quality;
return this;
}
/**
* @hide
*/
public @NonNull Builder setQuality(@NonNull Criteria criteria) {
switch (criteria.getAccuracy()) {
case Criteria.ACCURACY_COARSE:
mQuality = QUALITY_BALANCED_POWER_ACCURACY;
break;
case Criteria.ACCURACY_FINE:
mQuality = QUALITY_HIGH_ACCURACY;
break;
default: {
if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) {
mQuality = POWER_HIGH;
} else {
mQuality = POWER_LOW;
}
}
}
return this;
}
/**
* Sets the duration this request will continue before being automatically removed. Defaults
* to Note: Some allowance for jitter is already built into the
* minimum update interval, so you need not worry about updates blocked simply because they
* arrived a fraction of a second earlier than expected.
*
* Note: When {@link #build()} is invoked, the minimum of
* the interval and the minimum update interval will be used as the minimum update interval
* of the built request.
*/
public @NonNull Builder setMinUpdateIntervalMillis(
@IntRange(from = 0) long minUpdateIntervalMillis) {
mMinUpdateIntervalMillis = Preconditions.checkArgumentInRange(minUpdateIntervalMillis,
0, Long.MAX_VALUE, "minUpdateIntervalMillis");
return this;
}
/**
* Clears an explicitly set minimum update interval and reverts to an implicit minimum
* update interval (ie, the minimum update interval is some sensible default between 0 and
* the interval).
*/
public @NonNull Builder clearMinUpdateIntervalMillis() {
mMinUpdateIntervalMillis = IMPLICIT_MIN_UPDATE_INTERVAL;
return this;
}
/**
* Sets the minimum update distance between location updates. If a potential location
* update is closer to the last location update than the minimum update distance, then
* the potential location update will not occur. Defaults to 0, which represents no minimum
* update distance.
*/
public @NonNull Builder setMinUpdateDistanceMeters(
@FloatRange(from = 0, to = Float.MAX_VALUE) float minUpdateDistanceMeters) {
mMinUpdateDistanceMeters = Preconditions.checkArgumentInRange(minUpdateDistanceMeters,
0, Float.MAX_VALUE, "minUpdateDistanceMeters");
return this;
}
/**
* Sets the maximum time any location update may be delayed, and thus grouped with following
* updates to enable location batching. If the maximum update delay is equal to or greater
* than twice the interval, then location providers may provide batched results. Defaults to
* 0, which represents no batching allowed.
*/
public @NonNull Builder setMaxUpdateDelayMillis(
@IntRange(from = 0) long maxUpdateDelayMillis) {
mMaxUpdateDelayMillis = Preconditions.checkArgumentInRange(maxUpdateDelayMillis, 0,
Long.MAX_VALUE, "maxUpdateDelayMillis");
return this;
}
/**
* If set to true, indicates that app ops should not be updated with location usage due to
* this request. This implies that someone else (usually the creator of the location
* request) is responsible for updating app ops as appropriate. Defaults to false.
*
* Permissions enforcement occurs when resulting location request is actually used, not
* when this method is invoked.
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.UPDATE_APP_OPS_STATS)
public @NonNull Builder setHiddenFromAppOps(boolean hiddenFromAppOps) {
mHiddenFromAppOps = hiddenFromAppOps;
return this;
}
/**
* If set to true, indicates that the client is an ADAS (Advanced Driving Assistance
* Systems) client, which requires access to GNSS even if location settings would normally
* deny this, in order to enable auto safety features. This field is only respected on
* automotive devices, and only if the client is recognized as a legitimate ADAS
* application. Defaults to false.
*
* Permissions enforcement occurs when resulting location request is actually used, not
* when this method is invoked.
*
* @hide
*/
@SystemApi
@RequiresPermission(LOCATION_BYPASS)
@RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) {
mAdasGnssBypass = adasGnssBypass;
return this;
}
/**
* If set to true, indicates that location settings, throttling, background location limits,
* and any other possible limiting factors should be ignored in order to satisfy this
* request. This is only intended for use in user initiated emergency situations, and
* should be used extremely cautiously. Defaults to false.
*
* Permissions enforcement occurs when resulting location request is actually used, not
* when this method is invoked.
*
* @hide
*/
@SystemApi
@RequiresPermission(LOCATION_BYPASS)
public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) {
mBypass = locationSettingsIgnored;
return this;
}
/**
* It set to true, indicates that extreme trade-offs should be made if possible to save
* power for this request. This usually involves specialized hardware modes which can
* greatly affect the quality of locations. Not all devices may support this. Defaults to
* false.
*
* Permissions enforcement occurs when resulting location request is actually used, not
* when this method is invoked.
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
public @NonNull Builder setLowPower(boolean lowPower) {
mLowPower = lowPower;
return this;
}
/**
* Sets the work source to use for power blame for this location request. Defaults to an
* empty WorkSource, which implies the system is free to assign power blame as it determines
* best for this request (which usually means blaming the owner of the location listener).
*
* Permissions enforcement occurs when resulting location request is actually used, not
* when this method is invoked.
*
* @hide
*/
@SystemApi
@RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
public @NonNull Builder setWorkSource(@Nullable WorkSource workSource) {
mWorkSource = workSource;
return this;
}
/**
* Builds a location request from this builder. If an explicit minimum update interval is
* set, the minimum update interval of the location request will be the minimum of the
* interval and minimum update interval.
*
* If building a passive request then you must have set an explicit minimum update
* interval.
*
* @throws IllegalStateException if building a passive request with no explicit minimum
* update interval set
* @return a new location request
*/
public @NonNull LocationRequest build() {
Preconditions.checkState(mIntervalMillis != PASSIVE_INTERVAL
|| mMinUpdateIntervalMillis != IMPLICIT_MIN_UPDATE_INTERVAL,
"passive location requests must have an explicit minimum update interval");
return new LocationRequest(
null,
mIntervalMillis,
mQuality,
Long.MAX_VALUE,
mDurationMillis,
mMaxUpdates,
min(mMinUpdateIntervalMillis, mIntervalMillis),
mMinUpdateDistanceMeters,
mMaxUpdateDelayMillis,
mHiddenFromAppOps,
mAdasGnssBypass,
mBypass,
mLowPower,
new WorkSource(mWorkSource));
}
}
}
Long.MAX_VALUE
, which represents an unlimited duration.
*/
public @NonNull Builder setDurationMillis(@IntRange(from = 1) long durationMillis) {
mDurationMillis = Preconditions.checkArgumentInRange(durationMillis, 1, Long.MAX_VALUE,
"durationMillis");
return this;
}
/**
* Sets the maximum number of location updates for this request before this request is
* automatically removed. Defaults to Integer.MAX_VALUE
, which represents an
* unlimited number of updates.
*/
public @NonNull Builder setMaxUpdates(
@IntRange(from = 1, to = Integer.MAX_VALUE) int maxUpdates) {
mMaxUpdates = Preconditions.checkArgumentInRange(maxUpdates, 1, Integer.MAX_VALUE,
"maxUpdates");
return this;
}
/**
* Sets an explicit minimum update interval. If location updates are available faster than
* the request interval then an update will only occur if the minimum update interval has
* expired since the last location update. Defaults to no explicit minimum update interval
* set, which means some sensible default between 0 and the interval will be chosen. The
* exact value is not specified at the moment. If an exact known value is required, clients
* should set an explicit value themselves.
*
*