android_external_GmsApi/src/com/google/android/gms/location/LocationRequest.java

417 lines
17 KiB
Java

package com.google.android.gms.location;
import android.os.SystemClock;
import org.microg.safeparcel.AutoSafeParcelable;
import org.microg.safeparcel.SafeParceled;
import java.util.Arrays;
/**
* A data object that contains quality of service parameters for requests to the
* FusedLocationProviderApi.
* <p/>
* LocationRequest objects are used to request a quality of service for location updates from the
* FusedLocationProviderApi.
* <p/>
* For example, if your application wants high accuracy location it should create a location
* request with {@link #setPriority(int)} set to {@link #PRIORITY_HIGH_ACCURACY} and
* {@link #setInterval(long)} to 5 seconds. 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 create a location request with {@link #setPriority(int)} set to
* {@link #PRIORITY_NO_POWER}. 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 #PRIORITY_BALANCED_POWER_ACCURACY} combined with a faster
* {@link #setFastestInterval(long)} (such as 1 minute) and a slower {@link #setInterval(long)}
* (such as 60 minutes). They will only be assigned power blame for the interval set by
* {@link #setInterval(long)}, but can still receive locations triggered by other applications at a
* rate up to {@link #setFastestInterval(long)}. This style of request is appropriate for many
* location aware applications, including background usage. Do be careful to also throttle
* {@link #setFastestInterval(long)} 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
* (for example at {@link android.app.Activity#onPause()}), or at least swap the request to a
* larger interval and lower quality.
* <p/>
* Applications cannot specify the exact location sources, such as GPS, that are used by the
* LocationClient. 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/less
* accurate, and faster/slower than requested.
*/
public class LocationRequest extends AutoSafeParcelable {
/**
* Used with {@link #setPriority(int)} to request "block" level accuracy.
* <p/>
* Block level accuracy is considered to be about 100 meter accuracy. Using a coarse accuracy
* such as this often consumes less power.
*/
public static final int PRIORITY_BALANCED_POWER_ACCURACY = 102;
/**
* Used with {@link #setPriority(int)} to request the most accurate locations available.
* <p/>
* This will return the finest location available.
*/
public static final int PRIORITY_HIGH_ACCURACY = 100;
/**
* Used with {@link #setPriority(int)} to request "city" level accuracy.
* <p/>
* City level accuracy is considered to be about 10km accuracy. Using a coarse accuracy such as
* this often consumes less power.
*/
public static final int PRIORITY_LOW_POWER = 104;
/**
* Used with {@link #setPriority(int)} to request the best accuracy possible with zero
* additional power consumption.
* <p/>
* No locations will be returned unless a different client has requested location updates in
* which case this request will act as a passive listener to those locations.
*/
public static final int PRIORITY_NO_POWER = 105;
@SafeParceled(1000)
private final int versionCode;
@SafeParceled(1)
private int priority;
@SafeParceled(2)
private long interval;
@SafeParceled(3)
private long fastestInterval;
@SafeParceled(4)
private boolean explicitFastestInterval;
@SafeParceled(5)
private long expirationTime;
@SafeParceled(6)
private int numUpdates;
@SafeParceled(7)
private float smallestDesplacement;
@SafeParceled(8)
private long maxWaitTime;
public LocationRequest() {
this.versionCode = 1;
this.priority = PRIORITY_BALANCED_POWER_ACCURACY;
this.interval = 3600000;
this.fastestInterval = 600000;
this.explicitFastestInterval = false;
this.expirationTime = Long.MAX_VALUE;
this.numUpdates = Integer.MAX_VALUE;
this.smallestDesplacement = 0;
this.maxWaitTime = 0;
}
/**
* Create a location request with default parameters.
* <p/>
* Default parameters are for a block accuracy, slowly updated location. It can then be
* adjusted as required by the applications before passing to the FusedLocationProviderApi.
*
* @return a new location request
*/
public static LocationRequest create() {
return new LocationRequest();
}
/**
* Get the request expiration time, in milliseconds since boot.
* <p/>
* This value can be compared to {@link SystemClock#elapsedRealtime()} to determine
* the time until expiration.
*
* @return expiration time of request, in milliseconds since boot including suspend
*/
public long getExpirationTime() {
return expirationTime;
}
/**
* Get the fastest interval of this request, in milliseconds.
* <p/>
* The system will never provide location updates faster than the minimum of
* {@link #getFastestInterval()} and {@link #getInterval()}.
*
* @return fastest interval in milliseconds, exact
*/
public long getFastestInterval() {
return fastestInterval;
}
/**
* Get the desired interval of this request, in milliseconds.
*
* @return desired interval in milliseconds, inexact
*/
public long getInterval() {
return interval;
}
/**
* Get the number of updates requested.
* <p/>
* By default this is {@link java.lang.Integer#MAX_VALUE}, which indicates that locations are
* updated until the request is explicitly removed.
*
* @return number of updates
*/
public int getNumUpdates() {
return numUpdates;
}
/**
* Get the quality of the request.
*
* @return an accuracy constant
*/
public int getPriority() {
return priority;
}
/**
* Get the minimum displacement between location updates in meters
* <p/>
* By default this is 0.
*
* @return minimum displacement between location updates in meters
*/
public float getSmallestDesplacement() {
return smallestDesplacement;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
LocationRequest that = (LocationRequest) o;
if (expirationTime != that.expirationTime)
return false;
if (explicitFastestInterval != that.explicitFastestInterval)
return false;
if (fastestInterval != that.fastestInterval)
return false;
if (interval != that.interval)
return false;
if (maxWaitTime != that.maxWaitTime)
return false;
if (numUpdates != that.numUpdates)
return false;
if (priority != that.priority)
return false;
if (Float.compare(that.smallestDesplacement, smallestDesplacement) != 0)
return false;
return true;
}
@Override
public int hashCode() {
return Arrays.hashCode(
new Object[] { priority, interval, fastestInterval, explicitFastestInterval,
explicitFastestInterval, numUpdates, smallestDesplacement, maxWaitTime
});
}
/**
* Set the duration of this request, in milliseconds.
* <p/>
* The duration begins immediately (and not when the request is passed to the location client),
* so call this method again if the request is re-used at a later time.
* <p/>
* The location client will automatically stop updates after the request expires.
* <p/>
* The duration includes suspend time. Values less than 0 are allowed, but indicate that the
* request has already expired.
*
* @param millis duration of request in milliseconds
* @return the same object, so that setters can be chained
*/
public LocationRequest setExpirationDuration(long millis) {
expirationTime = SystemClock.elapsedRealtime() + millis;
return this;
}
/**
* Set the request expiration time, in millisecond since boot.
* <p/>
* This expiration time uses the same time base as {@link SystemClock#elapsedRealtime()}.
* <p/>
* The location client will automatically stop updates after the request expires.
* <p/>
* The duration includes suspend time. Values before {@link SystemClock#elapsedRealtime()} are
* allowed, but indicate that the request has already expired.
*
* @param millis expiration time of request, in milliseconds since boot including suspend
* @return the same object, so that setters can be chained
*/
public LocationRequest setExpirationTime(long millis) {
expirationTime = millis;
return this;
}
/**
* 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(long)} 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(long)}, 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(long)}).
* <p/>
* An interval of 0 is allowed, but not recommended, since location updates may be extremely
* fast on future implementations.
* <p/>
* If {@link #setFastestInterval(long)} is set slower than {@link #setInterval(long)}, then
* your effective fastest interval is {@link #setInterval(long)}.
*
* @param millis fastest interval for updates in milliseconds, exact
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
public LocationRequest setFastestInterval(long millis) throws IllegalArgumentException {
if (millis < 0)
throw new IllegalArgumentException("interval must not be negative");
fastestInterval = millis;
return this;
}
/**
* Set the desired interval for active location updates, in milliseconds.
* <p/>
* The location client 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 that you will receive updates can be controlled with
* {@link #setFastestInterval(long)}. By default this fastest rate is 6x the interval frequency.
* <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 #setPriority(int)} and {@link #setInterval(long)} 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 LocationRequest setInterval(long millis) throws IllegalArgumentException {
if (millis < 0)
throw new IllegalArgumentException("interval must not be negative");
interval = millis;
return this;
}
/**
* 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 client.
* <p/>
* When using this option care must be taken to either explicitly remove the request when no
* longer needed or to set an expiration with ({@link #setExpirationDuration(long)} or
* {@link #setExpirationTime(long)}. Otherwise in some cases if a location can't be computed,
* this request could stay active indefinitely consuming power.
*
* @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 LocationRequest setNumUpdates(int numUpdates) throws IllegalArgumentException {
if (numUpdates <= 0)
throw new IllegalArgumentException("numUpdates must not be 0 or negative");
this.numUpdates = numUpdates;
return this;
}
/**
* Set the priority of the request.
* <p/>
* Use with a priority constant such as {@link #PRIORITY_HIGH_ACCURACY}. No other values are
* accepted.
* <p/>
* The priority of the request is a strong hint to the LocationClient for which location
* sources to use. For example, {@link #PRIORITY_HIGH_ACCURACY} is more likely to use GPS, and
* {@link #PRIORITY_BALANCED_POWER_ACCURACY} 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 #setPriority(int)} and {@link #setInterval(long)} are the most important parameters
* on a location request.
*
* @param priority 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 LocationRequest setPriority(int priority) {
switch (priority) {
default:
throw new IllegalArgumentException("priority is not a known constant");
case PRIORITY_BALANCED_POWER_ACCURACY:
case PRIORITY_HIGH_ACCURACY:
case PRIORITY_LOW_POWER:
case PRIORITY_NO_POWER:
this.priority = priority;
}
return this;
}
/**
* Set the minimum displacement between location updates in meters
* <p/>
* By default this is 0.
*
* @param smallestDisplacementMeters the smallest displacement in meters the user must move
* between location updates.
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if smallestDisplacementMeters is negative
*/
public LocationRequest setSmallestDesplacement(float smallestDisplacementMeters) {
if (smallestDisplacementMeters < 0)
throw new IllegalArgumentException("smallestDisplacementMeters must not be negative");
this.smallestDesplacement = smallestDisplacementMeters;
return this;
}
@Override
public String toString() {
// TODO
return super.toString();
}
public static final Creator<LocationRequest> CREATOR = new AutoCreator<>(LocationRequest.class);
}