参考
http://blog.csdn.net/qq_24636637/article/details/50461284
http://blog.csdn.net/qq_33689414/article/details/54136922
package com.app.common.android; import android.annotation.SuppressLint; import android.content.Context; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.support.annotation.Nullable; import android.text.TextUtils; import com.app.common.task.CtrlResult; import com.app.common.task.CtrlTaskV2; import java.io.IOException; import java.io.Serializable; import java.util.List; import java.util.Locale; @SuppressLint("MissingPermission") public class GoogleLocationUtil { private static final String TAG = "GoogleLocationUtil"; public interface KKLocationListener { void onLocateSuccess(final KKLocation location); void onLocateFailed(final String errMessage); } private LocationManager mLocationManager; private Geocoder mGeocoder; private KKLocationListener mKKLocationListener; private volatile boolean callBackInvoked = false; public GoogleLocationUtil(Context context) { mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); mGeocoder = new Geocoder(context, Locale.CHINA); } private LocationListener mGoogleLocationListener = new LocationListener() { public void onLocationChanged(final Location location) { mLocationManager.removeUpdates(this); getAddress(location); } public void onStatusChanged(String provider, int status, Bundle extras) { LogUtil.d(TAG, "onStatusChanged: provider is " + provider + ",status is " + status); if (status == LocationProvider.OUT_OF_SERVICE) { notifyLocationChanged(provider + "服务受限", null); } else if (status == LocationProvider.TEMPORARILY_UNAVAILABLE) { notifyLocationChanged(provider + "服务暂不可用", null); } } //Called when the provider is enabled by the user. public void onProviderEnabled(String provider) { LogUtil.d(TAG, "onProviderEnabled: provider is " + provider); } public void onProviderDisabled(String provider) { notifyLocationChanged(provider + "已被禁用", null); } }; public KKLocationListener getLocationListener() { return mKKLocationListener; } public void getLocation(KKLocationListener locationListener) { getLocation(locationListener, LocationManager.NETWORK_PROVIDER); } public void getLocation(KKLocationListener locationListener, String provider) { this.mKKLocationListener = locationListener; if (!isProviderEnable(provider)) { LogUtil.e(TAG, "getLocation error: provider not found:" + provider); notifyLocationChanged("getLocation error: not provide found, have you open", null); return; } Location location = mLocationManager.getLastKnownLocation(provider); if (location != null) { LogUtil.d(TAG, provider + " getLastKnownLocation:" + location); getAddress(location); return; } mLocationManager.requestLocationUpdates(provider, 1000, 5, mGoogleLocationListener); UIThread.uiPost(new Runnable() { @Override public void run() { if (!callBackInvoked) { mLocationManager.removeUpdates(mGoogleLocationListener); notifyLocationChanged("not get location in 5000ms", null); } } }, 5000); } private boolean isProviderEnable(String provider) { boolean isOpen = true; if (!mLocationManager.isProviderEnabled(provider)) {//没有开启GPS isOpen = false; } return isOpen; } private CtrlTaskV2 mGetAddressTask = null;//替换你自己的异步任务操作 private void getAddress(@Nullable final Location location) { if (location == null) { LogUtil.e(TAG, "getAddress(): location = null"); return; } if (mGetAddressTask != null) { mGetAddressTask.cancel(true); mGetAddressTask = null; } mGetAddressTask = new CtrlTaskV2("getAddress", new CtrlTaskV2.ICtrlWork() { @Override public CtrlResult doWork() { try { List<Address> addresses = mGeocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); if (addresses != null && !addresses.isEmpty()) { final Address address = addresses.get(0); if (address != null) { KKLocation kkLocation = new KKLocation(); if (!TextUtils.isEmpty(address.getAdminArea())) { kkLocation.setProvince(address.getAdminArea()); } if (!TextUtils.isEmpty(address.getLocality())) { kkLocation.setCity(address.getLocality()); } if (!TextUtils.isEmpty(address.getSubLocality())) { kkLocation.setDistrict(address.getSubLocality()); } notifyLocationChanged(null, kkLocation); } else { LogUtil.e(TAG, "获取到的地理位置信息为 null !"); notifyLocationChanged("定位失败", null); } } else { LogUtil.e(TAG, "根据经纬度未找到相应位置信息"); notifyLocationChanged("定位失败", null); } } catch (IOException e) { LogUtil.e(TAG, "地理反编码IO异常!", e); notifyLocationChanged("定位失败", null); } return null; } }); mGetAddressTask.exec(); } private void notifyLocationChanged(final String errMessage, final KKLocation location) { callBackInvoked = true; UIThread.uiPost(new Runnable() { @Override public void run() { if (getLocationListener() != null) { if (!TextUtils.isEmpty(errMessage)) { getLocationListener().onLocateFailed(errMessage); } else if (location != null) { getLocationListener().onLocateSuccess(location); } } } }); } public static class KKLocation implements Serializable { private static final long serialVersionUID = 1L; private String province; private String city; private String district; public synchronized String getProvince() { return province; } public synchronized void setProvince(String province) { this.province = province; } public synchronized String getCity() { return city; } public synchronized void setCity(String city) { this.city = city; } public synchronized String getDistrict() { return district; } public synchronized void setDistrict(String district) { this.district = district; } @Override public String toString() { return "KKLocation{" + "province='" + province + '\'' + ", city='" + city + '\'' + ", district='" + district + '\'' + '}'; } } }