Получение неправильного местоположения широта / долгота

Я использую Nexus 6p с Android 7.1.2. Я установил точность определения местоположения устройства на HIGH_ACCURACY. В моем коде есть фоновая служба для обновления местоположения с использованием FusedLocation API. Как видите, я также установил приоритет запроса местоположения на HIGH_ACCURACY. Теперь я протестировал его, когда устройство лежало на моем столе без каких-либо движений, и большую часть времени у меня были одинаковые значения LAT/LONG, а иногда я видел незначительное изменение значений LAT/LONG, даже если устройство было выключено. не двигаюсь. Поэтому я напечатал точность местоположения, используя метод getAccuracy. В документах говорится, что если метод getAccuracy возвращает значение >= 68, это означает, что существует высокая вероятность того, что устройство (пользователь) находится в этом месте. Поэтому я попытался использовать этот метод (другая версия кода ниже) и проверил, возвращает ли getAccuracy значение >= 68, а затем распечатал сведения о местоположении. Угадай, что? не очень помогло..

Следующее, что я попробовал, это повернуть устройство, и я увидел, что, когда устройство было в ландшафтном режиме спиной ко мне, местоположение широта/долгота менялось (хотя я никуда не ходил), а точность увеличивалась и в некоторых случаях доходил до значения 180.

Так вот этого я не понимаю:

Почему иногда значения широты/долготы устройства отличаются, хотя устройство лежит на столе и не двигается?

И как повороты влияют на точность определения местоположения?!

Мой код:

 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();
    }
}

person Elior    schedule 18.10.2017    source источник


Ответы (1)


Это неточность GPS, это не проблема устройства. Он пытается определить точное местоположение, поэтому перемещается туда-сюда, пытаясь улучшить точность GPS. Попробуйте установить наименьшее смещение и интервал для более точного результата.

 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);
person Omar Hayat    schedule 18.10.2017
comment
Спасибо попробую - person Elior; 18.10.2017
comment
Хорошо.. кажется, работает.. Итак, если я правильно понял.. setSmallestDisplacement приведет к обновлению местоположения, только если есть разница в 27 метров (в вашем примере) - person Elior; 18.10.2017
comment
Да, я использую это в своем приложении, и это дает мне очень точный результат. - person Omar Hayat; 18.10.2017