-1

I'm looking for GPS coordinates. My criteria are:

  1. is not equal to the last location

  2. Accuracy < 500

In general terms, System should accept GPS coords that are <200m aprox.

I've made 4 tries in my app:

First try:

19.3820126,-99.1647096:Acc:50.528 Last location ( That's why we keep searching - error 3 km)
01-29 10:37:42.698  onLocationChanged﹕ 19.364292,-99.1776019:Acc:660.0 (error: Aprox 60 m - should accept it)
01-29 10:37:47.733  onLocationChanged﹕ 19.3639126,-99.1771124:Acc:660.0 (error: Aprox 80 m - should accept it)
01-29 10:37:52.788  onLocationChanged﹕ 19.3639126,-99.1771124:Acc:660.0 (error: Aprox 80 m - should accept it)
01-29 10:37:57.853  onLocationChanged﹕ 19.3820112,-99.1646983:Acc:50.531 (Last location - error 3km)... System get the wrong coord.

Second try:

01-29 10:42:05.885  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (error: Aprox 100 m - should accept it)
01-29 10:42:10.980  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (error: Aprox 100 m - should accept it)
01-29 10:42:15.985  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (error: Aprox 100 m - should accept it)
01-29 10:42:21.020  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (error: Aprox 100 m - should accept it)
01-29 10:42:26.085  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (error: Aprox 100 m - How can onLocationChanged can be called if location is not changing)

Third try:

01-29 10:47:20.002  onLocationChanged﹕ 19.3652615,-99.1782989:Acc:784.0 (Last location - error: Aprox 100 m)
01-29 10:47:25.037  onLocationChanged﹕ 19.3820153,-99.1646946:Acc:50.532 (Last location - error 3km)... System get the wrong coord.

Fourth try:

01-29 11:00:25.518  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 (error: Aprox 100 m - should accept it)
01-29 11:00:34.016  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 (error: Aprox 100 m - should accept it)
01-29 11:00:38.451  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 (error: Aprox 100 m - should accept it)
01-29 11:00:43.455  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 (error: Aprox 100 m - should accept it)
01-29 11:00:48.530  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 (error: Aprox 100 m - should accept it)
01-29 11:00:53.585  onLocationChanged﹕ 19.3651962,-99.1780395:Acc:639.0 Time's up, app doesn't accept the coord ( criteria is Acc < 500), but I could accept it.

Those 4 tries make me ask a lot:

  1. is Accuracy a trustable factor. I understand that the smaller the accuracy, the better result. Nevertheless, I find out here that trusting the accuracy get me the wrong result.

  2. In the first and third try, why the accecpted coord is another coord (my home, and I am at work)

  3. In the second try, why is onLocationChanged called if the coord is the same

My code is very standard:

public class LocationUtils implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final long ONE_MIN = 1000 * 60;
private Context ctx;
// Debugging tag for the application
public static final String APPTAG = "LocationSample";

public static final int MILLISECONDS_PER_SECOND = 1000;

// The update interval
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;

// A fast interval ceiling
public static final int FAST_CEILING_IN_SECONDS = 1;

// Update interval in milliseconds
public static final long UPDATE_INTERVAL_IN_MILLISECONDS =
        MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;

// A fast ceiling of update intervals, used when the app is visible
public static final long FAST_INTERVAL_CEILING_IN_MILLISECONDS =
        MILLISECONDS_PER_SECOND * FAST_CEILING_IN_SECONDS;
public static final long FASTEST_INTERVAL_CEILING_IN_MILLISECONDS = 100; // 16ms = 60fps

// Create an empty string for initializing strings
public static final String EMPTY_STRING = new String();
public static GoogleApiClient mGoogleApiClient;
public static LocationRequest mLocationRequest;
private int mAction;



public LocationUtils(Context context) {
    ctx = context;
}


public static void disconnectGPS(LocationListener list) {
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        stopPeriodicUpdates(mGoogleApiClient, list);
        mGoogleApiClient.disconnect();
    }
}

public static void startPeriodicUpdates(GoogleApiClient mGoogleApiClient, LocationRequest mLocationRequest, LocationListener listener) {
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, listener);

}

public static void stopPeriodicUpdates(GoogleApiClient mGoogleApiClient, LocationListener listener) {
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, listener);
}

public void init_location(Context ctx) {
    mGoogleApiClient = new GoogleApiClient.Builder(ctx)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    mLocationRequest = LocationRequest.create();

    /*
     * Set the update interval
     */
    mLocationRequest
            .setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);

    // Use high accuracy
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // Set the interval ceiling to one minute
    mLocationRequest
            .setFastestInterval(FAST_INTERVAL_CEILING_IN_MILLISECONDS);
    mLocationRequest
            .setFastestInterval(FASTEST_INTERVAL_CEILING_IN_MILLISECONDS);
}


public static boolean servicesAvailable(Context ctx) {
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(ctx);

    if (ConnectionResult.SUCCESS == resultCode) {
        return true;
    } else {
        GooglePlayServicesUtil.getErrorDialog(resultCode, (Activity) ctx, 0).show();
        return false;
    }
}

@Override
public void onConnected(Bundle bundle) {
        startPeriodicUpdates(mGoogleApiClient,mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onLocationChanged(Location location) {
    Log.e("onLocationChanged",location.getLatitude()+","+location.getLongitude()+":Acc:"+location.getAccuracy() );
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

public void connect(int action) {
    mAction = action;
    if (!mGoogleApiClient.isConnected()) {
        mGoogleApiClient.connect();
        }


    }
}

I'm testing with several devices, Samsung s4, s3 mini, core 2. I always have GPS on, no wifi, but 3G activated.

EDIT: I'm testing indoor, so GPS results should not be great, but I expect Fused Location adapting to my situation as I can no longer choose the provider.

Juliatzin
  • 18,455
  • 40
  • 166
  • 325
  • Afaik, GPS does not work well indoors. Google's FusedLocationProvider will attempt to use wifi to locate you more accurately when you move from outdoors to indoors. This may be why you are seeing low accuracies. – stkent Jan 28 '15 at 17:20
  • ok, my place is not so good for getting good result, that's why it is a good place to test ! then I don't understand why bad Acc (600) -> 80m difference. When I use Wifi, I get Coord very quickly, I have no more problem, but in my case, user will always be in the street, so he will never have Wifi – Juliatzin Jan 28 '15 at 17:23
  • GPS is Assisted GPS (AGPS) which means that it uses network towers triangulation/wifi to help find a location while the GPS tried to find a satellite, if you are indoors it obviously isnt going to be able to find a satellite – tyczj Jan 28 '15 at 17:30
  • In regards to your last edit, the fused location is adapting its using the network, it does not perform magic and return you a super accurate location especially if you are standing still. in short the location provider is working as expected – tyczj Jan 28 '15 at 17:44

2 Answers2

1

Accuracy is only 68% probability that your location is within the radius, so there is still a pretty good chance that it's incorrect.

By no WiFi you mean you are not connected to any network or that WiFi is disabled?

For example, if you had WiFi router in one place and then move to a new place and take WiFi router with you, Google will still return old location for quite a while.

As for your last question, you requested to update location every 5 seconds, so you will get callback with specified period even if location is the same.

Anton Tananaev
  • 2,458
  • 1
  • 25
  • 48
  • Ok, Understood for the bullet 1 and 3. for the second one, my work and my home are like 3 km distant. The case I test is always GPS + 3G and no wifi connection. I'm not moving any router – Juliatzin Jan 28 '15 at 21:53
-1

Duplicate question? How accurate is Android GPS?

However, if you're looking to pinpoint certain locations, depending on whatever it is you're trying to accomplish, look into geofencing.

http://appcrawlr.com/android-apps/best-apps-geo-fencing

Community
  • 1
  • 1