问题在于getLastLocation(),因为它使用了缓存位置。我遇到了同样的问题,因为我也尝试使用这种简单的方法。从那以后,我已经切换到收听更新(并在第一次成功更新后自动停止)。
这是我的有效代码。
首先,在Application中检查可用性(不是必须的,可以在Activity中并且不保留结果):
public class MainApp extends Application {
public static enum PlayServices {
NOT_CHECKED, AVAILABLE, UNAVAILABLE
};
public static PlayServices mPlayServices = PlayServices.NOT_CHECKED;
@Override
public void onCreate() {
super.onCreate();
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE;
}
}
}
然后,进入活动:
public class MainActivity extends SherlockFragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
在其onCreate():
if (MainApp.mPlayServices != MainApp.PlayServices.UNAVAILABLE) {
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setNumUpdates(1);
mLocationRequest.setFastestInterval(1000);
mUpdatesRequested = false;
MainApp.prefs.edit().putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested)
.commit();
}
MainActivity 类的其余部分:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(this.getClass().getSimpleName(), "onActivityResult(" + requestCode + ", " + resultCode
+ ")");
// Decide what to do based on the original request code
switch (requestCode) {
case MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try
* to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
// here we want to initiate location requests!
mLocationClient = new LocationClient(this, this, this);
break;
}
break;
}
}
@Override
public void onConnected(Bundle dataBundle) {
Log.d(this.getClass().getSimpleName(), "onConnected()");
Log.d(this.getClass().getSimpleName(), "Google Play Services are available.");
MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE;
if (!mUpdatesRequested) {
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
boolean network_enabled = false;
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
// don't start listeners if no provider is enabled
MainApp.locEnabled = gps_enabled || network_enabled;
if (!MainApp.locEnabled) {
// we have access to PlayServices, but user has disabled location visibility --> alert him
alertLocationOff();
} else {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
mUpdatesRequested = true;
}
}
}
@Override
public void onDisconnected() {
Log.d(this.getClass().getSimpleName(), "onDisconnected()");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(this.getClass().getSimpleName(), "onConnectionFailed()");
Log.d(this.getClass().getSimpleName(), "Google Play Services not available.");
MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE;
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this,
MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
}
}
@SuppressLint("NewApi")
@Override
public void onLocationChanged(Location location) {
Log.d(this.getClass().getSimpleName(), "onLocationChanged(), location=" + location);
if (location != null) {
boolean present = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
present = Geocoder.isPresent();
}
if (present) {
(new ExtractLocationTask(this)).execute(location);
} else {
Log.e(this.getClass().getSimpleName(), "Geocoder not present");
MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE;
}
}
}
private class ExtractLocationTask extends AsyncTask<Location, Void, Boolean> {
Context mContext;
public ExtractLocationTask(Context context) {
super();
mContext = context;
}
@Override
protected Boolean doInBackground(Location... params) {
Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPreExecute()");
boolean found = false;
try {
Geocoder geoCoder_local = new Geocoder(mContext, Locale.getDefault());
Geocoder geoCoder_en = new Geocoder(mContext, Locale.ENGLISH);
List<Address> addresses_local = geoCoder_local.getFromLocation(params[0].getLatitude(),
params[0].getLongitude(), 10);
List<Address> addresses_en = geoCoder_en.getFromLocation(params[0].getLatitude(),
params[0].getLongitude(), 10);
if (addresses_local != null && addresses_local.size() > 0) {
// do what you want with location info here
// based on mLocationRequest.setNumUpdates(1), no need to call
// removeLocationUpdates()
MainApp.locEnabled = true;
mUpdatesRequested = false;
MainApp.prefs.edit()
.putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested).commit();
found = true;
}
} catch (IOException e) {
Log.e(this.getClass().getSimpleName(), "Exception: ", e);
}
return found;
}
@Override
protected void onPostExecute(Boolean found) {
Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPostExecute()");
if (found) {
// update UI etc.
} else if (!mUpdatesReRequested) {
mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener) mContext);
mUpdatesRequested = true;
mUpdatesReRequested = true;
}
}
}
我希望这会帮助你让它工作!