android 定位更新 (Google LocationRequest)

对于定位,首先要先认识下定位地理坐标体系:

Android 定位地理坐标体系

还有Android API 定位:

Android GPS 取经纬度

 

认识完了坐标体系后,我们再进行定位:

明确说明在8.0以后,后台对获取位置的时间做了限制,一个小时内只能获取几次,所有需要在后台使用服务需要注意。

Google Android document

 

(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 }

 

以上两种方式是Google提供的位置服务:

The getLastLocation() method returns a Task that you can use to get a Location object with the latitude and longitude coordinates of a geographic location. The location object may be null in the following situations:

  • Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache.
  • The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings.
  • Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.

因为是获取上一次定位的信息,所以location在以下几种情况会返回null

  1. 在定位服务被关闭的时候,因为关闭后会清除上次的定位信息
  2. 设备从未记录其位置,可能是新设备或已恢复出厂设置的设备
  3. 设备不支持Google Play服务
  4. 设备上的Google Play服务已重新启动。

 

(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 }

 

android-play-location

posted @ 2018-01-29 11:46  晕菜一员  阅读(12167)  评论(0编辑  收藏  举报