15

In the Criteria class, there are two constants, ACCURACY_HIGH and ACCURACY_FINE, which are apparently used to require the LocationManager to return higher accuracy location updates. Here is what the documentation says about each of these constants:

public static final int ACCURACY_FINE (Added in API level 1)

  A constant indicating a finer location accuracy requirement
  Constant Value: 1 (0x00000001)

public static final int ACCURACY_HIGH (Added in API level 9)

  a constant indicating a high accuracy requirement - may be used for horizontal, altitude, speed or bearing accuracy. For horizontal and vertical position this corresponds roughly to an accuracy of less than 100 meters.
  Constant Value: 3 (0x00000003) 

Does anyone know which of these two constants provides (i.e. requires) the highest level of accuracy?

robguinness
  • 16,266
  • 14
  • 55
  • 65

3 Answers3

22

From what I can see in the source code, ACCURACY_FINE is grouped with ACCURACY_COARSE with constant values of 1 & 2 respectively. ACCURACY_LOW, MEDIUM and HIGH are grouped together with constant values 1, 2 & 3.

It seems that setAccuracy expects and returns either COARSE or FINE, while setVerticalAccuracy, setHorizontalAccuracy, setSpeedAccuracy and setBearingAccuracy expect LOW, MEDIUM or HIGH. Furthermore, when you call setAccuracy, it sets horizontal accuracy like so:

public void setAccuracy(int accuracy) {
    if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_COARSE) {
        throw new IllegalArgumentException("accuracy=" + accuracy);
    }
    if (accuracy == ACCURACY_FINE) {
        mHorizontalAccuracy = ACCURACY_HIGH;
    } else {
        mHorizontalAccuracy = ACCURACY_LOW;
    }
}

It's really confusing, but I hope I cleared it up for you a bit. Here's a link to the source in grepcode, you can download it and see for yourself if you don't have the source locally.

npace
  • 4,218
  • 1
  • 25
  • 35
  • 1
    Thanks! Unfortunately, it seems to be another case of Android documentation being a bit deficient. Source code link is helpful! – robguinness Jul 26 '13 at 12:25
  • 2
    Not to beg too much, but if the answer helped you, you could accept it! – npace Jul 26 '13 at 13:52
  • I like to give questions a day or two before accepting an answer. I did upvote you though! – robguinness Jul 26 '13 at 14:06
  • Well, it's been a day or two. I up-voted b/c this helped... fine == high apparently. –  Apr 02 '14 at 19:17
  • Upvoted as well since this was very helpful. The fact that ACCURACY_LOW == ACCURACY_FINE seems like a horrible design decision. And not using enums was the first mistake. :-P – stuckj May 12 '15 at 18:06
  • Upvoted. How hard can it be to click the accept button? It's not like it hurts you .... – Aaa Jan 19 '16 at 17:18
  • The question is: Why is there an option to require Low accuracy? Who wants to request geolocation data without accuracy? Is it faster or something? – Jorge Oct 06 '21 at 11:29
8

Both constants mean the highest accuracy, but are intended for different methods. From the documentation (which may have been updated since the question was asked):

ACCURACY_FINE is valid input for setAccuracy.

ACCURACY_HIGH is valid input for setBearingAccuracy, setHorizontalAccuracy, setSpeedAccuracy and setVerticalAccuracy.

I believe the idea of this modeling is that FINE and COARSE give you a choice of two opposites only, whereas LOW, MEDIUM and HIGH allow for a more subtle distinction. (The question remains, why setSpeedAccuracy ridicules that modeling by allowing only LOW and HIGH. But then, this might be a bug in either documentation or design. :) )

As mentioned by the OP, they introduced those values later, API level 9, in contrast to API level 1 for FINE-COARSE. The code found by npace simply reveals that internally the Android developers now map everything to the names and values of the LOW to HIGH value range, to get some consistency internally.

Community
  • 1
  • 1
mknecht
  • 1,205
  • 11
  • 20
-1

There are several criteia to determine the accuracy of the location

Once the device starts providing real-time locations, my suggestion is to check the accuracy of each result and consider rejecting those greater than a certain amount that are based on your requirements. The longer the location provider runs, and if the device has an unobstructed views of the sky and good cellular connection, then typically the accuracy will improve up to a certain point and then level off, and then it will fluctuate. Here’s a pseudo-code snippet showing how to check the accuracy of each GPS location result:

1
2
3

Here are some rough examples of accuracy thresholds . Your requirements may vary as to how these different thresholds will affect the behavior of your application; these were examples that required geocoding that converted the current location to an approximate address. Depending on the result the application gave different feedback to the user:

Rooftop  <= 10 meters (desired result)
Street >10 meters and <= 100 meters (let user know it’s close but not perfect. Good enough?)
Neighborhood > 100 meters and  <= 500 meters (give visual feedback that accuracy is low)
City > 500 meters and <= 2000 meters (ask user to verify city name from a list)
County > 2000 meters (prompt for manual location input)

Take into account your own unique use cases. You might completely reject any accuracy value greater than 100 meters (328 ft) if your app simply helps people find open parking lots at NFL games. You could have an app that returns a list of Dentist offices within a 5 mile (8000m) radius. Or a weather app could only need to know approximately what city you are in. These are just ideas to help get you thinking.

public void onLocationChanged(Location location) {
         if(location.getAccuracy() < 100.0 && location.getSpeed() < 6.95){
              //Do something
         }
         else{
              //Continue listening for a more accurate location
         }
benka
  • 4,732
  • 35
  • 47
  • 58
sijo jose
  • 130
  • 9