Как получить точное местоположение (широта и долгота) с помощью FusedLocationProviderClient
Привет, я использую FusedLocationClient для получения местоположения от пользователя. Это работает, я могу периодически получать широту и долготу, но иногда расстояние, показывающее неправильное, как это будет от 10.0 до 200.0 в секундах, а затем вернется к 10.0. Я хотел бы показать пользователю, что он находится в 200 метрах от магазина. но даже если они всего в 10 метрах, приложение иногда показывает, что они в 200 метрах от магазина.
Есть ли что-нибудь, что я могу сделать, чтобы улучшить точность определения местоположения Клиента.
class LocServices : Service() {
private val TAG = ""
private val UPDATE_INTERVAL_IN_MILLISECONDS: Long = 5000
private val FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2
private var mLocationRequest: LocationRequest? = null
private var mFusedLocationClient: FusedLocationProviderClient? = null
private var mLocationCallback: LocationCallback? = null
private var mLocation: Location? = null
var existLongitude: String? = null
var existLatitude: String? = null
var sharedPrefs: SharedPreferences? = null
override fun onCreate() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
super.onLocationResult(locationResult)
onNewLocation(locationResult!!.lastLocation)
}
}
createLocationRequest()
getLastLocation()
requestLocationUpdates()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i(TAG, "Service started")
return Service.START_STICKY
}
override fun onBind(intent: Intent): IBinder? {
return null
}
private fun requestLocationUpdates() {
sharedPrefs = this.getSharedPreferences("GEO", Context.MODE_PRIVATE)
if (sharedPrefs != null) {
existLatitude = sharedPrefs!!.getString("LAT", null)
existLongitude = sharedPrefs!!.getString("LONG", null)
}
if (existLatitude != null && existLongitude != null) {
Log.i(TAG, "Requesting location updates")
setRequestingLocationUpdates(this, true)
try {
mFusedLocationClient!!.requestLocationUpdates(mLocationRequest, mLocationCallback!!, Looper.myLooper())
} catch (unlikely: SecurityException) {
setRequestingLocationUpdates(this, false)
Log.e(TAG, "Lost location permission. Could not request updates. $unlikely")
}
}
}
private fun getLastLocation() {
try {
mFusedLocationClient!!.lastLocation
.addOnCompleteListener { task ->
if (task.isSuccessful && task.result != null) {
mLocation = task.result
} else {
Log.w(TAG, "Failed to get location.")
}
}
} catch (unlikely: SecurityException) {
Log.e(TAG, "Lost location permission.$unlikely")
}
}
private fun onNewLocation(location: Location) {
Log.i(TAG, "New location: $location")
mLocation = location
if (existLatitude != null && existLongitude != null) {
val selected_location = Location("locationA")
selected_location.latitude = existLatitude!!.toDouble()
selected_location.longitude = existLongitude!!.toDouble()
val near_locations = Location("locationB")
near_locations.latitude = mLocation!!.latitude
near_locations.longitude = mLocation!!.longitude
val distance = selected_location.distanceTo(near_locations)
Toast.makeText(this, distance.toString(), Toast.LENGTH_SHORT).show()
if (distance > 53.0) {
Toast.makeText(this, "You are outside $distance", Toast.LENGTH_SHORT).show()
}
}
}
private fun createLocationRequest() {
mLocationRequest = LocationRequest()
mLocationRequest!!.interval = UPDATE_INTERVAL_IN_MILLISECONDS
mLocationRequest!!.fastestInterval = FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS
mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
companion object {
val KEY_REQUESTING_LOCATION_UPDATES = "requesting_locaction_updates"
fun setRequestingLocationUpdates(context: Context, requestingLocationUpdates: Boolean) {
PreferenceManager.getDefaultSharedPreferences(context)
.edit()
.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, requestingLocationUpdates)
.apply()
}
}
}
1 ответ
Я думаю, что лучше всего рассчитать расстояние от GPS, чтобы рассчитать расстояние между двумя местоположениями и добавить. Чтобы рассчитать расстояние между двумя точками -
public static double GetDistanceInMeter(Location source, Location destination) {
double distance = 0d;
if (source != null && destination != null) {
double lat1 = source.getLatitude();
double lon1 = source.getLongitude();
double lat2 = destination.getLatitude();
double lon2 = destination.getLongitude();
final int R = 6371;
// Radius of the earth in km
double dLat = deg2rad(lat2 - lat1);
// deg2rad below
double dLon = deg2rad(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
// Distance in m
distance = (R * c) * 1000;
}
return distance;
}
Подход заключается в том, чтобы сохранить предыдущее местоположение, а затем вычислить расстояние между старым и новым, а затем добавить его к общему расстоянию. Это лучший подход к этой проблеме, а также самый точный. Поскольку GPS не так точен, то ваше общее пройденное расстояние будет +-50 метров.