我想使用Google融合定位API获取准确的位置信息?

12

我正在使用融合位置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
                }

            });

我该如何优化这段代码以获取准确的位置。谢谢。


我认为这段代码是完美的。我不认为它可以更加优化。 - Umer
2个回答

9

位置精度基于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.
   }

}

1
如果location.hasAccuracy()是false,location.getAccuracy()将始终返回0.0。在评估位置的准确性之前,必须检查hasAccuracy()。请参阅http://developer.android.com/reference/android/location/Location.html#getAccuracy()。 - Much Overflow

8

2020年最佳官方解决方案

Google API客户端/FusedLocationApi已经过时,而位置管理器基本没有用处。 因此,Google更喜欢使用Google Play服务位置API中的融合位置提供程序"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
                    }

                }

    }

如果您的应用可以持续跟踪位置,则必须接收位置更新

请查看Kotlin示例

// 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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接