1 /*
2  * Copyright (C) 2007 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 
17 package android.location;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 /**
23  * A class indicating the application criteria for selecting a
24  * location provider. Providers may be ordered according to accuracy,
25  * power usage, ability to report altitude, speed, bearing, and monetary
26  * cost.
27  */
28 public class Criteria implements Parcelable {
29     /**
30      * A constant indicating that the application does not choose to
31      * place requirement on a particular feature.
32      */
33     public static final int NO_REQUIREMENT = 0;
34 
35     /**
36      * A constant indicating a low power requirement.
37      */
38     public static final int POWER_LOW = 1;
39 
40     /**
41      * A constant indicating a medium power requirement.
42      */
43     public static final int POWER_MEDIUM = 2;
44 
45     /**
46      * A constant indicating a high power requirement.
47      */
48     public static final int POWER_HIGH = 3;
49 
50     /**
51      * A constant indicating a finer location accuracy requirement
52      */
53     public static final int ACCURACY_FINE = 1;
54 
55     /**
56      * A constant indicating an approximate accuracy requirement
57      */
58     public static final int ACCURACY_COARSE = 2;
59 
60     /**
61      * A constant indicating a low location accuracy requirement
62      * - may be used for horizontal, altitude, speed or bearing accuracy.
63      * For horizontal and vertical position this corresponds roughly to
64      * an accuracy of greater than 500 meters.
65      */
66     public static final int ACCURACY_LOW = 1;
67 
68     /**
69      * A constant indicating a medium accuracy requirement
70      * - currently used only for horizontal accuracy.
71      * For horizontal position this corresponds roughly to to an accuracy
72      * of between 100 and 500 meters.
73      */
74     public static final int ACCURACY_MEDIUM = 2;
75 
76     /**
77      * a constant indicating a high accuracy requirement
78      * - may be used for horizontal, altitude, speed or bearing accuracy.
79      * For horizontal and vertical position this corresponds roughly to
80      * an accuracy of less than 100 meters.
81      */
82     public static final int ACCURACY_HIGH = 3;
83 
84     private int mHorizontalAccuracy    = NO_REQUIREMENT;
85     private int mVerticalAccuracy      = NO_REQUIREMENT;
86     private int mSpeedAccuracy         = NO_REQUIREMENT;
87     private int mBearingAccuracy       = NO_REQUIREMENT;
88     private int mPowerRequirement      = NO_REQUIREMENT;
89     private boolean mAltitudeRequired  = false;
90     private boolean mBearingRequired   = false;
91     private boolean mSpeedRequired     = false;
92     private boolean mCostAllowed       = false;
93 
94     /**
95      * Constructs a new Criteria object.  The new object will have no
96      * requirements on accuracy, power, or response time; will not
97      * require altitude, speed, or bearing; and will not allow monetary
98      * cost.
99      */
Criteria()100     public Criteria() {}
101 
102     /**
103      * Constructs a new Criteria object that is a copy of the given criteria.
104      */
Criteria(Criteria criteria)105     public Criteria(Criteria criteria) {
106         mHorizontalAccuracy = criteria.mHorizontalAccuracy;
107         mVerticalAccuracy = criteria.mVerticalAccuracy;
108         mSpeedAccuracy = criteria.mSpeedAccuracy;
109         mBearingAccuracy = criteria.mBearingAccuracy;
110         mPowerRequirement = criteria.mPowerRequirement;
111         mAltitudeRequired = criteria.mAltitudeRequired;
112         mBearingRequired = criteria.mBearingRequired;
113         mSpeedRequired = criteria.mSpeedRequired;
114         mCostAllowed = criteria.mCostAllowed;
115     }
116 
117     /**
118      * Indicates the desired horizontal accuracy (latitude and longitude).
119      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
120      * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
121      * More accurate location may consume more power and may take longer.
122      *
123      * @throws IllegalArgumentException if accuracy is not one of the supported constants
124      */
setHorizontalAccuracy(int accuracy)125     public void setHorizontalAccuracy(int accuracy) {
126         if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
127             throw new IllegalArgumentException("accuracy=" + accuracy);
128         }
129         mHorizontalAccuracy = accuracy;
130     }
131 
132     /**
133      * Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
134      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
135      * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
136      */
getHorizontalAccuracy()137     public int getHorizontalAccuracy() {
138         return mHorizontalAccuracy;
139     }
140 
141     /**
142      * Indicates the desired vertical accuracy (altitude).
143      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
144      * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
145      * More accurate location may consume more power and may take longer.
146      *
147      * @throws IllegalArgumentException if accuracy is not one of the supported constants
148      */
setVerticalAccuracy(int accuracy)149     public void setVerticalAccuracy(int accuracy) {
150         if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
151             throw new IllegalArgumentException("accuracy=" + accuracy);
152         }
153         mVerticalAccuracy = accuracy;
154     }
155 
156     /**
157      * Returns a constant indicating the desired vertical accuracy (altitude).
158      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
159      * or {@link #NO_REQUIREMENT}.
160      */
getVerticalAccuracy()161     public int getVerticalAccuracy() {
162         return mVerticalAccuracy;
163     }
164 
165     /**
166      * Indicates the desired speed accuracy.
167      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
168      * or {@link #NO_REQUIREMENT}.
169      * More accurate location may consume more power and may take longer.
170      *
171      * @throws IllegalArgumentException if accuracy is not one of the supported constants
172      */
setSpeedAccuracy(int accuracy)173     public void setSpeedAccuracy(int accuracy) {
174         if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
175             throw new IllegalArgumentException("accuracy=" + accuracy);
176         }
177         mSpeedAccuracy = accuracy;
178     }
179 
180     /**
181      * Returns a constant indicating the desired speed accuracy
182      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
183      * or {@link #NO_REQUIREMENT}.
184      */
getSpeedAccuracy()185     public int getSpeedAccuracy() {
186         return mSpeedAccuracy;
187     }
188 
189     /**
190      * Indicates the desired bearing accuracy.
191      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
192      * or {@link #NO_REQUIREMENT}.
193      * More accurate location may consume more power and may take longer.
194      *
195      * @throws IllegalArgumentException if accuracy is not one of the supported constants
196      */
setBearingAccuracy(int accuracy)197     public void setBearingAccuracy(int accuracy) {
198         if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
199             throw new IllegalArgumentException("accuracy=" + accuracy);
200         }
201         mBearingAccuracy = accuracy;
202     }
203 
204     /**
205      * Returns a constant indicating the desired bearing accuracy.
206      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
207      * or {@link #NO_REQUIREMENT}.
208      */
getBearingAccuracy()209     public int getBearingAccuracy() {
210         return mBearingAccuracy;
211     }
212 
213     /**
214      * Indicates the desired accuracy for latitude and longitude. Accuracy
215      * may be {@link #ACCURACY_FINE} if desired location
216      * is fine, else it can be {@link #ACCURACY_COARSE}.
217      * More accurate location may consume more power and may take longer.
218      *
219      * @throws IllegalArgumentException if accuracy is not one of the supported constants
220      */
setAccuracy(int accuracy)221     public void setAccuracy(int accuracy) {
222         if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_COARSE) {
223             throw new IllegalArgumentException("accuracy=" + accuracy);
224         }
225         if (accuracy == ACCURACY_FINE) {
226             mHorizontalAccuracy = ACCURACY_HIGH;
227         } else {
228             mHorizontalAccuracy = ACCURACY_LOW;
229         }
230     }
231 
232     /**
233      * Returns a constant indicating desired accuracy of location
234      * Accuracy may be {@link #ACCURACY_FINE} if desired location
235      * is fine, else it can be {@link #ACCURACY_COARSE}.
236      */
getAccuracy()237     public int getAccuracy() {
238         if (mHorizontalAccuracy >= ACCURACY_HIGH) {
239             return ACCURACY_FINE;
240         } else {
241             return ACCURACY_COARSE;
242         }
243     }
244 
245     /**
246      * Indicates the desired maximum power level.  The level parameter
247      * must be one of NO_REQUIREMENT, POWER_LOW, POWER_MEDIUM, or
248      * POWER_HIGH.
249      */
setPowerRequirement(int level)250     public void setPowerRequirement(int level) {
251         if (level < NO_REQUIREMENT || level > POWER_HIGH) {
252             throw new IllegalArgumentException("level=" + level);
253         }
254         mPowerRequirement = level;
255     }
256 
257     /**
258      * Returns a constant indicating the desired power requirement.  The
259      * returned
260      */
getPowerRequirement()261     public int getPowerRequirement() {
262         return mPowerRequirement;
263     }
264 
265     /**
266      * Indicates whether the provider is allowed to incur monetary cost.
267      */
setCostAllowed(boolean costAllowed)268     public void setCostAllowed(boolean costAllowed) {
269         mCostAllowed = costAllowed;
270     }
271 
272     /**
273      * Returns whether the provider is allowed to incur monetary cost.
274      */
isCostAllowed()275     public boolean isCostAllowed() {
276         return mCostAllowed;
277     }
278 
279     /**
280      * Indicates whether the provider must provide altitude information.
281      * Not all fixes are guaranteed to contain such information.
282      */
setAltitudeRequired(boolean altitudeRequired)283     public void setAltitudeRequired(boolean altitudeRequired) {
284         mAltitudeRequired = altitudeRequired;
285     }
286 
287     /**
288      * Returns whether the provider must provide altitude information.
289      * Not all fixes are guaranteed to contain such information.
290      */
isAltitudeRequired()291     public boolean isAltitudeRequired() {
292         return mAltitudeRequired;
293     }
294 
295     /**
296      * Indicates whether the provider must provide speed information.
297      * Not all fixes are guaranteed to contain such information.
298      */
setSpeedRequired(boolean speedRequired)299     public void setSpeedRequired(boolean speedRequired) {
300         mSpeedRequired = speedRequired;
301     }
302 
303     /**
304      * Returns whether the provider must provide speed information.
305      * Not all fixes are guaranteed to contain such information.
306      */
isSpeedRequired()307     public boolean isSpeedRequired() {
308         return mSpeedRequired;
309     }
310 
311     /**
312      * Indicates whether the provider must provide bearing information.
313      * Not all fixes are guaranteed to contain such information.
314      */
setBearingRequired(boolean bearingRequired)315     public void setBearingRequired(boolean bearingRequired) {
316         mBearingRequired = bearingRequired;
317     }
318 
319     /**
320      * Returns whether the provider must provide bearing information.
321      * Not all fixes are guaranteed to contain such information.
322      */
isBearingRequired()323     public boolean isBearingRequired() {
324         return mBearingRequired;
325     }
326 
327     public static final @android.annotation.NonNull Parcelable.Creator<Criteria> CREATOR =
328         new Parcelable.Creator<Criteria>() {
329         @Override
330         public Criteria createFromParcel(Parcel in) {
331             Criteria c = new Criteria();
332             c.mHorizontalAccuracy = in.readInt();
333             c.mVerticalAccuracy = in.readInt();
334             c.mSpeedAccuracy = in.readInt();
335             c.mBearingAccuracy = in.readInt();
336             c.mPowerRequirement = in.readInt();
337             c.mAltitudeRequired = in.readInt() != 0;
338             c.mBearingRequired = in.readInt() != 0;
339             c.mSpeedRequired = in.readInt() != 0;
340             c.mCostAllowed = in.readInt() != 0;
341             return c;
342         }
343 
344         @Override
345         public Criteria[] newArray(int size) {
346             return new Criteria[size];
347         }
348     };
349 
350     @Override
describeContents()351     public int describeContents() {
352         return 0;
353     }
354 
355     @Override
writeToParcel(Parcel parcel, int flags)356     public void writeToParcel(Parcel parcel, int flags) {
357         parcel.writeInt(mHorizontalAccuracy);
358         parcel.writeInt(mVerticalAccuracy);
359         parcel.writeInt(mSpeedAccuracy);
360         parcel.writeInt(mBearingAccuracy);
361         parcel.writeInt(mPowerRequirement);
362         parcel.writeInt(mAltitudeRequired ? 1 : 0);
363         parcel.writeInt(mBearingRequired ? 1 : 0);
364         parcel.writeInt(mSpeedRequired ? 1 : 0);
365         parcel.writeInt(mCostAllowed ? 1 : 0);
366     }
367 
powerToString(int power)368     private static String powerToString(int power) {
369         switch (power) {
370             case NO_REQUIREMENT:
371                 return "NO_REQ";
372             case POWER_LOW:
373                 return "LOW";
374             case POWER_MEDIUM:
375                 return "MEDIUM";
376             case POWER_HIGH:
377                 return "HIGH";
378             default:
379                 return "???";
380         }
381     }
382 
accuracyToString(int accuracy)383     private static String accuracyToString(int accuracy) {
384         switch (accuracy) {
385             case NO_REQUIREMENT:
386                 return "---";
387             case ACCURACY_HIGH:
388                 return "HIGH";
389             case ACCURACY_MEDIUM:
390                 return "MEDIUM";
391             case ACCURACY_LOW:
392                 return "LOW";
393             default:
394                 return "???";
395         }
396     }
397 
398     @Override
toString()399     public String toString() {
400         StringBuilder s = new StringBuilder();
401         s.append("Criteria[power=").append(powerToString(mPowerRequirement));
402         s.append(" acc=").append(accuracyToString(mHorizontalAccuracy));
403         s.append(']');
404         return s.toString();
405     }
406 }
407