mirror of https://github.com/YTVanced/VancedMicroG
528 lines
22 KiB
Java
528 lines
22 KiB
Java
/*
|
|
* Copyright (C) 2013-2017 microG Project Team
|
|
*
|
|
* 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 com.google.android.gms.location;
|
|
|
|
import android.os.SystemClock;
|
|
|
|
import org.microg.safeparcel.AutoSafeParcelable;
|
|
|
|
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;
|
|
|
|
@Field(1000)
|
|
private int versionCode = 1;
|
|
@Field(1)
|
|
private int priority;
|
|
@Field(2)
|
|
private long interval;
|
|
@Field(3)
|
|
private long fastestInterval;
|
|
@Field(4)
|
|
private boolean explicitFastestInterval;
|
|
@Field(5)
|
|
private long expirationTime;
|
|
@Field(6)
|
|
private int numUpdates;
|
|
@Field(7)
|
|
private float smallestDisplacement;
|
|
@Field(8)
|
|
private long maxWaitTime;
|
|
@Field(9)
|
|
private boolean waitForAccurateLocation;
|
|
|
|
public LocationRequest() {
|
|
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.smallestDisplacement = 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;
|
|
}
|
|
|
|
/**
|
|
* Gets the maximum wait time in milliseconds for location updates. If the wait time is smaller than the interval
|
|
* requested with {@link #setInterval(long)}, then the interval will be used instead.
|
|
*
|
|
* @return maximum wait time in milliseconds, inexact
|
|
* @see #setMaxWaitTime(long)
|
|
*/
|
|
public long getMaxWaitTime() {
|
|
return maxWaitTime;
|
|
}
|
|
|
|
/**
|
|
* 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 getSmallestDisplacement() {
|
|
return smallestDisplacement;
|
|
}
|
|
|
|
@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.smallestDisplacement, smallestDisplacement) != 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Arrays.hashCode(
|
|
new Object[]{priority, interval, fastestInterval, explicitFastestInterval,
|
|
explicitFastestInterval, numUpdates, smallestDisplacement, maxWaitTime
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns whether or not the fastest interval was explicitly specified for the location request.
|
|
*
|
|
* @return True if the fastest interval was explicitly set for the location request; false otherwise
|
|
*/
|
|
public boolean isFastestIntervalExplicitlySet() {
|
|
return explicitFastestInterval;
|
|
}
|
|
|
|
/**
|
|
* Returns whether the location services will wait a few seconds initially for accurate locations, if accurate
|
|
* locations cannot be computed on the device for {@link #PRIORITY_HIGH_ACCURACY} requests.
|
|
*/
|
|
public boolean isWaitForAccurateLocation() {
|
|
return waitForAccurateLocation;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
explicitFastestInterval = true;
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum wait time in milliseconds for location updates.
|
|
* <p>
|
|
* If you pass a value at least 2x larger than the interval specified with {@link #setInterval(long)}, then
|
|
* location delivery may be delayed and multiple locations can be delivered at once. Locations are determined at
|
|
* the {@link #setInterval(long)} rate, but can be delivered in batch after the interval you set in this method.
|
|
* This can consume less battery and give more accurate locations, depending on the device's hardware capabilities.
|
|
* You should set this value to be as large as possible for your needs if you don't need immediate location
|
|
* delivery.
|
|
*
|
|
* @param millis desired maximum wait time in millisecond, inexact
|
|
* @return the same object, so that setters can be chained
|
|
* @throws IllegalArgumentException if the interval is less than zero
|
|
*/
|
|
public LocationRequest setMaxWaitTime(long millis) throws IllegalArgumentException {
|
|
if (millis < 0)
|
|
throw new IllegalArgumentException("interval must not be negative");
|
|
maxWaitTime = 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 setSmallestDisplacement(float smallestDisplacementMeters) {
|
|
if (smallestDisplacementMeters < 0)
|
|
throw new IllegalArgumentException("smallestDisplacementMeters must not be negative");
|
|
this.smallestDisplacement = smallestDisplacementMeters;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets whether the client wants the locations services to wait a few seconds for accurate locations initially,
|
|
* when accurate locations could not be computed on the device immediately after {@link #PRIORITY_HIGH_ACCURACY}
|
|
* request is made. By default the location services will wait for accurate locations.
|
|
* <p>
|
|
* Note that this only applies to clients with {@link #PRIORITY_HIGH_ACCURACY} requests.
|
|
* <p>
|
|
* Also note this only applies to the initial locations computed right after the location request is added. The
|
|
* following inaccurate locations may still be delivered to the clients without delay.
|
|
*/
|
|
public LocationRequest setWaitForAccurateLocation(boolean waitForAccurateLocation) {
|
|
this.waitForAccurateLocation = waitForAccurateLocation;
|
|
return this;
|
|
}
|
|
|
|
private static String priorityToString(int priority) {
|
|
switch (priority) {
|
|
case PRIORITY_HIGH_ACCURACY:
|
|
return "PRIORITY_HIGH_ACCURACY";
|
|
case PRIORITY_BALANCED_POWER_ACCURACY:
|
|
return "PRIORITY_BALANCED_POWER_ACCURACY";
|
|
case PRIORITY_LOW_POWER:
|
|
return "PRIORITY_LOW_POWER";
|
|
case PRIORITY_NO_POWER:
|
|
return "PRIORITY_NO_POWER";
|
|
default:
|
|
return "???";
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append("Request[");
|
|
sb.append(priorityToString(priority));
|
|
if (priority != PRIORITY_NO_POWER)
|
|
sb.append(" requested=").append(interval).append("ms");
|
|
sb.append(" fastest=").append(fastestInterval).append("ms");
|
|
if (maxWaitTime > interval)
|
|
sb.append(" maxWait=").append(maxWaitTime).append("ms");
|
|
if (smallestDisplacement > 0)
|
|
sb.append(" smallestDisplacement=").append(smallestDisplacement).append("m");
|
|
if (expirationTime != Long.MAX_VALUE)
|
|
sb.append(" expireIn=").append(SystemClock.elapsedRealtime() - expirationTime).append("ms");
|
|
if (numUpdates != Integer.MAX_VALUE)
|
|
sb.append(" num=").append(numUpdates);
|
|
sb.append("]");
|
|
return sb.toString();
|
|
}
|
|
|
|
public static final Creator<LocationRequest> CREATOR = new AutoCreator<LocationRequest>(LocationRequest.class);
|
|
}
|