Search code examples
androidandroid-fusedlocation

Android Fused Location API gives inaccurate Location in onLocationChanged


I am struggling a little here, I am using Fused API for getting location updates. My intention is to draw a path on Map when user walks.

I have implemented that as follows :

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.map_layout, container, false);

        // some other initialization
        //....
        //
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }

        return view;
    }

then I start the stuff by following method

private void startReceivingLocationUpdates() {
        if (checkGPSPermission() && mGoogleApiClient.isConnected() && !isReceivingLocationUpdates) {
            LocationRequest locationRequest = new LocationRequest();
            locationRequest.setInterval(5000);
            locationRequest.setFastestInterval(5000);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                    locationRequest, this);
            isReceivingLocationUpdates = true;
        }
    }

& Here I receive the location update

@Override
    public void onLocationChanged(Location location) {
      if(getDistanceBetweenTwoLacation(mCoordinates.get(mCoordinates.size() - 1), location) > 3d) {
            for(int i= 0; i < mCoordinates.size(); i++) {
                Location locationTemp = mCoordinates.get(i);
                Log.d(TAG, "i => " + i + " Lat => " + String.valueOf(locationTemp.getLatitude()) + " Lng => " + String.valueOf(locationTemp.getLongitude()));
            }
            if(mCoordinates.size() > 0)
                Log.d(TAG, "lat difference is => " + getDistanceBetweenTwoLacation(mCoordinates.get(mCoordinates.size() - 1), location));
            mCoordinates.add(location);
        }
    }

Now the problem is , onLocationChanged gives location with lat-lng whose difference/distance from past location is about 5-90 meters many times even if device is steady on same place. Am I missing something?

btw, here's the method which returns the distance from two lat-lngs which I used

private double getDistanceBetweenTwoLacation(Location origin, Location destination) {
        return origin.distanceTo(destination);
    }

Solution

  • Inaccurate (and moving/drifting/jumping) GPS fixes when indoors is pretty common. Without a clear view of the sky, an accurate GPS fix is impossible. In your Location object, there is a getAccuracy() method which returns a float. This value is the accuracy of the position fix in meters, wit 68% (1 standard deviation) confidence and represents the radius of a circle.

    While indoors you will probably see an accuracy value of 20, 30, perhaps even 50 meters while the Lat & Long jump around within that distance. Once outdoors, the accuracy value should drop to under 10 meters, often under 5 meters, and your position will jump around much less frequently.

    tl;dr : GPS doesn't give accurate results indoors.