LocationRequest.java revision 6fa9ad4afcd762aea519ff61811386c23d18ddb2
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.location; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.os.SystemClock; 22import android.util.TimeUtils; 23 24public final class LocationRequest implements Parcelable { 25 // QOS control 26 public static final int ACCURACY_FINE = 100; // ~1 meter 27 public static final int ACCURACY_BLOCK = 102; // ~100 meters 28 public static final int ACCURACY_CITY = 104; // ~10 km 29 public static final int POWER_NONE = 200; 30 public static final int POWER_LOW = 201; 31 public static final int POWER_HIGH = 203; 32 33 private int mQuality = POWER_LOW; 34 private long mFastestInterval = 6 * 1000; // 6 seconds 35 private long mInterval = 60 * 1000; // 1 minute 36 private long mExpireAt = Long.MAX_VALUE; // no expiry 37 private int mNumUpdates = Integer.MAX_VALUE; // no expiry 38 private float mSmallestDisplacement = 0.0f; // meters 39 40 private String mProvider = null; // for deprecated API's that explicitly request a provider 41 42 public static LocationRequest create() { 43 LocationRequest request = new LocationRequest(); 44 return request; 45 } 46 47 /** @hide */ 48 public static LocationRequest createFromDeprecatedProvider(String provider, long minTime, 49 float minDistance, boolean singleShot) { 50 if (minTime < 0) minTime = 0; 51 if (minDistance < 0) minDistance = 0; 52 53 int quality; 54 if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { 55 quality = POWER_NONE; 56 } else if (LocationManager.GPS_PROVIDER.equals(provider)) { 57 quality = ACCURACY_FINE; 58 } else { 59 quality = POWER_LOW; 60 } 61 62 LocationRequest request = new LocationRequest() 63 .setProvider(provider) 64 .setQuality(quality) 65 .setInterval(minTime) 66 .setFastestInterval(minTime) 67 .setSmallestDisplacement(minDistance); 68 if (singleShot) request.setNumUpdates(1); 69 return request; 70 } 71 72 /** @hide */ 73 public static LocationRequest createFromDeprecatedCriteria(Criteria criteria, long minTime, 74 float minDistance, boolean singleShot) { 75 if (minTime < 0) minTime = 0; 76 if (minDistance < 0) minDistance = 0; 77 78 int quality; 79 switch (criteria.getAccuracy()) { 80 case Criteria.ACCURACY_COARSE: 81 quality = ACCURACY_BLOCK; 82 break; 83 case Criteria.ACCURACY_FINE: 84 quality = ACCURACY_FINE; 85 break; 86 default: { 87 switch (criteria.getPowerRequirement()) { 88 case Criteria.POWER_HIGH: 89 quality = POWER_HIGH; 90 default: 91 quality = POWER_LOW; 92 } 93 } 94 } 95 96 LocationRequest request = new LocationRequest() 97 .setQuality(quality) 98 .setInterval(minTime) 99 .setFastestInterval(minTime) 100 .setSmallestDisplacement(minDistance); 101 if (singleShot) request.setNumUpdates(1); 102 return request; 103 } 104 105 /** @hide */ 106 public LocationRequest() { } 107 108 public LocationRequest setQuality(int quality) { 109 checkQuality(quality); 110 mQuality = quality; 111 return this; 112 } 113 114 public int getQuality() { 115 return mQuality; 116 } 117 118 public LocationRequest setInterval(long millis) { 119 checkInterval(millis); 120 mInterval = millis; 121 return this; 122 } 123 124 public long getInterval() { 125 return mInterval; 126 } 127 128 public LocationRequest setFastestInterval(long millis) { 129 checkInterval(millis); 130 mFastestInterval = millis; 131 return this; 132 } 133 134 public long getFastestInterval() { 135 return mFastestInterval; 136 } 137 138 public LocationRequest setExpireIn(long millis) { 139 mExpireAt = millis + SystemClock.elapsedRealtime(); 140 if (mExpireAt < 0) mExpireAt = 0; 141 return this; 142 } 143 144 public LocationRequest setExpireAt(long millis) { 145 mExpireAt = millis; 146 if (mExpireAt < 0) mExpireAt = 0; 147 return this; 148 } 149 150 public long getExpireAt() { 151 return mExpireAt; 152 } 153 154 public int getNumUpdates() { 155 return mNumUpdates; 156 } 157 158 /** @hide */ 159 public void decrementNumUpdates() { 160 if (mNumUpdates != Integer.MAX_VALUE) { 161 mNumUpdates--; 162 } 163 if (mNumUpdates < 0) { 164 mNumUpdates = 0; 165 } 166 } 167 168 public LocationRequest setNumUpdates(int numUpdates) { 169 if (numUpdates < 0) throw new IllegalArgumentException("invalid numUpdates: " + numUpdates); 170 mNumUpdates = numUpdates; 171 return this; 172 } 173 174 /** @hide */ 175 public LocationRequest setProvider(String provider) { 176 checkProvider(provider); 177 mProvider = provider; 178 return this; 179 } 180 181 /** @hide */ 182 public String getProvider() { 183 return mProvider; 184 } 185 186 /** @hide */ 187 public LocationRequest setSmallestDisplacement(float meters) { 188 checkDisplacement(meters); 189 mSmallestDisplacement = meters; 190 return this; 191 } 192 193 /** @hide */ 194 public float getSmallestDisplacement() { 195 return mSmallestDisplacement; 196 } 197 198 /** @hide */ 199 public LocationRequest applyCoarsePermissionRestrictions() { 200 switch (mQuality) { 201 case ACCURACY_FINE: 202 mQuality = ACCURACY_BLOCK; 203 break; 204 } 205 // cap fastest interval to 6 seconds 206 if (mFastestInterval < 6 * 1000) mFastestInterval = 6 * 1000; 207 // cap requested interval to 1 minute 208 if (mInterval < 60 * 1000) mInterval = 60 * 1000; 209 return this; 210 } 211 212 private static void checkInterval(long millis) { 213 if (millis < 0) { 214 throw new IllegalArgumentException("invalid interval: " + millis); 215 } 216 } 217 218 private static void checkQuality(int quality) { 219 switch (quality) { 220 case ACCURACY_FINE: 221 case ACCURACY_BLOCK: 222 case ACCURACY_CITY: 223 case POWER_NONE: 224 case POWER_LOW: 225 case POWER_HIGH: 226 break; 227 default: 228 throw new IllegalArgumentException("invalid quality: " + quality); 229 } 230 } 231 232 private static void checkDisplacement(float meters) { 233 if (meters < 0.0f) { 234 throw new IllegalArgumentException("invalid displacement: " + meters); 235 } 236 } 237 238 private static void checkProvider(String name) { 239 if (name == null) { 240 throw new IllegalArgumentException("invalid provider: " + name); 241 } 242 } 243 244 public static final Parcelable.Creator<LocationRequest> CREATOR = 245 new Parcelable.Creator<LocationRequest>() { 246 @Override 247 public LocationRequest createFromParcel(Parcel in) { 248 LocationRequest request = new LocationRequest(); 249 request.setQuality(in.readInt()); 250 request.setFastestInterval(in.readLong()); 251 request.setInterval(in.readLong()); 252 request.setExpireAt(in.readLong()); 253 request.setNumUpdates(in.readInt()); 254 request.setSmallestDisplacement(in.readFloat()); 255 String provider = in.readString(); 256 if (provider != null) request.setProvider(provider); 257 return request; 258 } 259 @Override 260 public LocationRequest[] newArray(int size) { 261 return new LocationRequest[size]; 262 } 263 }; 264 @Override 265 public int describeContents() { 266 return 0; 267 } 268 @Override 269 public void writeToParcel(Parcel parcel, int flags) { 270 parcel.writeInt(mQuality); 271 parcel.writeLong(mFastestInterval); 272 parcel.writeLong(mInterval); 273 parcel.writeLong(mExpireAt); 274 parcel.writeInt(mNumUpdates); 275 parcel.writeFloat(mSmallestDisplacement); 276 parcel.writeString(mProvider); 277 } 278 279 /** @hide */ 280 public static String qualityToString(int quality) { 281 switch (quality) { 282 case ACCURACY_FINE: 283 return "ACCURACY_FINE"; 284 case ACCURACY_BLOCK: 285 return "ACCURACY_BLOCK"; 286 case ACCURACY_CITY: 287 return "ACCURACY_CITY"; 288 case POWER_NONE: 289 return "POWER_NONE"; 290 case POWER_LOW: 291 return "POWER_LOW"; 292 case POWER_HIGH: 293 return "POWER_HIGH"; 294 default: 295 return "???"; 296 } 297 } 298 299 @Override 300 public String toString() { 301 StringBuilder s = new StringBuilder(); 302 s.append("Request[").append(qualityToString(mQuality)); 303 if (mProvider != null) s.append(' ').append(mProvider); 304 if (mQuality != POWER_NONE) { 305 s.append(" requested="); 306 TimeUtils.formatDuration(mInterval, s); 307 } 308 s.append(" fastest="); 309 TimeUtils.formatDuration(mFastestInterval, s); 310 if (mExpireAt != Long.MAX_VALUE) { 311 long expireIn = mExpireAt - SystemClock.elapsedRealtime(); 312 s.append(" expireIn="); 313 TimeUtils.formatDuration(expireIn, s); 314 } 315 if (mNumUpdates != Integer.MAX_VALUE){ 316 s.append(" num=").append(mNumUpdates); 317 } 318 s.append(']'); 319 return s.toString(); 320 } 321} 322