我正在尝试获取手机的current
位置,为此我使用GPSTracker tutorial,问题始终是使用方法getLastKnownLocation
并返回旧位置。
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
使用getLastKnownLocation
或Network
提供商时,您可以看到教程使用GPS
,但我真的需要当前的位置。
我不知道如何得到它!
答案 0 :(得分:6)
将融合位置提供程序API与GoogleApiClient结合使用。你可以找到apis here。它们旨在为位置提供高精度。使用GoogleApiClient使用它。
new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build()
使用位置提供程序还有其他方法。您不应将自己局限于使用GPS和移动网络获得的位置。而是迭代所有位置提供商,并根据您的准确性要求选择那些给您高精度的。以下代码执行此操作:
Location bestResult = null;
float bestAccuracy = Float.MAX_VALUE;
long bestAge = Long.MIN_VALUE;
List<String> matchingProviders = mLocationManager.getAllProviders();
for (String provider : matchingProviders) {
Location location = mLocationManager.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if (accuracy < bestAccuracy) {
bestResult = location;
bestAccuracy = accuracy;
bestAge = time;
}
}
}
// Return best reading or null
if (bestAccuracy > minAccuracy
|| (System.currentTimeMillis() - bestAge) > maxAge) {
return null;
} else {
return bestResult;
}
您也可以在检查位置对象的准确性后直接使用它。您应该利用其他应用访问的位置,而不仅仅是依靠GPS /移动网络获得的位置。
如果您想持续收听位置更新,请实施Locationlistener回调以持续获取位置更新。
答案 1 :(得分:2)
创建此类:
public class MyLocation{
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
@Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
现在将其放入您的活动代码
LocationResult locationResult = new LocationResult() {
@Override
public void gotLocation(Location location) {
Log.d(tag, "lon: "+location.getLongitude()+" ----- lat: "+location.getLatitude());
}
};
最后称之为
MyLocation myLocation = new MyLocation();
myLocation.getLocation(context, locationResult);
你已经完成了。
答案 2 :(得分:1)
如果我没记错的话,该教程相当陈旧,不使用融合位置。如果您在Android Studio中进行开发,请考虑尝试使用此库:https://github.com/mcharmas/Android-ReactiveLocation
使用最新的API减少代码和融合位置。
简单地获取最后一个已知位置:
ReactiveLocationProvider locationProvider = new ReactiveLocationProvider(context);
locationProvider.getLastKnownLocation()
.subscribe(new Action1<Location>() {
@Override
public void call(Location location) {
// doSthImportantWithObtainedLocation(location);
}
});
多数民众赞成!
答案 3 :(得分:1)
我认为其中一个答案使用了locationListener,但是这里有一个简单的解决方案,即使通过调用get getBestProvider无法获得GPS,也会返回该位置,
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, 2000, 0, locationListener);
private final LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
Double latitude = location.getLatitude();
Double longitude = location.getLongitude();
}
};
答案 4 :(得分:1)
The method mentioned above is the deprecated method and Android has asked developers to use the below method.
https://developer.android.com/training/location/retrieve-current.html
Sample Code
onCreate(){
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
buildAlertMessageNoGps();
}
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
@Override
protected void onStart() {
super.onStart();
// Connect the client.
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
// Disconnecting the client invalidates it.
mGoogleApiClient.disconnect();
super.onStop();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(1000 * 60 * 5);
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
@Override
public void onLocationChanged(Location location) {
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
String address = addresses.get(0).getAddressLine(1);
} catch (IOException e) {
e.printStackTrace();
}
editor.commit();
}
答案 5 :(得分:1)
使用以下代码 -
private class LocationListener extends Activity implements android.location.LocationListener{
Location mLastLocation;
public LocationListener(String provider){
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
Toast.makeText(mContext, "Driver location :"+location.getLatitude()+" , "+location.getLongitude(), Toast.LENGTH_SHORT).show();
//TODO call web service to update driver location to server
driverLocationUpdateServerRequest(location);
}
@Override
public void onProviderDisabled(String provider){
Log.e(TAG, "onProviderDisabled: " + provider);
}
@Override
public void onProviderEnabled(String provider){
Log.e(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras){
Log.e(TAG, "onStatusChanged: " + provider);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
}