summaryrefslogtreecommitdiffstats
path: root/location/java
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2012-07-16 12:18:23 -0700
committerNick Pelly <npelly@google.com>2012-08-10 14:57:09 -0700
commit6fa9ad4afcd762aea519ff61811386c23d18ddb2 (patch)
tree5b027550205ada4b972f5cc3d8073819c07d9c75 /location/java
parentc47f80f1ae96e3c8b6a750d68cc12dfbbca97254 (diff)
downloadframeworks_base-6fa9ad4afcd762aea519ff61811386c23d18ddb2.zip
frameworks_base-6fa9ad4afcd762aea519ff61811386c23d18ddb2.tar.gz
frameworks_base-6fa9ad4afcd762aea519ff61811386c23d18ddb2.tar.bz2
Location overhaul, major commit.
Themes: Fused Location, Geofencing, LocationRequest. API changes o Fused location is always returned when asking for location by Criteria. o Fused location is never returned as a LocationProvider object, nor returned as a provider String. This wouldn't make sense because the current API design assumes that LocationProvider's have fixed properties (accuracy, power etc). o The fused location engine will tune itself based on the criteria passed by applications. o Deprecate LocationProvider. Apps should use fused location (via Criteria class), instead of enumerating through LocationProvider objects. It is also over-engineered: designed for a world with a plethora of location providers that never materialized. o The Criteria class is also over-engineered, with many methods that aren't currently used, but for now we won't deprecate them since they may have value in the future. It is now used to tune the fused location engine. o Deprecate getBestProvider() and getProvider(). o Add getLastKnownLocation(Criteria), so we can return last known fused locations. o Apps with only ACCESS_COARSE_LOCATION _can_ now use the GPS, but the location they receive will be fudged to a 1km radius. They can also use NETWORK and fused locatoins, which are fudged in the same way if necessary. o Totally deprecate Criteria, in favor of LocationRequest. Criteria was designed to map QOS to a location provider. What we really need is to map QOS to _locations_. The death knell was the conflicting ACCURACY_ constants on Criteria, with values 1, 2, 3, 1, 2. Yes not a typo. o Totally deprecate LocationProvider. o Deprecate test/mock provider support. They require a named provider, which is a concept we are moving away from. We do not yet have a replacement, but I think its ok to deprecate since you also need to have 'allow mock locations' checked in developer settings. They will continue to work. o Deprecate event codes associated with provider status. The fused provider is _always_ available. o Introduce Geofence data object to provide an easier path fowards for polygons etc. Implementation changes o Fused implementation: incoming (GPS and NLP) location fixes are given a weight, that exponentially decays with respect to age and accuracy. The half-life of age is ~60 seconds, and the half-life of accuracy is ~20 meters. The fixes are weighted and combined to output a fused location. o Move Fused Location impl into frameworks/base/packages/FusedLocation o Refactor Fused Location behind the IProvider AIDL interface. This allow us to distribute newer versions of Fused Location in a new APK, at run-time. o Introduce ServiceWatcher.java, to refactor code used for run-time upgrades of Fused Location, and the NLP. o Fused Location is by default run in the system server (but can be moved to any process or pacakge, even at run-time). o Plumb the Criteria requirements through to the Fused Location provider via ILocation.sendExtraCommand(). I re-used this interface to avoid modifying the ILocation interface, which would have broken run-time upgradability of the NLP. o Switch the geofence manager to using fused location. o Clean up 'adb shell dumpsys location' output. o Introduce config_locationProviderPackageNames and config_overlay_locationProviderPackageNames to configure the default and overlay package names for Geocoder, NLP and FLP. o Lots of misc cleanup. o Improve location fudging. Apply random vector then quantize. o Hide internal POJO's from clients of com.android.location.provider.jar (NLP and FLP). Introduce wrappers ProviderRequestUnbundled and ProviderPropertiesUnbundled. o Introduce ProviderProperties to collapse all the provider accuracy/ bearing/altitude/power plumbing (that is deprecated anyway). o DELETE lots of code: DummyLocationProvider, o Rename the (internal) LocationProvider to LocationProviderBase. o Plumb pid, uid and packageName throughout LocationManagerService#Receiver to support future features. TODO: The FLP and Geofencer have a lot of room to be more intelligent TODO: Documentation TODO: test test test Change-Id: Iacefd2f176ed40ce1e23b090a164792aa8819c55
Diffstat (limited to 'location/java')
-rw-r--r--location/java/android/location/Criteria.java45
-rw-r--r--location/java/android/location/Geofence.aidl19
-rw-r--r--location/java/android/location/Geofence.java174
-rw-r--r--location/java/android/location/ILocationManager.aidl72
-rw-r--r--location/java/android/location/Location.java68
-rw-r--r--location/java/android/location/LocationManager.java606
-rw-r--r--location/java/android/location/LocationProvider.java114
-rw-r--r--location/java/android/location/LocationRequest.aidl19
-rw-r--r--location/java/android/location/LocationRequest.java321
-rw-r--r--location/java/com/android/internal/location/DummyLocationProvider.java180
-rw-r--r--location/java/com/android/internal/location/ILocationProvider.aidl (renamed from location/java/android/location/ILocationProvider.aidl)33
-rw-r--r--location/java/com/android/internal/location/ProviderProperties.aidl19
-rw-r--r--location/java/com/android/internal/location/ProviderProperties.java152
-rw-r--r--location/java/com/android/internal/location/ProviderRequest.aidl19
-rw-r--r--location/java/com/android/internal/location/ProviderRequest.java94
15 files changed, 1422 insertions, 513 deletions
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index 1f3fb7a..6258a43 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -24,7 +24,9 @@ import android.os.Parcelable;
* location provider. Providers maybe ordered according to accuracy,
* power usage, ability to report altitude, speed,
* and bearing, and monetary cost.
+ * @deprecated {@link LocationRequest} instead
*/
+@Deprecated
public class Criteria implements Parcelable {
/**
* A constant indicating that the application does not choose to
@@ -326,6 +328,7 @@ public class Criteria implements Parcelable {
public static final Parcelable.Creator<Criteria> CREATOR =
new Parcelable.Creator<Criteria>() {
+ @Override
public Criteria createFromParcel(Parcel in) {
Criteria c = new Criteria();
c.mHorizontalAccuracy = in.readInt();
@@ -340,15 +343,18 @@ public class Criteria implements Parcelable {
return c;
}
+ @Override
public Criteria[] newArray(int size) {
return new Criteria[size];
}
};
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mHorizontalAccuracy);
parcel.writeInt(mVerticalAccuracy);
@@ -360,4 +366,43 @@ public class Criteria implements Parcelable {
parcel.writeInt(mSpeedRequired ? 1 : 0);
parcel.writeInt(mCostAllowed ? 1 : 0);
}
+
+ private static String powerToString(int power) {
+ switch (power) {
+ case NO_REQUIREMENT:
+ return "NO_REQ";
+ case POWER_LOW:
+ return "LOW";
+ case POWER_MEDIUM:
+ return "MEDIUM";
+ case POWER_HIGH:
+ return "HIGH";
+ default:
+ return "???";
+ }
+ }
+
+ private static String accuracyToString(int accuracy) {
+ switch (accuracy) {
+ case NO_REQUIREMENT:
+ return "---";
+ case ACCURACY_HIGH:
+ return "HIGH";
+ case ACCURACY_MEDIUM:
+ return "MEDIUM";
+ case ACCURACY_LOW:
+ return "LOW";
+ default:
+ return "???";
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("Criteria[power=").append(powerToString(mPowerRequirement));
+ s.append(" acc=").append(accuracyToString(mHorizontalAccuracy));
+ s.append(']');
+ return s.toString();
+ }
}
diff --git a/location/java/android/location/Geofence.aidl b/location/java/android/location/Geofence.aidl
new file mode 100644
index 0000000..a5c6aa0
--- /dev/null
+++ b/location/java/android/location/Geofence.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable Geofence;
diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java
new file mode 100644
index 0000000..353a1ca
--- /dev/null
+++ b/location/java/android/location/Geofence.java
@@ -0,0 +1,174 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a Geofence
+ */
+public final class Geofence implements Parcelable {
+ /** @hide */
+ public static final int TYPE_HORIZONTAL_CIRCLE = 1;
+
+ private final int mType;
+ private final double mLatitude;
+ private final double mLongitude;
+ private final float mRadius;
+
+ /**
+ * Create a horizontal, circular geofence.
+ * @param latitude latitude in degrees
+ * @param longitude longitude in degrees
+ * @param radius radius in meters
+ * @return a new geofence
+ * @throws IllegalArgumentException if any parameters are out of range
+ */
+ public static Geofence createCircle(double latitude, double longitude, float radius) {
+ return new Geofence(latitude, longitude, radius);
+ }
+
+ private Geofence(double latitude, double longitude, float radius) {
+ checkRadius(radius);
+ checkLatLong(latitude, longitude);
+ mType = TYPE_HORIZONTAL_CIRCLE;
+ mLatitude = latitude;
+ mLongitude = longitude;
+ mRadius = radius;
+ }
+
+ /** @hide */
+ public int getType() {
+ return mType;
+ }
+
+ /** @hide */
+ public double getLatitude() {
+ return mLatitude;
+ }
+
+ /** @hide */
+ public double getLongitude() {
+ return mLongitude;
+ }
+
+ /** @hide */
+ public float getRadius() {
+ return mRadius;
+ }
+
+ private static void checkRadius(float radius) {
+ if (radius <= 0) {
+ throw new IllegalArgumentException("invalid radius: " + radius);
+ }
+ }
+
+ private static void checkLatLong(double latitude, double longitude) {
+ if (latitude > 90.0 || latitude < -90.0) {
+ throw new IllegalArgumentException("invalid latitude: " + latitude);
+ }
+ if (longitude > 180.0 || longitude < -180.0) {
+ throw new IllegalArgumentException("invalid longitude: " + longitude);
+ }
+ }
+
+ private static void checkType(int type) {
+ if (type != TYPE_HORIZONTAL_CIRCLE) {
+ throw new IllegalArgumentException("invalid type: " + type);
+ }
+ }
+
+ public static final Parcelable.Creator<Geofence> CREATOR = new Parcelable.Creator<Geofence>() {
+ @Override
+ public Geofence createFromParcel(Parcel in) {
+ int type = in.readInt();
+ double latitude = in.readDouble();
+ double longitude = in.readDouble();
+ float radius = in.readFloat();
+ checkType(type);
+ return Geofence.createCircle(latitude, longitude, radius);
+ }
+ @Override
+ public Geofence[] newArray(int size) {
+ return new Geofence[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mType);
+ parcel.writeDouble(mLatitude);
+ parcel.writeDouble(mLongitude);
+ parcel.writeFloat(mRadius);
+ }
+
+ private static String typeToString(int type) {
+ switch (type) {
+ case TYPE_HORIZONTAL_CIRCLE:
+ return "CIRCLE";
+ default:
+ checkType(type);
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Geofence[%s %.6f, %.6f %.0fm]",
+ typeToString(mType), mLatitude, mLongitude, mRadius);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(mLatitude);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(mLongitude);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + Float.floatToIntBits(mRadius);
+ result = prime * result + mType;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof Geofence))
+ return false;
+ Geofence other = (Geofence) obj;
+ if (mRadius != other.mRadius)
+ return false;
+ if (mLatitude != other.mLatitude)
+ return false;
+ if (mLongitude != other.mLongitude)
+ return false;
+ if (mType != other.mType)
+ return false;
+ return true;
+ }
+}
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 47b7adf..a2ce606 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -20,53 +20,36 @@ import android.app.PendingIntent;
import android.location.Address;
import android.location.Criteria;
import android.location.GeocoderParams;
+import android.location.Geofence;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
import android.location.ILocationListener;
import android.location.Location;
+import android.location.LocationRequest;
import android.os.Bundle;
+import com.android.internal.location.ProviderProperties;
+
/**
* System private API for talking with the location service.
*
- * {@hide}
+ * @hide
*/
interface ILocationManager
{
- List<String> getAllProviders();
- List<String> getProviders(in Criteria criteria, boolean enabledOnly);
- String getBestProvider(in Criteria criteria, boolean enabledOnly);
- boolean providerMeetsCriteria(String provider, in Criteria criteria);
+ void requestLocationUpdates(in LocationRequest request, in ILocationListener listener,
+ in PendingIntent intent, String packageName);
+ void removeUpdates(in ILocationListener listener, in PendingIntent intent, String packageName);
+
+ void requestGeofence(in LocationRequest request, in Geofence geofence,
+ in PendingIntent intent, String packageName);
+ void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName);
- void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
- boolean singleShot, in ILocationListener listener);
- void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
- boolean singleShot, in PendingIntent intent);
- void removeUpdates(in ILocationListener listener);
- void removeUpdatesPI(in PendingIntent intent);
+ Location getLastLocation(in LocationRequest request);
boolean addGpsStatusListener(IGpsStatusListener listener);
void removeGpsStatusListener(IGpsStatusListener listener);
- // for reporting callback completion
- void locationCallbackFinished(ILocationListener listener);
-
- boolean sendExtraCommand(String provider, String command, inout Bundle extras);
-
- void addProximityAlert(double latitude, double longitude, float distance,
- long expiration, in PendingIntent intent, in String packageName);
- void removeProximityAlert(in PendingIntent intent);
-
- Bundle getProviderInfo(String provider);
- boolean isProviderEnabled(String provider);
-
- Location getLastKnownLocation(String provider);
-
- // Used by location providers to tell the location manager when it has a new location.
- // Passive is true if the location is coming from the passive provider, in which case
- // it need not be shared with other providers.
- void reportLocation(in Location location, boolean passive);
-
boolean geocoderIsPresent();
String getFromLocation(double latitude, double longitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
@@ -75,9 +58,17 @@ interface ILocationManager
double upperRightLatitude, double upperRightLongitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
- void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
- boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
- boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy);
+ boolean sendNiResponse(int notifId, int userResponse);
+
+ // --- deprecated ---
+ List<String> getAllProviders();
+ List<String> getProviders(in Criteria criteria, boolean enabledOnly);
+ String getBestProvider(in Criteria criteria, boolean enabledOnly);
+ boolean providerMeetsCriteria(String provider, in Criteria criteria);
+ ProviderProperties getProviderProperties(String provider);
+ boolean isProviderEnabled(String provider);
+
+ void addTestProvider(String name, in ProviderProperties properties);
void removeTestProvider(String provider);
void setTestProviderLocation(String provider, in Location loc);
void clearTestProviderLocation(String provider);
@@ -86,6 +77,17 @@ interface ILocationManager
void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime);
void clearTestProviderStatus(String provider);
- // for NI support
- boolean sendNiResponse(int notifId, int userResponse);
+ boolean sendExtraCommand(String provider, String command, inout Bundle extras);
+
+ // --- internal ---
+
+ // Used by location providers to tell the location manager when it has a new location.
+ // Passive is true if the location is coming from the passive provider, in which case
+ // it need not be shared with other providers.
+ void reportLocation(in Location location, boolean passive);
+
+ // for reporting callback completion
+ void locationCallbackFinished(ILocationListener listener);
+
+
}
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 5ad60ab..ece4500 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -21,6 +21,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.Printer;
+import android.util.TimeUtils;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
@@ -84,17 +85,6 @@ public class Location implements Parcelable {
// Scratchpad
private float[] mResults = new float[2];
- public void dump(Printer pw, String prefix) {
- pw.println(prefix + "mProvider=" + mProvider + " mTime=" + mTime);
- pw.println(prefix + "mElapsedRealtimeNano=" + mElapsedRealtimeNano);
- pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude);
- pw.println(prefix + "mHasAltitude=" + mHasAltitude + " mAltitude=" + mAltitude);
- pw.println(prefix + "mHasSpeed=" + mHasSpeed + " mSpeed=" + mSpeed);
- pw.println(prefix + "mHasBearing=" + mHasBearing + " mBearing=" + mBearing);
- pw.println(prefix + "mHasAccuracy=" + mHasAccuracy + " mAccuracy=" + mAccuracy);
- pw.println(prefix + "mExtras=" + mExtras);
- }
-
/**
* Constructs a new Location. By default, time, latitude,
* longitude, and numSatellites are 0; hasAltitude, hasSpeed, and
@@ -766,25 +756,46 @@ public class Location implements Parcelable {
mExtras = (extras == null) ? null : new Bundle(extras);
}
- @Override public String toString() {
- return "Location[mProvider=" + mProvider +
- ",mTime=" + mTime +
- ",mElapsedRealtimeNano=" + mElapsedRealtimeNano +
- ",mLatitude=" + mLatitude +
- ",mLongitude=" + mLongitude +
- ",mHasAltitude=" + mHasAltitude +
- ",mAltitude=" + mAltitude +
- ",mHasSpeed=" + mHasSpeed +
- ",mSpeed=" + mSpeed +
- ",mHasBearing=" + mHasBearing +
- ",mBearing=" + mBearing +
- ",mHasAccuracy=" + mHasAccuracy +
- ",mAccuracy=" + mAccuracy +
- ",mExtras=" + mExtras + "]";
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("Location[");
+ s.append(mProvider);
+ s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
+ if (mHasAccuracy) s.append(String.format(" acc=%.0f", mAccuracy));
+ else s.append(" acc=???");
+ if (mTime == 0) {
+ s.append(" t=?!?");
+ }
+ if (mElapsedRealtimeNano == 0) {
+ s.append(" et=?!?");
+ } else {
+ long age = SystemClock.elapsedRealtimeNano() - mElapsedRealtimeNano;
+ s.append(" age=");
+ TimeUtils.formatDuration(age / 1000000L, s);
+ }
+ if (mHasAltitude) s.append(" alt=").append(mAltitude);
+ if (mHasSpeed) s.append(" vel=").append(mSpeed);
+ if (mHasBearing) s.append(" bear=").append(mBearing);
+
+ if (mExtras != null) {
+ s.append(" {").append(mExtras).append('}');
+ }
+ s.append(']');
+ return s.toString();
+ }
+
+ /**
+ * @deprecated Use {@link #toString} instead
+ */
+ @Deprecated
+ public void dump(Printer pw, String prefix) {
+ pw.println(prefix + toString());
}
public static final Parcelable.Creator<Location> CREATOR =
new Parcelable.Creator<Location>() {
+ @Override
public Location createFromParcel(Parcel in) {
String provider = in.readString();
Location l = new Location(provider);
@@ -804,15 +815,18 @@ public class Location implements Parcelable {
return l;
}
+ @Override
public Location[] newArray(int size) {
return new Location[size];
}
};
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mProvider);
parcel.writeLong(mTime);
@@ -828,5 +842,5 @@ public class Location implements Parcelable {
parcel.writeInt(mHasAccuracy ? 1 : 0);
parcel.writeFloat(mAccuracy);
parcel.writeBundle(mExtras);
- }
+ }
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 15a2928..083b900 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -25,15 +25,15 @@ import android.os.Looper;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
-import android.os.SystemClock;
import android.util.Log;
-import com.android.internal.location.DummyLocationProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import com.android.internal.location.ProviderProperties;
+
/**
* This class provides access to the system location services. These
* services allow applications to obtain periodic updates of the
@@ -71,7 +71,9 @@ public class LocationManager {
*
* Requires either of the permissions android.permission.ACCESS_COARSE_LOCATION
* or android.permission.ACCESS_FINE_LOCATION.
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String NETWORK_PROVIDER = "network";
/**
@@ -87,7 +89,9 @@ public class LocationManager {
* <ul>
* <li> satellites - the number of satellites used to derive the fix
* </ul>
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String GPS_PROVIDER = "gps";
/**
@@ -100,10 +104,22 @@ public class LocationManager {
*
* Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS
* is not enabled this provider might only return coarse fixes.
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String PASSIVE_PROVIDER = "passive";
/**
+ * Name of the Fused location provider.<p>
+ * This provider combines inputs for all possible location sources
+ * to provide the best possible Location fix.<p>
+ *
+ * Requires the permission android.permission.ACCESS_FINE_LOCATION.
+ * @hide
+ */
+ public static final String FUSED_PROVIDER = "fused";
+
+ /**
* Key used for the Bundle extra holding a boolean indicating whether
* a proximity alert is entering (true) or exiting (false)..
*/
@@ -112,13 +128,17 @@ public class LocationManager {
/**
* Key used for a Bundle extra holding an Integer status value
* when a status change is broadcast using a PendingIntent.
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String KEY_STATUS_CHANGED = "status";
/**
* Key used for a Bundle extra holding an Boolean status value
* when a provider enabled/disabled event is broadcast using a PendingIntent.
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
/**
@@ -141,7 +161,9 @@ public class LocationManager {
/**
* Broadcast intent action when the configured location providers
* change.
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public static final String PROVIDERS_CHANGED_ACTION =
"android.location.PROVIDERS_CHANGED";
@@ -274,19 +296,8 @@ public class LocationManager {
mContext = context;
}
- private LocationProvider createProvider(String name, Bundle info) {
- DummyLocationProvider provider =
- new DummyLocationProvider(name, mService);
- provider.setRequiresNetwork(info.getBoolean("network"));
- provider.setRequiresSatellite(info.getBoolean("satellite"));
- provider.setRequiresCell(info.getBoolean("cell"));
- provider.setHasMonetaryCost(info.getBoolean("cost"));
- provider.setSupportsAltitude(info.getBoolean("altitude"));
- provider.setSupportsSpeed(info.getBoolean("speed"));
- provider.setSupportsBearing(info.getBoolean("bearing"));
- provider.setPowerRequirement(info.getInt("power"));
- provider.setAccuracy(info.getInt("accuracy"));
- return provider;
+ private LocationProvider createProvider(String name, ProviderProperties properties) {
+ return new LocationProvider(name, properties);
}
/**
@@ -295,15 +306,14 @@ public class LocationManager {
* accessed by the calling activity or are currently disabled.
*
* @return list of Strings containing names of the providers
+ * @deprecated use the {@link Criteria} class instead
*/
+ @Deprecated
public List<String> getAllProviders() {
- if (false) {
- Log.d(TAG, "getAllProviders");
- }
try {
return mService.getAllProviders();
- } catch (RemoteException ex) {
- Log.e(TAG, "getAllProviders: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
return null;
}
@@ -315,12 +325,16 @@ public class LocationManager {
* @param enabledOnly if true then only the providers which are currently
* enabled are returned.
* @return list of Strings containing names of the providers
+ * @deprecated The {@link LocationProvider} class is deprecated. So
+ * use the {@link Criteria} class to request location instead of
+ * enumerating providers.
*/
+ @Deprecated
public List<String> getProviders(boolean enabledOnly) {
try {
return mService.getProviders(null, enabledOnly);
- } catch (RemoteException ex) {
- Log.e(TAG, "getProviders: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
return null;
}
@@ -332,22 +346,24 @@ public class LocationManager {
* @param name the provider name
* @return a LocationProvider, or null
*
- * @throws IllegalArgumentException if name is null
+ * @throws IllegalArgumentException if name is null or does not exisit
* @throws SecurityException if the caller is not permitted to access the
* given provider.
+ * @deprecated The {@link LocationProvider} class is deprecated. So
+ * use the {@link Criteria} class to request location instead of
+ * enumerating providers.
*/
+ @Deprecated
public LocationProvider getProvider(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name==null");
- }
+ checkProvider(name);
try {
- Bundle info = mService.getProviderInfo(name);
- if (info == null) {
+ ProviderProperties properties = mService.getProviderProperties(name);
+ if (properties == null) {
return null;
}
- return createProvider(name, info);
- } catch (RemoteException ex) {
- Log.e(TAG, "getProvider: RemoteException", ex);
+ return createProvider(name, properties);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
return null;
}
@@ -361,15 +377,17 @@ public class LocationManager {
* @param enabledOnly if true then only the providers which are currently
* enabled are returned.
* @return list of Strings containing names of the providers
+ * @deprecated The {@link LocationProvider} class is deprecated. So
+ * use the {@link Criteria} class to request location instead of
+ * enumerating providers.
*/
+ @Deprecated
public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
+ checkCriteria(criteria);
try {
return mService.getProviders(criteria, enabledOnly);
- } catch (RemoteException ex) {
- Log.e(TAG, "getProviders: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
return null;
}
@@ -395,15 +413,15 @@ public class LocationManager {
* @param criteria the criteria that need to be matched
* @param enabledOnly if true then only a provider that is currently enabled is returned
* @return name of the provider that best matches the requirements
+ * @deprecated using an explicit provider doesn't allow fused location
*/
+ @Deprecated
public String getBestProvider(Criteria criteria, boolean enabledOnly) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
+ checkCriteria(criteria);
try {
return mService.getBestProvider(criteria, enabledOnly);
- } catch (RemoteException ex) {
- Log.e(TAG, "getBestProvider: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
return null;
}
@@ -480,16 +498,17 @@ public class LocationManager {
* @throws IllegalArgumentException if listener is null
* @throws RuntimeException if the calling thread has no Looper
* @throws SecurityException if no suitable permission is present for the provider.
+ * @deprecated use the {@link LocationRequest} class instead
*/
- public void requestLocationUpdates(String provider,
- long minTime, float minDistance, LocationListener listener) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- _requestLocationUpdates(provider, null, minTime, minDistance, false, listener, null);
+ @Deprecated
+ public void requestLocationUpdates(String provider, long minTime, float minDistance,
+ LocationListener listener) {
+ checkProvider(provider);
+ checkListener(listener);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, minTime, minDistance, false);
+ requestLocationUpdates(request, listener, null, null);
}
/**
@@ -564,17 +583,17 @@ public class LocationManager {
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present for the provider.
+ * @deprecated use the {@link LocationRequest} class instead
*/
- public void requestLocationUpdates(String provider,
- long minTime, float minDistance, LocationListener listener,
- Looper looper) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- _requestLocationUpdates(provider, null, minTime, minDistance, false, listener, looper);
+ @Deprecated
+ public void requestLocationUpdates(String provider, long minTime, float minDistance,
+ LocationListener listener, Looper looper) {
+ checkProvider(provider);
+ checkListener(listener);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, minTime, minDistance, false);
+ requestLocationUpdates(request, listener, looper, null);
}
/**
@@ -639,39 +658,17 @@ public class LocationManager {
* @throws IllegalArgumentException if criteria is null
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present for the provider.
+ * @deprecated use the {@link LocationRequest} class instead
*/
- public void requestLocationUpdates(long minTime, float minDistance,
- Criteria criteria, LocationListener listener, Looper looper) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- _requestLocationUpdates(null, criteria, minTime, minDistance, false, listener, looper);
- }
-
- private void _requestLocationUpdates(String provider, Criteria criteria, long minTime,
- float minDistance, boolean singleShot, LocationListener listener, Looper looper) {
- if (minTime < 0L) {
- minTime = 0L;
- }
- if (minDistance < 0.0f) {
- minDistance = 0.0f;
- }
+ @Deprecated
+ public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
+ LocationListener listener, Looper looper) {
+ checkCriteria(criteria);
+ checkListener(listener);
- try {
- synchronized (mListeners) {
- ListenerTransport transport = mListeners.get(listener);
- if (transport == null) {
- transport = new ListenerTransport(listener, looper);
- }
- mListeners.put(listener, transport);
- mService.requestLocationUpdates(provider, criteria, minTime, minDistance, singleShot, transport);
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "requestLocationUpdates: DeadObjectException", ex);
- }
+ LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+ criteria, minTime, minDistance, false);
+ requestLocationUpdates(request, listener, looper, null);
}
/**
@@ -749,16 +746,17 @@ public class LocationManager {
* on this device
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present for the provider.
+ * @deprecated use the {@link LocationRequest} class instead
*/
- public void requestLocationUpdates(String provider,
- long minTime, float minDistance, PendingIntent intent) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
- if (intent == null) {
- throw new IllegalArgumentException("intent==null");
- }
- _requestLocationUpdates(provider, null, minTime, minDistance, false, intent);
+ @Deprecated
+ public void requestLocationUpdates(String provider, long minTime, float minDistance,
+ PendingIntent intent) {
+ checkProvider(provider);
+ checkPendingIntent(intent);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, minTime, minDistance, false);
+ requestLocationUpdates(request, null, null, intent);
}
/**
@@ -825,32 +823,17 @@ public class LocationManager {
* @throws IllegalArgumentException if criteria is null
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present for the provider.
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
PendingIntent intent) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
- if (intent == null) {
- throw new IllegalArgumentException("intent==null");
- }
- _requestLocationUpdates(null, criteria, minTime, minDistance, false, intent);
- }
-
- private void _requestLocationUpdates(String provider, Criteria criteria,
- long minTime, float minDistance, boolean singleShot, PendingIntent intent) {
- if (minTime < 0L) {
- minTime = 0L;
- }
- if (minDistance < 0.0f) {
- minDistance = 0.0f;
- }
+ checkCriteria(criteria);
+ checkPendingIntent(intent);
- try {
- mService.requestLocationUpdatesPI(provider, criteria, minTime, minDistance, singleShot, intent);
- } catch (RemoteException ex) {
- Log.e(TAG, "requestLocationUpdates: RemoteException", ex);
- }
+ LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+ criteria, minTime, minDistance, false);
+ requestLocationUpdates(request, null, null, intent);
}
/**
@@ -879,15 +862,16 @@ public class LocationManager {
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present for the provider
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- _requestLocationUpdates(provider, null, 0L, 0.0f, true, listener, looper);
+ checkProvider(provider);
+ checkListener(listener);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, 0, 0, true);
+ requestLocationUpdates(request, listener, looper, null);
}
/**
@@ -918,15 +902,16 @@ public class LocationManager {
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present to access
* the location services
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- _requestLocationUpdates(null, criteria, 0L, 0.0f, true, listener, looper);
+ checkCriteria(criteria);
+ checkListener(listener);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+ criteria, 0, 0, true);
+ requestLocationUpdates(request, listener, looper, null);
}
/**
@@ -951,15 +936,16 @@ public class LocationManager {
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present for the provider
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void requestSingleUpdate(String provider, PendingIntent intent) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
- if (intent == null) {
- throw new IllegalArgumentException("intent==null");
- }
- _requestLocationUpdates(provider, null, 0L, 0.0f, true, intent);
+ checkProvider(provider);
+ checkPendingIntent(intent);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, 0, 0, true);
+ requestLocationUpdates(request, null, null, intent);
}
/**
@@ -986,15 +972,54 @@ public class LocationManager {
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present for the provider
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void requestSingleUpdate(Criteria criteria, PendingIntent intent) {
- if (criteria == null) {
- throw new IllegalArgumentException("criteria==null");
- }
- if (intent == null) {
- throw new IllegalArgumentException("intent==null");
+ checkCriteria(criteria);
+ checkPendingIntent(intent);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+ criteria, 0, 0, true);
+ requestLocationUpdates(request, null, null, intent);
+ }
+
+ public void requestLocationUpdates(LocationRequest request, LocationListener listener,
+ Looper looper) {
+ checkListener(listener);
+ requestLocationUpdates(request, listener, looper, null);
+ }
+
+ public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
+ checkPendingIntent(intent);
+ requestLocationUpdates(request, null, null, intent);
+ }
+
+ private ListenerTransport wrapListener(LocationListener listener, Looper looper) {
+ if (listener == null) return null;
+ synchronized (mListeners) {
+ ListenerTransport transport = mListeners.get(listener);
+ if (transport == null) {
+ transport = new ListenerTransport(listener, looper);
+ }
+ mListeners.put(listener, transport);
+ return transport;
}
- _requestLocationUpdates(null, criteria, 0L, 0.0f, true, intent);
+ }
+
+ private void requestLocationUpdates(LocationRequest request, LocationListener listener,
+ Looper looper, PendingIntent intent) {
+
+ String packageName = mContext.getPackageName();
+
+ // wrap the listener class
+ ListenerTransport transport = wrapListener(listener, looper);
+
+ try {
+ mService.requestLocationUpdates(request, transport, intent, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
+ }
}
/**
@@ -1006,19 +1031,19 @@ public class LocationManager {
* @throws IllegalArgumentException if listener is null
*/
public void removeUpdates(LocationListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("listener==null");
- }
- if (false) {
- Log.d(TAG, "removeUpdates: listener = " + listener);
+ checkListener(listener);
+ String packageName = mContext.getPackageName();
+
+ ListenerTransport transport;
+ synchronized (mListeners) {
+ transport = mListeners.remove(listener);
}
+ if (transport == null) return;
+
try {
- ListenerTransport transport = mListeners.remove(listener);
- if (transport != null) {
- mService.removeUpdates(transport);
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "removeUpdates: DeadObjectException", ex);
+ mService.removeUpdates(transport, null, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1031,16 +1056,13 @@ public class LocationManager {
* @throws IllegalArgumentException if intent is null
*/
public void removeUpdates(PendingIntent intent) {
- if (intent == null) {
- throw new IllegalArgumentException("intent==null");
- }
- if (false) {
- Log.d(TAG, "removeUpdates: intent = " + intent);
- }
+ checkPendingIntent(intent);
+ String packageName = mContext.getPackageName();
+
try {
- mService.removeUpdatesPI(intent);
- } catch (RemoteException ex) {
- Log.e(TAG, "removeUpdates: RemoteException", ex);
+ mService.removeUpdates(null, intent, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1086,20 +1108,31 @@ public class LocationManager {
*
* @throws SecurityException if no permission exists for the required
* providers.
+ * @deprecated use the {@link LocationRequest} class instead
*/
- public void addProximityAlert(double latitude, double longitude,
- float radius, long expiration, PendingIntent intent) {
- if (false) {
- Log.d(TAG, "addProximityAlert: latitude = " + latitude +
- ", longitude = " + longitude + ", radius = " + radius +
- ", expiration = " + expiration +
- ", intent = " + intent);
+ @Deprecated
+ public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
+ PendingIntent intent) {
+ checkPendingIntent(intent);
+ if (expiration < 0) expiration = Long.MAX_VALUE;
+
+ Geofence fence = Geofence.createCircle(latitude, longitude, radius);
+ LocationRequest request = new LocationRequest().setExpireIn(expiration);
+ try {
+ mService.requestGeofence(request, fence, intent, mContext.getPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
+ }
+
+ public void requestGeofence(LocationRequest request, Geofence fence, PendingIntent intent) {
+ checkPendingIntent(intent);
+ checkGeofence(fence);
+
try {
- mService.addProximityAlert(latitude, longitude, radius, expiration, intent,
- mContext.getPackageName());
- } catch (RemoteException ex) {
- Log.e(TAG, "addProximityAlert: RemoteException", ex);
+ mService.requestGeofence(request, fence, intent, mContext.getPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1108,15 +1141,40 @@ public class LocationManager {
*
* @param intent the PendingIntent that no longer needs to be notified of
* proximity alerts
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void removeProximityAlert(PendingIntent intent) {
- if (false) {
- Log.d(TAG, "removeProximityAlert: intent = " + intent);
+ checkPendingIntent(intent);
+ String packageName = mContext.getPackageName();
+
+ try {
+ mService.removeGeofence(null, intent, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
+ }
+
+ public void removeGeofence(Geofence fence, PendingIntent intent) {
+ checkPendingIntent(intent);
+ checkGeofence(fence);
+ String packageName = mContext.getPackageName();
+
try {
- mService.removeProximityAlert(intent);
- } catch (RemoteException ex) {
- Log.e(TAG, "removeProximityAlert: RemoteException", ex);
+ mService.removeGeofence(fence, intent, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
+ }
+ }
+
+ public void removeAllGeofences(PendingIntent intent) {
+ checkPendingIntent(intent);
+ String packageName = mContext.getPackageName();
+
+ try {
+ mService.removeGeofence(null, intent, packageName);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1130,19 +1188,30 @@ public class LocationManager {
*
* @throws SecurityException if no suitable permission is present for the provider.
* @throws IllegalArgumentException if provider is null
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public boolean isProviderEnabled(String provider) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
- }
+ checkProvider(provider);
+
try {
return mService.isProviderEnabled(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "isProviderEnabled: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
return false;
}
}
+ public Location getLastLocation(LocationRequest request) {
+ try {
+ return mService.getLastLocation(request);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
+ return null;
+ }
+ }
+
+
/**
* Returns a Location indicating the data from the last known
* location fix obtained from the given provider. This can be done
@@ -1157,15 +1226,49 @@ public class LocationManager {
*
* @throws SecurityException if no suitable permission is present for the provider.
* @throws IllegalArgumentException if provider is null or doesn't exist
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public Location getLastKnownLocation(String provider) {
- if (provider == null) {
- throw new IllegalArgumentException("provider==null");
+ checkProvider(provider);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+ provider, 0, 0, true);
+
+ try {
+ return mService.getLastLocation(request);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
+ return null;
}
+ }
+
+ /**
+ * Return the last know Location that satisfies the given
+ * criteria. This can be done without starting the provider.
+ * Note that this location could
+ * be out-of-date, for example if the device was turned off and
+ * moved to another location.
+ *
+ * <p> If no location is found that satisfies the criteria, null is returned
+ *
+ * @param criteria location criteria
+ * @return the last known location that satisfies criteria, or null
+ *
+ * @throws SecurityException if no suitable permission is present
+ * @throws IllegalArgumentException if criteria is null
+ * @deprecated use the {@link LocationRequest} class instead
+ */
+ @Deprecated
+ public Location getLastKnownLocation(Criteria criteria) {
+ checkCriteria(criteria);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+ criteria, 0, 0, true);
try {
- return mService.getLastKnownLocation(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "getLastKnowLocation: RemoteException", ex);
+ return mService.getLastLocation(request);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
return null;
}
}
@@ -1190,16 +1293,23 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION} system setting is not enabled
* @throws IllegalArgumentException if a provider with the given name already exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
- boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
- boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
+ boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
+ boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
+ ProviderProperties properties = new ProviderProperties(requiresNetwork,
+ requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed,
+ supportsBearing, powerRequirement, accuracy);
+ if (name.matches(LocationProvider.BAD_CHARS_REGEX)) {
+ throw new IllegalArgumentException("provider name contains illegal character: " + name);
+ }
+
try {
- mService.addTestProvider(name, requiresNetwork, requiresSatellite, requiresCell,
- hasMonetaryCost, supportsAltitude, supportsSpeed, supportsBearing, powerRequirement,
- accuracy);
- } catch (RemoteException ex) {
- Log.e(TAG, "addTestProvider: RemoteException", ex);
+ mService.addTestProvider(name, properties);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1212,12 +1322,14 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void removeTestProvider(String provider) {
try {
mService.removeTestProvider(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "removeTestProvider: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1236,23 +1348,27 @@ public class LocationManager {
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
* @throws IllegalArgumentException if the location is incomplete
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void setTestProviderLocation(String provider, Location loc) {
if (!loc.isComplete()) {
+ IllegalArgumentException e = new IllegalArgumentException(
+ "Incomplete location object, missing timestamp or accuracy? " + loc);
if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN) {
- // for backwards compatibility, allow mock locations that are incomplete
- Log.w(TAG, "Incomplete Location object", new Throwable());
+ // just log on old platform (for backwards compatibility)
+ Log.w(TAG, e);
loc.makeComplete();
} else {
- throw new IllegalArgumentException(
- "Location object not complete. Missing timestamps or accuracy?");
+ // really throw it!
+ throw e;
}
}
try {
mService.setTestProviderLocation(provider, loc);
- } catch (RemoteException ex) {
- Log.e(TAG, "setTestProviderLocation: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1265,12 +1381,14 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void clearTestProviderLocation(String provider) {
try {
mService.clearTestProviderLocation(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "clearTestProviderLocation: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1285,12 +1403,14 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void setTestProviderEnabled(String provider, boolean enabled) {
try {
mService.setTestProviderEnabled(provider, enabled);
- } catch (RemoteException ex) {
- Log.e(TAG, "setTestProviderEnabled: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1303,14 +1423,15 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void clearTestProviderEnabled(String provider) {
try {
mService.clearTestProviderEnabled(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "clearTestProviderEnabled: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
-
}
/**
@@ -1326,12 +1447,14 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
try {
mService.setTestProviderStatus(provider, status, extras, updateTime);
- } catch (RemoteException ex) {
- Log.e(TAG, "setTestProviderStatus: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1344,12 +1467,14 @@ public class LocationManager {
* or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
* Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
* @throws IllegalArgumentException if no provider with the given name exists
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public void clearTestProviderStatus(String provider) {
try {
mService.clearTestProviderStatus(provider);
- } catch (RemoteException ex) {
- Log.e(TAG, "clearTestProviderStatus: RemoteException", ex);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException", e);
}
}
@@ -1587,7 +1712,9 @@ public class LocationManager {
* The provider may optionally fill the extras Bundle with results from the command.
*
* @return true if the command succeeds.
+ * @deprecated use the {@link LocationRequest} class instead
*/
+ @Deprecated
public boolean sendExtraCommand(String provider, String command, Bundle extras) {
try {
return mService.sendExtraCommand(provider, command, extras);
@@ -1612,4 +1739,41 @@ public class LocationManager {
}
}
+ private static void checkProvider(String provider) {
+ if (provider == null) {
+ throw new IllegalArgumentException("invalid provider: " + provider);
+ }
+ }
+
+ private static void checkCriteria(Criteria criteria) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("invalid criteria: " + criteria);
+ }
+ }
+ private static void checkListener(LocationListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("invalid listener: " + listener);
+ }
+ }
+
+ private void checkPendingIntent(PendingIntent intent) {
+ if (intent == null) {
+ throw new IllegalArgumentException("invalid pending intent: " + intent);
+ }
+ if (!intent.isTargetedToPackage()) {
+ IllegalArgumentException e = new IllegalArgumentException(
+ "pending intent msut be targeted to package");
+ if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN) {
+ throw e;
+ } else {
+ Log.w(TAG, e);
+ }
+ }
+ }
+
+ private static void checkGeofence(Geofence fence) {
+ if (fence == null) {
+ throw new IllegalArgumentException("invalid geofence: " + fence);
+ }
+ }
}
diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java
index 8c16580..737e17f 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -16,8 +16,8 @@
package android.location;
-import android.os.RemoteException;
-import android.util.Log;
+
+import com.android.internal.location.ProviderProperties;
/**
* An abstract superclass for location providers. A location provider
@@ -32,35 +32,40 @@ import android.util.Log;
* characteristics or monetary costs to the user. The {@link
* Criteria} class allows providers to be selected based on
* user-specified criteria.
+ *
+ * @deprecated Use the {@link Criteria} class to request location instead of
+ * enumerating providers.
*/
-public abstract class LocationProvider {
- private static final String TAG = "LocationProvider";
- // A regular expression matching characters that may not appear
- // in the name of a LocationProvider.
- static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";
-
- private final String mName;
- private final ILocationManager mService;
-
+@Deprecated
+public class LocationProvider {
public static final int OUT_OF_SERVICE = 0;
public static final int TEMPORARILY_UNAVAILABLE = 1;
public static final int AVAILABLE = 2;
/**
+ * A regular expression matching characters that may not appear
+ * in the name of a LocationProvider
+ * @hide
+ */
+ public static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";
+
+ private final String mName;
+ private final ProviderProperties mProperties;
+
+ /**
* Constructs a LocationProvider with the given name. Provider names must
* consist only of the characters [a-zA-Z0-9].
*
* @throws IllegalArgumentException if name contains an illegal character
*
- * {@hide}
+ * @hide
*/
- public LocationProvider(String name, ILocationManager service) {
+ public LocationProvider(String name, ProviderProperties properties) {
if (name.matches(BAD_CHARS_REGEX)) {
- throw new IllegalArgumentException("name " + name +
- " contains an illegal character");
+ throw new IllegalArgumentException("provider name contains illegal character: " + name);
}
mName = name;
- mService = service;
+ mProperties = properties;
}
/**
@@ -75,40 +80,81 @@ public abstract class LocationProvider {
* false otherwise.
*/
public boolean meetsCriteria(Criteria criteria) {
- try {
- return mService.providerMeetsCriteria(mName, criteria);
- } catch (RemoteException e) {
- Log.e(TAG, "meetsCriteria: RemoteException", e);
+ return propertiesMeetCriteria(mName, mProperties, criteria);
+ }
+
+ /**
+ * @hide
+ */
+ public static boolean propertiesMeetCriteria(String name, ProviderProperties properties,
+ Criteria criteria) {
+ if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
+ // passive provider never matches
+ return false;
+ }
+ if (properties == null) {
+ // unfortunately this can happen for provider in remote services
+ // that have not finished binding yet
+ return false;
+ }
+
+ if (criteria.getAccuracy() != Criteria.NO_REQUIREMENT &&
+ criteria.getAccuracy() < properties.mAccuracy) {
return false;
}
+ if (criteria.getPowerRequirement() != Criteria.NO_REQUIREMENT &&
+ criteria.getPowerRequirement() < properties.mPowerRequirement) {
+ return false;
+ }
+ if (criteria.isAltitudeRequired() && !properties.mSupportsAltitude) {
+ return false;
+ }
+ if (criteria.isSpeedRequired() && !properties.mSupportsSpeed) {
+ return false;
+ }
+ if (criteria.isBearingRequired() && !properties.mSupportsBearing) {
+ return false;
+ }
+ if (!criteria.isCostAllowed() && properties.mHasMonetaryCost) {
+ return false;
+ }
+ return true;
}
/**
* Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise.
*/
- public abstract boolean requiresNetwork();
+ public boolean requiresNetwork() {
+ return mProperties.mRequiresNetwork;
+ }
/**
* Returns true if the provider requires access to a
* satellite-based positioning system (e.g., GPS), false
* otherwise.
*/
- public abstract boolean requiresSatellite();
+ public boolean requiresSatellite() {
+ return mProperties.mRequiresSatellite;
+ }
/**
* Returns true if the provider requires access to an appropriate
* cellular network (e.g., to make use of cell tower IDs), false
* otherwise.
*/
- public abstract boolean requiresCell();
+ public boolean requiresCell() {
+ return mProperties.mRequiresCell;
+ }
/**
* Returns true if the use of this provider may result in a
* monetary charge to the user, false if use is free. It is up to
* each provider to give accurate information.
*/
- public abstract boolean hasMonetaryCost();
+ public boolean hasMonetaryCost() {
+ return mProperties.mHasMonetaryCost;
+ }
/**
* Returns true if the provider is able to provide altitude
@@ -116,7 +162,9 @@ public abstract class LocationProvider {
* under most circumstances but may occassionally not report it
* should return true.
*/
- public abstract boolean supportsAltitude();
+ public boolean supportsAltitude() {
+ return mProperties.mSupportsAltitude;
+ }
/**
* Returns true if the provider is able to provide speed
@@ -124,7 +172,9 @@ public abstract class LocationProvider {
* under most circumstances but may occassionally not report it
* should return true.
*/
- public abstract boolean supportsSpeed();
+ public boolean supportsSpeed() {
+ return mProperties.mSupportsSpeed;
+ }
/**
* Returns true if the provider is able to provide bearing
@@ -132,7 +182,9 @@ public abstract class LocationProvider {
* under most circumstances but may occassionally not report it
* should return true.
*/
- public abstract boolean supportsBearing();
+ public boolean supportsBearing() {
+ return mProperties.mSupportsBearing;
+ }
/**
* Returns the power requirement for this provider.
@@ -140,7 +192,9 @@ public abstract class LocationProvider {
* @return the power requirement for this provider, as one of the
* constants Criteria.POWER_REQUIREMENT_*.
*/
- public abstract int getPowerRequirement();
+ public int getPowerRequirement() {
+ return mProperties.mPowerRequirement;
+ }
/**
* Returns a constant describing horizontal accuracy of this provider.
@@ -149,5 +203,7 @@ public abstract class LocationProvider {
* location is only approximate then {@link Criteria#ACCURACY_COARSE}
* is returned.
*/
- public abstract int getAccuracy();
+ public int getAccuracy() {
+ return mProperties.mAccuracy;
+ }
}
diff --git a/location/java/android/location/LocationRequest.aidl b/location/java/android/location/LocationRequest.aidl
new file mode 100644
index 0000000..b1a8647
--- /dev/null
+++ b/location/java/android/location/LocationRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable LocationRequest;
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
new file mode 100644
index 0000000..3110196
--- /dev/null
+++ b/location/java/android/location/LocationRequest.java
@@ -0,0 +1,321 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.util.TimeUtils;
+
+public final class LocationRequest implements Parcelable {
+ // QOS control
+ public static final int ACCURACY_FINE = 100; // ~1 meter
+ public static final int ACCURACY_BLOCK = 102; // ~100 meters
+ public static final int ACCURACY_CITY = 104; // ~10 km
+ public static final int POWER_NONE = 200;
+ public static final int POWER_LOW = 201;
+ public static final int POWER_HIGH = 203;
+
+ private int mQuality = POWER_LOW;
+ private long mFastestInterval = 6 * 1000; // 6 seconds
+ private long mInterval = 60 * 1000; // 1 minute
+ private long mExpireAt = Long.MAX_VALUE; // no expiry
+ private int mNumUpdates = Integer.MAX_VALUE; // no expiry
+ private float mSmallestDisplacement = 0.0f; // meters
+
+ private String mProvider = null; // for deprecated API's that explicitly request a provider
+
+ public static LocationRequest create() {
+ LocationRequest request = new LocationRequest();
+ return request;
+ }
+
+ /** @hide */
+ public static LocationRequest createFromDeprecatedProvider(String provider, long minTime,
+ float minDistance, boolean singleShot) {
+ 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 */
+ public static LocationRequest createFromDeprecatedCriteria(Criteria criteria, long minTime,
+ float minDistance, boolean singleShot) {
+ 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: {
+ switch (criteria.getPowerRequirement()) {
+ case Criteria.POWER_HIGH:
+ quality = POWER_HIGH;
+ default:
+ 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() { }
+
+ public LocationRequest setQuality(int quality) {
+ checkQuality(quality);
+ mQuality = quality;
+ return this;
+ }
+
+ public int getQuality() {
+ return mQuality;
+ }
+
+ public LocationRequest setInterval(long millis) {
+ checkInterval(millis);
+ mInterval = millis;
+ return this;
+ }
+
+ public long getInterval() {
+ return mInterval;
+ }
+
+ public LocationRequest setFastestInterval(long millis) {
+ checkInterval(millis);
+ mFastestInterval = millis;
+ return this;
+ }
+
+ public long getFastestInterval() {
+ return mFastestInterval;
+ }
+
+ public LocationRequest setExpireIn(long millis) {
+ mExpireAt = millis + SystemClock.elapsedRealtime();
+ if (mExpireAt < 0) mExpireAt = 0;
+ return this;
+ }
+
+ public LocationRequest setExpireAt(long millis) {
+ mExpireAt = millis;
+ if (mExpireAt < 0) mExpireAt = 0;
+ return this;
+ }
+
+ public long getExpireAt() {
+ return mExpireAt;
+ }
+
+ public int getNumUpdates() {
+ return mNumUpdates;
+ }
+
+ /** @hide */
+ public void decrementNumUpdates() {
+ if (mNumUpdates != Integer.MAX_VALUE) {
+ mNumUpdates--;
+ }
+ if (mNumUpdates < 0) {
+ mNumUpdates = 0;
+ }
+ }
+
+ public LocationRequest setNumUpdates(int numUpdates) {
+ if (numUpdates < 0) throw new IllegalArgumentException("invalid numUpdates: " + numUpdates);
+ mNumUpdates = numUpdates;
+ return this;
+ }
+
+ /** @hide */
+ public LocationRequest setProvider(String provider) {
+ checkProvider(provider);
+ mProvider = provider;
+ return this;
+ }
+
+ /** @hide */
+ public String getProvider() {
+ return mProvider;
+ }
+
+ /** @hide */
+ public LocationRequest setSmallestDisplacement(float meters) {
+ checkDisplacement(meters);
+ mSmallestDisplacement = meters;
+ return this;
+ }
+
+ /** @hide */
+ public float getSmallestDisplacement() {
+ return mSmallestDisplacement;
+ }
+
+ /** @hide */
+ public LocationRequest applyCoarsePermissionRestrictions() {
+ switch (mQuality) {
+ case ACCURACY_FINE:
+ mQuality = ACCURACY_BLOCK;
+ break;
+ }
+ // cap fastest interval to 6 seconds
+ if (mFastestInterval < 6 * 1000) mFastestInterval = 6 * 1000;
+ // cap requested interval to 1 minute
+ if (mInterval < 60 * 1000) mInterval = 60 * 1000;
+ return this;
+ }
+
+ private static void checkInterval(long millis) {
+ if (millis < 0) {
+ throw new IllegalArgumentException("invalid interval: " + millis);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ private static void checkDisplacement(float meters) {
+ if (meters < 0.0f) {
+ throw new IllegalArgumentException("invalid displacement: " + meters);
+ }
+ }
+
+ private static void checkProvider(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("invalid provider: " + name);
+ }
+ }
+
+ public static final Parcelable.Creator<LocationRequest> CREATOR =
+ new Parcelable.Creator<LocationRequest>() {
+ @Override
+ public LocationRequest createFromParcel(Parcel in) {
+ LocationRequest request = new LocationRequest();
+ request.setQuality(in.readInt());
+ request.setFastestInterval(in.readLong());
+ request.setInterval(in.readLong());
+ request.setExpireAt(in.readLong());
+ request.setNumUpdates(in.readInt());
+ request.setSmallestDisplacement(in.readFloat());
+ String provider = in.readString();
+ if (provider != null) request.setProvider(provider);
+ return request;
+ }
+ @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.writeInt(mQuality);
+ parcel.writeLong(mFastestInterval);
+ parcel.writeLong(mInterval);
+ parcel.writeLong(mExpireAt);
+ parcel.writeInt(mNumUpdates);
+ parcel.writeFloat(mSmallestDisplacement);
+ parcel.writeString(mProvider);
+ }
+
+ /** @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 "???";
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("Request[").append(qualityToString(mQuality));
+ if (mProvider != null) s.append(' ').append(mProvider);
+ if (mQuality != POWER_NONE) {
+ s.append(" requested=");
+ TimeUtils.formatDuration(mInterval, s);
+ }
+ s.append(" fastest=");
+ TimeUtils.formatDuration(mFastestInterval, s);
+ if (mExpireAt != Long.MAX_VALUE) {
+ long expireIn = mExpireAt - SystemClock.elapsedRealtime();
+ s.append(" expireIn=");
+ TimeUtils.formatDuration(expireIn, s);
+ }
+ if (mNumUpdates != Integer.MAX_VALUE){
+ s.append(" num=").append(mNumUpdates);
+ }
+ s.append(']');
+ return s.toString();
+ }
+}
diff --git a/location/java/com/android/internal/location/DummyLocationProvider.java b/location/java/com/android/internal/location/DummyLocationProvider.java
deleted file mode 100644
index 3122960..0000000
--- a/location/java/com/android/internal/location/DummyLocationProvider.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.internal.location;
-
-import android.location.ILocationManager;
-import android.location.LocationProvider;
-
-/**
- * A stub implementation of LocationProvider used by LocationManager.
- * A DummyLocationProvider may be queried to determine the properties
- * of the provider whcih it shadows, but does not actually provide location
- * data.
- *
- * {@hide}
- */
-public class DummyLocationProvider extends LocationProvider {
-
- private static final String TAG = "DummyLocationProvider";
-
- String mName;
- boolean mRequiresNetwork;
- boolean mRequiresSatellite;
- boolean mRequiresCell;
- boolean mHasMonetaryCost;
- boolean mSupportsAltitude;
- boolean mSupportsSpeed;
- boolean mSupportsBearing;
- int mPowerRequirement;
- int mAccuracy;
-
- public DummyLocationProvider(String name, ILocationManager service) {
- super(name, service);
- }
-
- public void setRequiresNetwork(boolean requiresNetwork) {
- mRequiresNetwork = requiresNetwork;
- }
-
- public void setRequiresSatellite(boolean requiresSatellite) {
- mRequiresSatellite = requiresSatellite;
- }
-
- public void setRequiresCell(boolean requiresCell) {
- mRequiresCell = requiresCell;
- }
-
- public void setHasMonetaryCost(boolean hasMonetaryCost) {
- mHasMonetaryCost = hasMonetaryCost;
- }
-
- public void setSupportsAltitude(boolean supportsAltitude) {
- mSupportsAltitude = supportsAltitude;
- }
-
- public void setSupportsSpeed(boolean supportsSpeed) {
- mSupportsSpeed = supportsSpeed;
- }
-
- public void setSupportsBearing(boolean supportsBearing) {
- mSupportsBearing = supportsBearing;
- }
-
- public void setPowerRequirement(int powerRequirement) {
- mPowerRequirement = powerRequirement;
- }
-
- public void setAccuracy(int accuracy) {
- mAccuracy = accuracy;
- }
-
- /**
- * Returns true if the provider requires access to a
- * data network (e.g., the Internet), false otherwise.
- */
- @Override
- public boolean requiresNetwork() {
- return mRequiresNetwork;
- }
-
- /**
- * Returns true if the provider requires access to a
- * satellite-based positioning system (e.g., GPS), false
- * otherwise.
- */
- @Override
- public boolean requiresSatellite() {
- return mRequiresSatellite;
- }
-
- /**
- * Returns true if the provider requires access to an appropriate
- * cellular network (e.g., to make use of cell tower IDs), false
- * otherwise.
- */
- @Override
- public boolean requiresCell() {
- return mRequiresCell;
- }
-
- /**
- * Returns true if the use of this provider may result in a
- * monetary charge to the user, false if use is free. It is up to
- * each provider to give accurate information.
- */
- @Override
- public boolean hasMonetaryCost() {
- return mHasMonetaryCost;
- }
-
- /**
- * Returns true if the provider is able to provide altitude
- * information, false otherwise. A provider that reports altitude
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- @Override
- public boolean supportsAltitude() {
- return mSupportsAltitude;
- }
-
- /**
- * Returns true if the provider is able to provide speed
- * information, false otherwise. A provider that reports speed
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- @Override
- public boolean supportsSpeed() {
- return mSupportsSpeed;
- }
-
- /**
- * Returns true if the provider is able to provide bearing
- * information, false otherwise. A provider that reports bearing
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- @Override
- public boolean supportsBearing() {
- return mSupportsBearing;
- }
-
- /**
- * Returns the power requirement for this provider.
- *
- * @return the power requirement for this provider, as one of the
- * constants Criteria.POWER_REQUIREMENT_*.
- */
- @Override
- public int getPowerRequirement() {
- return mPowerRequirement;
- }
-
- /**
- * Returns a constant describing the horizontal accuracy returned
- * by this provider.
- *
- * @return the horizontal accuracy for this provider, as one of the
- * constants Criteria.ACCURACY_*.
- */
- @Override
- public int getAccuracy() {
- return mAccuracy;
- }
-}
-
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/com/android/internal/location/ILocationProvider.aidl
index ecf6789..39c2d92 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/com/android/internal/location/ILocationProvider.aidl
@@ -14,40 +14,31 @@
* limitations under the License.
*/
-package android.location;
+package com.android.internal.location;
-import android.location.Criteria;
import android.location.Location;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.WorkSource;
+import com.android.internal.location.ProviderProperties;
+import com.android.internal.location.ProviderRequest;
+
/**
* Binder interface for services that implement location providers.
- *
- * {@hide}
+ * <p>Use {@link LocationProviderBase} as a helper to implement this
+ * interface.
+ * @hide
*/
interface ILocationProvider {
- boolean requiresNetwork();
- boolean requiresSatellite();
- boolean requiresCell();
- boolean hasMonetaryCost();
- boolean supportsAltitude();
- boolean supportsSpeed();
- boolean supportsBearing();
- int getPowerRequirement();
- boolean meetsCriteria(in Criteria criteria);
- int getAccuracy();
void enable();
void disable();
+
+ void setRequest(in ProviderRequest request, in WorkSource ws);
+
+ // --- deprecated (but still supported) ---
+ ProviderProperties getProperties();
int getStatus(out Bundle extras);
long getStatusUpdateTime();
- String getInternalState();
- void enableLocationTracking(boolean enable);
- void setMinTime(long minTime, in WorkSource ws);
- void updateNetworkState(int state, in NetworkInfo info);
- void updateLocation(in Location location);
boolean sendExtraCommand(String command, inout Bundle extras);
- void addListener(int uid);
- void removeListener(int uid);
}
diff --git a/location/java/com/android/internal/location/ProviderProperties.aidl b/location/java/com/android/internal/location/ProviderProperties.aidl
new file mode 100644
index 0000000..b901444
--- /dev/null
+++ b/location/java/com/android/internal/location/ProviderProperties.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 com.android.internal.location;
+
+parcelable ProviderProperties;
diff --git a/location/java/com/android/internal/location/ProviderProperties.java b/location/java/com/android/internal/location/ProviderProperties.java
new file mode 100644
index 0000000..08aed80
--- /dev/null
+++ b/location/java/com/android/internal/location/ProviderProperties.java
@@ -0,0 +1,152 @@
+/*
+ * 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 com.android.internal.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A Parcelable containing (legacy) location provider properties.
+ * This object is just used inside the framework and system services.
+ * @hide
+ */
+public final class ProviderProperties implements Parcelable {
+ /**
+ * True if provider requires access to a
+ * data network (e.g., the Internet), false otherwise.
+ */
+ public final boolean mRequiresNetwork;
+
+ /**
+ * True if the provider requires access to a
+ * satellite-based positioning system (e.g., GPS), false
+ * otherwise.
+ */
+ public final boolean mRequiresSatellite;
+
+ /**
+ * True if the provider requires access to an appropriate
+ * cellular network (e.g., to make use of cell tower IDs), false
+ * otherwise.
+ */
+ public final boolean mRequiresCell;
+
+ /**
+ * True if the use of this provider may result in a
+ * monetary charge to the user, false if use is free. It is up to
+ * each provider to give accurate information. Cell (network) usage
+ * is not considered monetary cost.
+ */
+ public final boolean mHasMonetaryCost;
+
+ /**
+ * True if the provider is able to provide altitude
+ * information, false otherwise. A provider that reports altitude
+ * under most circumstances but may occasionally not report it
+ * should return true.
+ */
+ public final boolean mSupportsAltitude;
+
+ /**
+ * True if the provider is able to provide speed
+ * information, false otherwise. A provider that reports speed
+ * under most circumstances but may occasionally not report it
+ * should return true.
+ */
+ public final boolean mSupportsSpeed;
+
+ /**
+ * True if the provider is able to provide bearing
+ * information, false otherwise. A provider that reports bearing
+ * under most circumstances but may occasionally not report it
+ * should return true.
+ */
+ public final boolean mSupportsBearing;
+
+ /**
+ * Power requirement for this provider.
+ *
+ * @return the power requirement for this provider, as one of the
+ * constants Criteria.POWER_*.
+ */
+ public final int mPowerRequirement;
+
+ /**
+ * Constant describing the horizontal accuracy returned
+ * by this provider.
+ *
+ * @return the horizontal accuracy for this provider, as one of the
+ * constants Criteria.ACCURACY_COARSE or Criteria.ACCURACY_FINE
+ */
+ public final int mAccuracy;
+
+ public ProviderProperties(boolean mRequiresNetwork,
+ boolean mRequiresSatellite, boolean mRequiresCell, boolean mHasMonetaryCost,
+ boolean mSupportsAltitude, boolean mSupportsSpeed, boolean mSupportsBearing,
+ int mPowerRequirement, int mAccuracy) {
+ this.mRequiresNetwork = mRequiresNetwork;
+ this.mRequiresSatellite = mRequiresSatellite;
+ this.mRequiresCell = mRequiresCell;
+ this.mHasMonetaryCost = mHasMonetaryCost;
+ this.mSupportsAltitude = mSupportsAltitude;
+ this.mSupportsSpeed = mSupportsSpeed;
+ this.mSupportsBearing = mSupportsBearing;
+ this.mPowerRequirement = mPowerRequirement;
+ this.mAccuracy = mAccuracy;
+ }
+
+ public static final Parcelable.Creator<ProviderProperties> CREATOR =
+ new Parcelable.Creator<ProviderProperties>() {
+ @Override
+ public ProviderProperties createFromParcel(Parcel in) {
+ boolean requiresNetwork = in.readInt() == 1;
+ boolean requiresSatellite = in.readInt() == 1;
+ boolean requiresCell = in.readInt() == 1;
+ boolean hasMonetaryCost = in.readInt() == 1;
+ boolean supportsAltitude = in.readInt() == 1;
+ boolean supportsSpeed = in.readInt() == 1;
+ boolean supportsBearing = in.readInt() == 1;
+ int powerRequirement = in.readInt();
+ int accuracy = in.readInt();
+ return new ProviderProperties(requiresNetwork, requiresSatellite,
+ requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed, supportsBearing,
+ powerRequirement, accuracy);
+ }
+ @Override
+ public ProviderProperties[] newArray(int size) {
+ return new ProviderProperties[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mRequiresNetwork ? 1 : 0);
+ parcel.writeInt(mRequiresSatellite ? 1 : 0);
+ parcel.writeInt(mRequiresCell ? 1 : 0);
+ parcel.writeInt(mHasMonetaryCost ? 1 : 0);
+ parcel.writeInt(mSupportsAltitude ? 1 : 0);
+ parcel.writeInt(mSupportsSpeed ? 1 : 0);
+ parcel.writeInt(mSupportsSpeed ? 1 : 0);
+ parcel.writeInt(mPowerRequirement);
+ parcel.writeInt(mAccuracy);
+ }
+}
diff --git a/location/java/com/android/internal/location/ProviderRequest.aidl b/location/java/com/android/internal/location/ProviderRequest.aidl
new file mode 100644
index 0000000..4e1ea95
--- /dev/null
+++ b/location/java/com/android/internal/location/ProviderRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 com.android.internal.location;
+
+parcelable ProviderRequest;
diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/com/android/internal/location/ProviderRequest.java
new file mode 100644
index 0000000..25c51f5
--- /dev/null
+++ b/location/java/com/android/internal/location/ProviderRequest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.android.internal.location;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.location.LocationRequest;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.TimeUtils;
+
+/** @hide */
+public final class ProviderRequest implements Parcelable {
+ /** Location reporting is requested (true) */
+ public boolean reportLocation = false;
+
+ /** The smallest requested interval */
+ public long interval = Long.MAX_VALUE;
+
+ /**
+ * A more detailed set of requests.
+ * <p>Location Providers can optionally use this to
+ * fine tune location updates, for example when there
+ * is a high power slow interval request and a
+ * low power fast interval request.
+ */
+ public List<LocationRequest> locationRequests = null;
+
+ public ProviderRequest() {
+ }
+
+ public static final Parcelable.Creator<ProviderRequest> CREATOR =
+ new Parcelable.Creator<ProviderRequest>() {
+ @Override
+ public ProviderRequest createFromParcel(Parcel in) {
+ ProviderRequest request = new ProviderRequest();
+ request.reportLocation = in.readInt() == 1;
+ request.interval = in.readLong();
+ int count = in.readInt();
+ request.locationRequests = new ArrayList<LocationRequest>(count);
+ for (int i = 0; i < count; i++) {
+ request.locationRequests.add(LocationRequest.CREATOR.createFromParcel(in));
+ }
+ return request;
+ }
+ @Override
+ public ProviderRequest[] newArray(int size) {
+ return new ProviderRequest[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(reportLocation ? 1 : 0);
+ parcel.writeLong(interval);
+ parcel.writeParcelableArray(locationRequests.toArray(
+ new LocationRequest[locationRequests.size()]), 0);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("ProviderRequest[");
+ if (reportLocation) {
+ s.append("ON");
+ s.append(" interval=");
+ TimeUtils.formatDuration(interval, s);
+ } else {
+ s.append("OFF");
+ }
+ s.append(']');
+ return s.toString();
+ }
+}