对于定位,首先要先认识下定位地理坐标体系:
认识完了坐标体系后,我们再进行定位:
(1)FusedLocationProviderClient LocationRequest
LocationServices.getFusedLocationProviderClient(Context)
.requestLocationUpdates(LocationRequest, LocationCallback, Looper.myLooper());
1]创建 LocationRequest;
2]创建 FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
3]创建 LocationSettingsRequest, 传入创建好的LocationRequest;
4] 创建 SettingsClient, 检查定位设置是否满足可用;
5]请求 requestLocationUpdates 定位更新;
1 package com.demo.utils.location; 2 3 import android.app.Activity; 4 import android.content.Context; 5 import android.content.IntentSender; 6 import android.location.Location; 7 import android.os.Bundle; 8 import android.os.Looper; 9 import android.support.annotation.NonNull; 10 import android.support.annotation.Nullable; 11 import android.util.Log; 12 import android.widget.Toast; 13 14 import com.google.android.gms.common.ConnectionResult; 15 import com.google.android.gms.common.api.ApiException; 16 import com.google.android.gms.common.api.GoogleApiClient; 17 import com.google.android.gms.common.api.ResolvableApiException; 18 import com.google.android.gms.location.FusedLocationProviderClient; 19 import com.google.android.gms.location.LocationCallback; 20 import com.google.android.gms.location.LocationRequest; 21 import com.google.android.gms.location.LocationResult; 22 import com.google.android.gms.location.LocationServices; 23 import com.google.android.gms.location.LocationSettingsRequest; 24 import com.google.android.gms.location.LocationSettingsResponse; 25 import com.google.android.gms.location.LocationSettingsStatusCodes; 26 import com.google.android.gms.location.SettingsClient; 27 import com.google.android.gms.maps.model.LatLng; 28 import com.google.android.gms.tasks.OnFailureListener; 29 import com.google.android.gms.tasks.OnSuccessListener; 30 31 /** 32 * class: 33 * <p> 34 * 35 * @author charles 36 * created at 17/12/7 37 * @Desciption 38 */ 39 40 public class FusedLocationUtil { 41 42 public static final int REQUEST_CHECK_SETTINGS = 10; 43 44 private GoogleApiClient mGoogleApiClient; 45 private LocationRequest mLocationRequest; 46 private CLocationCallBack mLocationCallBack; 47 private FusedLocationProviderClient mFusedLocationClient; 48 49 private long UPDATE_INTERVAL = 2000; /* 10 secs */ 50 private long FASTEST_INTERVAL = 1000; /* 2 sec */ 51 52 protected FusedLocationUtils() { 53 initGoogleApiClient(); 54 // Create the location request to start receiving updates 55 mLocationRequest = new LocationRequest(); 56 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 57 mLocationRequest.setInterval(UPDATE_INTERVAL); 58 mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 59 } 60 61 private void initGoogleApiClient() { 62 mGoogleApiClient = new GoogleApiClient.Builder(AppManager.getInstance()) 63 .addOnConnectionFailedListener(connectionFailedListener) 64 .addConnectionCallbacks(connectionCallbacks) 65 .addApi(LocationServices.API) 66 .build(); 67 } 68 69 //连接google服务失败监听器 70 private GoogleApiClient.OnConnectionFailedListener connectionFailedListener = 71 new GoogleApiClient.OnConnectionFailedListener() { 72 @Override 73 public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 74 75 int errorCode = connectionResult.getErrorCode(); 76 // 裝置沒有安裝Google Play服務 77 if (errorCode == ConnectionResult.SERVICE_MISSING) { 78 Toast.makeText(DemoApplication.getInstance(), "Google play service missing", Toast.LENGTH_LONG).show(); 79 } 80 81 if (mLocationCallBack != null) { 82 mLocationCallBack.onLatLngResult(new LatLng(0, 0)); 83 mLocationCallBack.onLocationChange(null, true); 84 } 85 } 86 }; 87 88 //连接google服务成功监听器 89 private GoogleApiClient.ConnectionCallbacks connectionCallbacks = 90 new GoogleApiClient.ConnectionCallbacks() { 91 @Override 92 public void onConnected(@Nullable Bundle bundle) { 93 94 } 95 96 @Override 97 public void onConnectionSuspended(int status) { 98 99 } 100 }; 101 102 public void requestLocationUpdate(final Context context, CLocationCallBack callBack) { 103 104 mLocationCallBack = callBack; 105 if (mFusedLocationClient == null) { 106 107 if (context instanceof Activity) { 108 mFusedLocationClient = LocationServices.getFusedLocationProviderClient(((Activity) context)); 109 } else { 110 mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context); 111 } 112 113 // Create LocationSettingsRequest object using location request 114 LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); 115 builder.addLocationRequest(mLocationRequest); 116 LocationSettingsRequest locationSettingsRequest = builder.build(); 117 118 // Check whether location settings are satisfied 119 // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient 120 SettingsClient settingsClient; 121 122 if (context instanceof Activity) { 123 settingsClient = LocationServices.getSettingsClient(((Activity) context)); 124 } else { 125 settingsClient = LocationServices.getSettingsClient(context); 126 } 127 128 settingsClient.checkLocationSettings(locationSettingsRequest) 129 .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() { 130 @Override 131 public void onSuccess(LocationSettingsResponse locationSettingsResponse) { 132 133 android.util.Log.e("checkLocationSettings", "==onSuccess"); 134 135 startLocationUpdates(); 136 } 137 }) 138 .addOnFailureListener(new OnFailureListener() { 139 @Override 140 public void onFailure(@NonNull Exception e) { 141 int statusCode = ((ApiException) e).getStatusCode(); 142 switch (statusCode) { 143 case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: 144 Log.i("FusedLocationUtils", "Location settings are not satisfied. Attempting to upgrade " + 145 "location settings "); 146 if (context instanceof Activity) { 147 try { 148 // Show the dialog by calling startResolutionForResult(), and check the 149 // result in onActivityResult(). 150 ResolvableApiException rae = (ResolvableApiException) e; 151 rae.startResolutionForResult(((Activity) context), REQUEST_CHECK_SETTINGS); 152 } catch (IntentSender.SendIntentException sie) { 153 Log.i("FusedLocationUtils", "PendingIntent unable to execute request."); 154 } 155 } 156 break; 157 case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: 158 159 String errorMessage = "Location settings are inadequate, and cannot be " + 160 "fixed here. Fix in Settings."; 161 Log.e("FusedLocationUtils", errorMessage); 162 if (context instanceof Activity) { 163 Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show(); 164 } 165 } 166 } 167 }); 168 } 169 170 if (mGoogleApiClient.isConnected()) { 171 // new Google API SDK v11 uses getFusedLocationProviderClient(this) 172 mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, 173 Looper.myLooper()); 174 return; 175 } 176 177 if (mGoogleApiClient.isConnecting()) 178 return; 179 mGoogleApiClient.connect(); 180 } 181 182 // Trigger new location updates at interval 183 public void startLocationUpdates() { 184 185 if (mFusedLocationClient != null) { 186 mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, 187 Looper.myLooper()); 188 } 189 190 } 191 192 private LocationCallback mLocationCallback = new LocationCallback() { 193 @Override 194 public void onLocationResult(LocationResult locationResult) { 195 196 android.util.Log.e("FusedLocationUtils", "onLocationResult"); 197 198 if (locationResult == null || locationResult.getLastLocation() == null) { 199 return; 200 } 201 202 Location lastLocation = locationResult.getLastLocation(); 203 204 android.util.Log.e("onLocationResult", "==locationResult:" + lastLocation.toString()); 205 206 if (mLocationCallBack != null) { 207 mLocationCallBack.onLatLngResult(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude())); 208 mLocationCallBack.onLocationChange(lastLocation, true); 209 } 210 } 211 }; 212 213 public void stopLocation() { 214 if (mFusedLocationClient != null) { 215 mFusedLocationClient.removeLocationUpdates(mLocationCallback); 216 } 217 } 218 219 public void recycleResource() { 220 if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting()) 221 mGoogleApiClient.disconnect(); 222 if (mFusedLocationClient != null) { 223 mFusedLocationClient = null; 224 } 225 mLocationCallBack = null; 226 } 227 228 }
(2)FusedLocationApi LocationRequest
LocationServices.FusedLocationApi.requestLocationUpdates(LocationRequest)
1]初始化 GoogleApiClient;
2]创建LocationRequest;
3]外部调用传入定位回调时,连接google服务;
4]GoogleApiClient.ConnectionCallbacks 回调,表明连接google服务成功,连接成功后,开始定位请求;
5]GoogleApiClient.OnConnectionFailedListener 回调,表明连接google服务失败,可在此回调进行相对应的提示;
1 package com.demo.utils.location; 2 3 import android.location.Location; 4 import android.os.Bundle; 5 import android.support.annotation.NonNull; 6 import android.support.annotation.Nullable; 7 import android.widget.Toast; 8 9 import com.google.android.gms.common.ConnectionResult; 10 import com.google.android.gms.common.api.GoogleApiClient; 11 import com.google.android.gms.location.LocationListener; 12 import com.google.android.gms.location.LocationRequest; 13 import com.google.android.gms.location.LocationServices; 14 import com.google.android.gms.maps.model.LatLng; 15 16 /** 17 * Created by Charles on 17/6/30. 18 */ 19 20 public class GoogleLocationUtil { 21 22 private GoogleApiClient mGoogleApiClient; 23 private LocationRequest mLocationRequest; 24 private CLocationCallBack mLocationCallBack; 25 26 protected GoogleLocationUtils() { 27 initGoogleApiClient(); 28 createLocationRequest(); 29 } 30 31 private void initGoogleApiClient() { 32 mGoogleApiClient = new GoogleApiClient.Builder(DemoApplication.getInstance()) 33 .addOnConnectionFailedListener(connectionFailedListener) 34 .addConnectionCallbacks(connectionCallbacks) 35 .addApi(LocationServices.API) 36 .build(); 37 } 38 39 private void createLocationRequest() { 40 mLocationRequest = LocationRequest.create(); 41 mLocationRequest.setInterval(2000); 42 mLocationRequest.setFastestInterval(1000); 43 mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 44 } 45 46 //连接google服务失败监听器 47 private GoogleApiClient.OnConnectionFailedListener connectionFailedListener = 48 new GoogleApiClient.OnConnectionFailedListener() { 49 @Override 50 public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 51 52 int errorCode = connectionResult.getErrorCode(); 53 // 裝置沒有安裝Google Play服務 54 if (errorCode == ConnectionResult.SERVICE_MISSING) { 55 Toast.makeText(DemoApplication.getInstance(), "Google play service missing", Toast.LENGTH_LONG).show(); 56 } 57 58 if (mLocationCallBack != null) { 59 mLocationCallBack.onLatLngResult(new LatLng(0, 0)); 60 mLocationCallBack.onLocationChange(null, true); 61 } 62 } 63 }; 64 65 //连接google服务成功监听器 66 private GoogleApiClient.ConnectionCallbacks connectionCallbacks = 67 new GoogleApiClient.ConnectionCallbacks() { 68 @Override 69 public void onConnected(@Nullable Bundle bundle) { 70 startLocationUpdate(); 71 } 72 73 @Override 74 public void onConnectionSuspended(int status) { 75 if (mLocationCallBack != null) { 76 mLocationCallBack.onLatLngResult(new LatLng(0, 0)); 77 mLocationCallBack.onLocationChange(null, true); 78 } 79 } 80 }; 81 82 private LocationListener locationListener = new LocationListener() { 83 @Override 84 public void onLocationChanged(Location location) { 85 Log.e("onLocationChanged", "Google location is:", location.toString()); 86 if (mLocationCallBack != null) { 87 mLocationCallBack.onLatLngResult(new LatLng(location.getLatitude(), location.getLongitude())); 88 mLocationCallBack.onLocationChange(location, true); 89 } 90 } 91 }; 92 93 private void startLocationUpdate() { 94 if (!mGoogleApiClient.isConnected()) 95 return; 96 97 Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 98 99 if (lastLocation != null) { 100 Log.e("startLocationUpdate", "== the last google location is:", lastLocation.toString()); 101 if (mLocationCallBack != null) { 102 mLocationCallBack.onLatLngResult(new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude())); 103 mLocationCallBack.onLocationChange(lastLocation, false); 104 } 105 } 106 107 LocationServices.FusedLocationApi.requestLocationUpdates( 108 mGoogleApiClient, mLocationRequest, locationListener); 109 } 110 111 public void requestLocationUpdate() { 112 113 if (mGoogleApiClient == null || mLocationRequest == null || locationListener == null) { 114 return; 115 } 116 117 if (!mGoogleApiClient.isConnected()) 118 return; 119 120 LocationServices.FusedLocationApi.requestLocationUpdates( 121 mGoogleApiClient, mLocationRequest, locationListener); 122 } 123 124 public void requestLocation(CLocationCallBack locationCallBack) { 125 this.mLocationCallBack = locationCallBack; 126 if (mGoogleApiClient.isConnected()) { 127 LocationServices.FusedLocationApi.requestLocationUpdates 128 (mGoogleApiClient, mLocationRequest, locationListener); 129 return; 130 } 131 if (mGoogleApiClient.isConnecting()) 132 return; 133 mGoogleApiClient.connect(); 134 } 135 136 public void stopUpdate() { 137 if (mGoogleApiClient.isConnected()) 138 LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListener); 139 } 140 141 public void stopLocation() { 142 if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting()) 143 mGoogleApiClient.disconnect(); 144 145 mLocationCallBack = null; 146 } 147 148 public boolean isConnected() { 149 return mGoogleApiClient != null && mGoogleApiClient.isConnected(); 150 } 151 152 }
(3)高德定位:
1] 在AndroidManifest 中,<application>节点中,添加如下代码:
1 <meta-data android:name="com.amap.api.v2.apikey" android:value="your key" /> 2 3 <service android:name="com.amap.api.location.APSService"></service>
2] 使用;
1 public class AMapLocationUtil implements AMapLocationListener { 2 3 protected AMapLocationUtil() { 4 mlocationClient = new AMapLocationClient(AppManager.getInstance()); 5 //初始化定位参数 6 mLocationOption = new AMapLocationClientOption(); 7 //设置定位监听 8 mlocationClient.setLocationListener(this); 9 //设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式 10 mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); 11 //设置定位间隔,单位毫秒,默认为2000ms 12 mLocationOption.setInterval(2000); 13 mLocationOption.setNeedAddress(false); 14 mLocationOption.setMockEnable(false); 15 //设置定位参数 16 mlocationClient.setLocationOption(mLocationOption); 17 18 mLastLocation = new Location(""); 19 } 20 21 //声明mlocationClient对象 22 private AMapLocationClient mlocationClient; 23 //声明mLocationOption对象 24 private AMapLocationClientOption mLocationOption = null; 25 private CLocationCallBack mLocationCallBack; 26 private Location mLastLocation; 27 28 public void requestLocationUpdate(CLocationCallBack callBack) { 29 mLocationCallBack = callBack; 30 31 // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗, 32 // 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求 33 // 在定位结束后,在合适的生命周期调用onDestroy()方法 34 // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除 35 //启动定位 36 mlocationClient.startLocation(); 37 } 38 39 public void startLocation() { 40 mlocationClient.startLocation(); 41 } 42 43 @Override 44 public void onLocationChanged(AMapLocation aMapLocation) { 45 if (aMapLocation != null) { 46 if (aMapLocation.getErrorCode() == 0) { 47 //定位成功回调信息,设置相关消息 48 aMapLocation.getLatitude();//获取纬度 49 aMapLocation.getLongitude();//获取经度 50 51 double[] wgs84 = JZLocationConverter.gcj02ToWgs84(aMapLocation.getLatitude(), aMapLocation.getLongitude()); 52 53 mLastLocation.setLatitude(wgs84[0]); 54 mLastLocation.setLongitude(wgs84[1]); 55 56 android.util.Log.e("AMapLocationUtil", "onLocationChanged:" + mLastLocation.toString()); 57 58 if (mLocationCallBack != null) { 59 mLocationCallBack.onLatLngResult(new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude())); 60 mLocationCallBack.onLocationChange(mLastLocation, false); 61 } 62 63 } else { 64 //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。 65 android.util.Log.e("AmapError", "location Error, ErrCode:" 66 + aMapLocation.getErrorCode() + ", errInfo:" 67 + aMapLocation.getErrorInfo()); 68 } 69 } 70 } 71 72 public void stopLocation() { 73 if (mlocationClient != null) { 74 mlocationClient.stopLocation(); 75 } 76 } 77 78 public void recycleResource() { 79 mLocationCallBack = null; 80 if (mlocationClient != null) { 81 mlocationClient.unRegisterLocationListener(this); 82 mlocationClient.onDestroy(); 83 } 84 } 85 86 }
统一的对外回调:
1 public interface CLocationCallBack { 2 3 void onLocationChange(Location location, boolean isStopUpdate); 4 5 void onLatLngResult(LatLng latLng); 6 7 }