Я хочу получить точное местоположение с помощью 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