Я хочу получить точное местоположение с помощью API-интерфейса местоположения Google?

Я использую Fused location Api, я получаю местоположение с точностью около 10 метров. Иногда это дает точность от 4 до 8 метров. Я хочу большей точности, используя это слитное местоположение Api или любым другим способом. Есть ли способ получить местоположение с точностью менее 4 метров.

Я получаю местоположение с этим путем.

    public class GetCurrentLocation implements
            ConnectionCallbacks, OnConnectionFailedListener, LocationListener {

        private static final String TAG = "location-updates-sample";
        public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 0;
        public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
                UPDATE_INTERVAL_IN_MILLISECONDS / 2;
        private final String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
        private final String LOCATION_KEY = "location-key";
        private final String LAST_UPDATED_TIME_STRING_KEY = "last-updated-time-string-key";
        private GoogleApiClient mGoogleApiClient;
        private LocationRequest mLocationRequest;

        private Context mContext;
        private getLocation mGetCurrentLocation;

        public GetCurrentLocation(Context context) {
            mContext = context;

            buildGoogleApiClient();
        }

        private synchronized void buildGoogleApiClient() {
            Log.i(TAG, "Building GoogleApiClient");
            mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
            createLocationRequest();
        }

        public interface getLocation{
            public void onLocationChanged(Location location);
        }

        public void startGettingLocation(getLocation location) {
            mGetCurrentLocation = location;
            connect();
        }

        public void stopGettingLocation() {
            stopLocationUpdates();
            disconnect();
        }

        private void createLocationRequest() {
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }

        private void startLocationUpdates() {
            if (mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(
                        mGoogleApiClient, mLocationRequest, this);
            }
        }
    private void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }



    private void connect() {
        mGoogleApiClient.connect();
    }

    private void disconnect() {
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "Connected to GoogleApiClient");
        startLocationUpdates();

    }

    @Override
    public void onLocationChanged(Location location) {
        mGetCurrentLocation.onLocationChanged(location);
    }

    @Override
    public void onConnectionSuspended(int cause) {
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
    }
}

И я использую этот класс в своем коде активности.

private GetCurrentLocation mListen;
mListen = new GetCurrentLocation(this);
            mListen.startGettingLocation(new GetCurrentLocation.getLocation() {
                @Override
                public void onLocationChanged(Location location) {
                   // Here is my working with location object
                }

            });

Как я могу оптимизировать этот код, чтобы получить точное местоположение. Благодарю.

1 ответ

Точность определения местоположения зависит от поставщика услуг GPS/ сети, вы можете просто ждать и получать данные о них.

Вы можете снова определить точность

@Override
public void onLocationChanged(Location location) {
   int suitableMeter = 20; // adjust your need
   if (location.hasAccuracy()  && location.getAccuracy() <= suitableMeter) {
        // This is your most accurate location.
   }

}

Лучшее официальное решение 2019 года

Клиент API Google / FusedLocationApi устарел, а диспетчер местоположения вообще бесполезен.Таким образом, Google предпочитает Fused Location Provider. Использование API-интерфейсов определения местоположения сервисов Google Play "FusedLocationProviderClient" используется для определения местоположения и лучшего способа экономии заряда аккумулятора и точности.

Вот пример кода в kotlin, чтобы получить последнее известное местоположение / одноразовое местоположение (эквивалентное текущему местоположению)

 // declare a global variable of FusedLocationProviderClient
    private lateinit var fusedLocationClient: FusedLocationProviderClient

// in onCreate() initialize FusedLocationProviderClient
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)

 /**
     * call this method for receive location
     * get location and give callback when successfully retrieve
     * function itself check location permission before access related methods
     *
     */
    fun getLastKnownLocation() {
            fusedLocationClient.lastLocation
                .addOnSuccessListener { location->
                    if (location != null) {
                       // use your location object
                        // get latitude , longitude and other info from this
                    }

                }

    }

Если ваше приложение может постоянно отслеживать местоположение, вы должны получать обновления местоположения

Проверьте образец для этого в котлине

// declare a global variable FusedLocationProviderClient
        private lateinit var fusedLocationClient: FusedLocationProviderClient

    // in onCreate() initialize FusedLocationProviderClient
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)


      // globally declare LocationRequest
        private lateinit var locationRequest: LocationRequest

        // globally declare LocationCallback    
        private lateinit var locationCallback: LocationCallback


        /**
         * call this method in onCreate
         * onLocationResult call when location is changed 
         */
        private fun getLocationUpdates()
        {

                fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
                locationRequest = LocationRequest()
                locationRequest.interval = 50000
                locationRequest.fastestInterval = 50000
                locationRequest.smallestDisplacement = 170f // 170 m = 0.1 mile
                locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
                locationCallback = object : LocationCallback() {
                    override fun onLocationResult(locationResult: LocationResult?) {
                        locationResult ?: return

                        if (locationResult.locations.isNotEmpty()) {
                            // latest location is on 0th index
                            val location =
                                LatLng(locationResult.locations[0].latitude, locationResult.locations[0].longitude)
                            // use your location object
                            // get latitude , longitude and other info from this
                        }


                    }
                }
        }

        //start location updates
        private fun startLocationUpdates() {
            fusedLocationClient.requestLocationUpdates(
                locationRequest,
                locationCallback,
                null /* Looper */
            )
        }

        // stop location updates
        private fun stopLocationUpdates() {
            fusedLocationClient.removeLocationUpdates(locationCallback)
        }

        // stop receiving location update when activity not visible/foreground
        override fun onPause() {
            super.onPause()
            stopLocationUpdates()
        }

        // start receiving location update when activity  visible/foreground
        override fun onResume() {
            super.onResume()
            startLocationUpdates()
        }

Убедитесь, что вы позаботились о разрешении Mainfaist и разрешении времени выполнения для местоположения

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

и для Gradle добавьте это

implementation 'com.google.android.gms:play-services-location:17.0.0'

Подробности смотрите в этих официальных документах.

https://developer.android.com/training/location/retrieve-current

https://developer.android.com/training/location/receive-location-updates

https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient

Другие вопросы по тегам