我有一个需要设备当前位置(纬度和经度)的android应用程序。我已经在网上尝试了一些教程,特别是一些来自堆栈溢出的解决方案,但是它们对我来说效果不佳。我的要求非常简单:首先,我需要它要快,并且在片段开始时需要一次定位。其次,我需要尽可能精确,我的意思是,如果无法使用GPS,则应首先使用GPS,然后使用网络提供商。
例如,我试过了this solution,但是它在30秒后返回null,但是我知道有些事情是可以的,因为google map和其他应用程序效果很好!
几乎所有答案都暗示着要使用getLastKnownLocation(),但是我想它不是当前的,如果是这样,我就不要了。
有人可以建议我一种简单快捷的方法来仅一次获得该位置吗?
最佳答案
在这里,您可以使用此...
用法示例:
public void foo(Context context) {
// when you need location
// if inside activity context = this;
SingleShotLocationProvider.requestSingleUpdate(context,
new SingleShotLocationProvider.LocationCallback() {
@Override public void onNewLocationAvailable(GPSCoordinates location) {
Log.d("Location", "my location is " + location.toString());
}
});
}
您可能要验证经度/纬度是实际值,而不是0或其他值。如果我没记错的话,这不应该抛出NPE,但您可能需要验证一下。
public class SingleShotLocationProvider {
public static interface LocationCallback {
public void onNewLocationAvailable(GPSCoordinates location);
}
// calls back to calling thread, note this is for low grain: if you want higher precision, swap the
// contents of the else and if. Also be sure to check gps permission/settings are allowed.
// call usually takes <10ms
public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isNetworkEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
}, null);
} else {
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
}, null);
}
}
}
// consider returning Location instead of this dummy wrapper class
public static class GPSCoordinates {
public float longitude = -1;
public float latitude = -1;
public GPSCoordinates(float theLatitude, float theLongitude) {
longitude = theLongitude;
latitude = theLatitude;
}
public GPSCoordinates(double theLatitude, double theLongitude) {
longitude = (float) theLongitude;
latitude = (float) theLatitude;
}
}
}