我正在尝试获取当前用户的位置。我试图重构我的代码以获得更好的结果,但我只是在准确性方面不断获得荒谬的位置,它在 900-600 米之间。
我怎样才能获得更好的结果,以使其达到 50m 以内的精度?
这是我的代码:
package com.agam.mapslocation;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class MapsActivity extends Activity {
private static final int ONE_MINUTE = 1000 * 60 * 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
final LocationManager locationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
final EditText et = (EditText) findViewById(R.id.editText1);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location l) {
// Called when a new location is found by the network location
// provider.
Location gps = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location net = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location bestLocation = null;
bestLocation = isBetterLocation(gps, net);
bestLocation = isBetterLocation(bestLocation, l);
if(bestLocation!=null)
displayLocation(et, bestLocation);
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
public void onProviderEnabled(String provider) {
if (provider.equals(LocationManager.GPS_PROVIDER)) {
et.setText("GPS ON!");
}
}
public void onProviderDisabled(String provider) {
}
};
// Register the listener with the Location Manager to receive location
// updates
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, locationListener);
}
public static void displayLocation(View v, Location l) {
((EditText) v).setText(String.format(
"Long:%s,\nLat:%s,\nAccu:%s,\nTime ago:%s,\nProvider:%s",
l.getLongitude(), l.getLatitude(), l.getAccuracy(),
new java.util.Date().getTime() - l.getTime(), l.getProvider()));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_maps, menu);
return true;
}
/**
* Determines whether one Location reading is better than the current
* Location fix
*
* @param location
* The new Location that you want to evaluate
* @param currentBestLocation
* The current Location fix, to which you want to compare the new
* one
*/
protected Location isBetterLocation(Location location,
Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return location;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > ONE_MINUTE;
boolean isSignificantlyOlder = timeDelta < -ONE_MINUTE;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use
// the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return location;
// If the new location is more than two minutes older, it must be
// worse
} else if (isSignificantlyOlder) {
return currentBestLocation;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and
// accuracy
if (isMoreAccurate) {
return location;
} else if (isNewer && !isLessAccurate) {
return location;
} else if (isNewer && !isSignificantlyLessAccurate
&& isFromSameProvider) {
return location;
}
return currentBestLocation;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
}
注意:我强调静态位置,例如不要移动,因为它可能有助于答案。