I'm using Nexus 6p with Android 7.1.2. I set the device location accuracy to be HIGH_ACCURACY
.
In my code, I have a background service for location update, using the FusedLocation
API. As you can see I also set the location request priority to be HIGH_ACCURACY
.
Now I've tested it when the device was on my desk without any movements and for most of the time I've got the same LAT/LONG values and sometimes I saw a minor change with the LAT/LONG values even though the device wasn't moving.
So I printed the Location accuracy using the getAccuracy
method.
The docs says that if getAccuracy
method returns a value >= 68 so it means that there is a high chance that the device (user) is at this location.
So I tried to use this method (another version of the code below) and checked if getAccuracy returns a value >= 68 and then print the location details.
Guess what? it didn't help so much..
The next thing I tried is to rotate the device and I saw that when the device was in landsacpe mode with the back to me, the location lat/long was changed (even though i didn't go anywhere) and the accuracy was increased and in some cases reached to the value of 180.
So I don't understand this:
Why sometimes the device's lat/long values are different even though the device is lying on the desk and doesn't move?
And how the rotations is impact on the location accuracy?!
My Code:
public class LocationUpdateService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener
{
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private boolean playsServiceAvailable;
private String TAG = getClass().getSimpleName();
@Override
public void onCreate()
{
Log.d(TAG,"onCreate");
super.onCreate();
initRequestLocation();
playsServiceAvailable = checkPlayServicesConnection();
setupLocationApiClient();
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG, "onStartCommand");
super.onStartCommand(intent,flags,startId);
if (!playsServiceAvailable || googleApiClient.isConnected())
{
return START_STICKY;
}
setupLocationApiClient();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting())
{
Log.d(TAG, "onStartCommand: googleApiclient.connect()");
googleApiClient.connect();
}
return START_STICKY;
}
@Override
public void onDestroy()
{
Log.d(TAG, "onDestroy");
if (this.playsServiceAvailable && this.googleApiClient != null)
{
this.googleApiClient.unregisterConnectionCallbacks(this);
this.googleApiClient.unregisterConnectionFailedListener(this);
this.googleApiClient.disconnect();
this.googleApiClient = null;
}
super.onDestroy();
}
@Override
public void onConnected(@Nullable Bundle bundle)
{
try
{
LocationServices.FusedLocationApi.requestLocationUpdates(this.googleApiClient, locationRequest, this);
}
catch (SecurityException e)
{
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int i)
{
googleApiClient = null;
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult)
{
}
@Override
public void onLocationChanged(Location currentLocation)
{
Log.d(TAG, "onLocationChanged:\n\t\t\t" +
"CurrentLocation:\n\t\t\t\t" +
"ACCURACY: " + currentLocation.getAccuracy() + "\n\t\t\t\t" +
"LAT: " + currentLocation.getLatitude() + "\n\t\t\t\t" +
"LONG: " + currentLocation.getLongitude() + "\n\t\t\t\t" +
"TIME: " + currentLocation.getTime());
}
private boolean checkPlayServicesConnection ()
{
int resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context);
if (resultCode != ConnectionResult.SUCCESS)
{
return false;
}
return true;
}
private void initRequestLocation()
{
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000)
.setFastestInterval(1000);
}
private void setupLocationApiClient()
{
Log.d(TAG,"setupLocationApiClient");
if (googleApiClient == null)
initGoogleApiClient();
}
private synchronized void initGoogleApiClient()
{
Log.d(TAG,"initGoogleApiClient");
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
}
}
This is GPS In-accuracy this not issue with device. It try to fetch exact location so that's why it move here and there try to improve gps accuracy. Try to set smallest displacement and interval for more accurate result.
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(27);//27 meter
mLocationRequest.setInterval(5000); // Update location every 5 seconds
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);