10
10
import android .os .Bundle ;
11
11
import android .support .v4 .app .ActivityCompat ;
12
12
import android .support .v4 .content .ContextCompat ;
13
+ import android .util .Log ;
13
14
14
15
import java .util .List ;
15
16
import java .util .concurrent .CopyOnWriteArrayList ;
19
20
public class LocationServiceManager implements LocationListener {
20
21
public static final int LOCATION_REQUEST = 1 ;
21
22
22
- private static final long MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 2 * 60 * 1000 ;
23
+ // Maybe these values can be improved for efficiency
24
+ private static final long MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 2 * 60 * 100 ;
23
25
private static final long MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS = 10 ;
24
26
25
27
private Context context ;
@@ -120,12 +122,14 @@ private boolean requestLocationUpdatesFromProvider(String locationProvider) {
120
122
*
121
123
* @param location the location to be tested
122
124
* @param currentBestLocation the current best location
123
- * @return true if the given location is better
125
+ * @return LOCATION_SIGNIFICANTLY_CHANGED if location changed significantly
126
+ * LOCATION_SLIGHTLY_CHANGED if location changed slightly
124
127
*/
125
- protected boolean isBetterLocation (Location location , Location currentBestLocation ) {
128
+ protected LocationChangeType isBetterLocation (Location location , Location currentBestLocation ) {
129
+
126
130
if (currentBestLocation == null ) {
127
131
// A new location is always better than no location
128
- return true ;
132
+ return LocationChangeType . LOCATION_SIGNIFICANTLY_CHANGED ;
129
133
}
130
134
131
135
// Check whether the new location fix is newer or older
@@ -134,15 +138,6 @@ protected boolean isBetterLocation(Location location, Location currentBestLocati
134
138
boolean isSignificantlyOlder = timeDelta < -MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS ;
135
139
boolean isNewer = timeDelta > 0 ;
136
140
137
- // If it's been more than two minutes since the current location, use the new location
138
- // because the user has likely moved
139
- if (isSignificantlyNewer ) {
140
- return true ;
141
- // If the new location is more than two minutes older, it must be worse
142
- } else if (isSignificantlyOlder ) {
143
- return false ;
144
- }
145
-
146
141
// Check whether the new location fix is more or less accurate
147
142
int accuracyDelta = (int ) (location .getAccuracy () - currentBestLocation .getAccuracy ());
148
143
boolean isLessAccurate = accuracyDelta > 0 ;
@@ -153,15 +148,28 @@ protected boolean isBetterLocation(Location location, Location currentBestLocati
153
148
boolean isFromSameProvider = isSameProvider (location .getProvider (),
154
149
currentBestLocation .getProvider ());
155
150
156
- // Determine location quality using a combination of timeliness and accuracy
157
- if (isMoreAccurate ) {
158
- return true ;
159
- } else if (isNewer && !isLessAccurate ) {
160
- return true ;
161
- } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider ) {
162
- return true ;
151
+ float [] results = new float [5 ];
152
+ Location .distanceBetween (
153
+ currentBestLocation .getLatitude (),
154
+ currentBestLocation .getLongitude (),
155
+ location .getLatitude (),
156
+ location .getLongitude (),
157
+ results );
158
+
159
+ // If it's been more than two minutes since the current location, use the new location
160
+ // because the user has likely moved
161
+ if (isSignificantlyNewer
162
+ || isMoreAccurate
163
+ || (isNewer && !isLessAccurate )
164
+ || (isNewer && !isSignificantlyLessAccurate && isFromSameProvider )) {
165
+ if (results [0 ] < 1000 ) { // Means change is smaller than 1000 meter
166
+ return LocationChangeType .LOCATION_SLIGHTLY_CHANGED ;
167
+ } else {
168
+ return LocationChangeType .LOCATION_SIGNIFICANTLY_CHANGED ;
169
+ }
170
+ } else {
171
+ return LocationChangeType .LOCATION_NOT_CHANGED ;
163
172
}
164
- return false ;
165
173
}
166
174
167
175
/**
@@ -208,12 +216,19 @@ public void removeLocationListener(LocationUpdateListener listener) {
208
216
209
217
@ Override
210
218
public void onLocationChanged (Location location ) {
211
- if (isBetterLocation (location , lastLocation )) {
212
- lastLocation = location ;
213
- for (LocationUpdateListener listener : locationListeners ) {
214
- listener .onLocationChanged (LatLng .from (lastLocation ));
219
+ if (isBetterLocation (location , lastLocation )
220
+ .equals (LocationChangeType .LOCATION_SIGNIFICANTLY_CHANGED )) {
221
+ lastLocation = location ;
222
+ for (LocationUpdateListener listener : locationListeners ) {
223
+ listener .onLocationChangedSignificantly (LatLng .from (lastLocation ));
224
+ }
225
+ } else if (isBetterLocation (location , lastLocation )
226
+ .equals (LocationChangeType .LOCATION_SLIGHTLY_CHANGED )) {
227
+ lastLocation = location ;
228
+ for (LocationUpdateListener listener : locationListeners ) {
229
+ listener .onLocationChangedSlightly (LatLng .from (lastLocation ));
230
+ }
215
231
}
216
- }
217
232
}
218
233
219
234
@ Override
@@ -230,4 +245,10 @@ public void onProviderEnabled(String provider) {
230
245
public void onProviderDisabled (String provider ) {
231
246
Timber .d ("Provider %s disabled" , provider );
232
247
}
248
+
249
+ public enum LocationChangeType {
250
+ LOCATION_SIGNIFICANTLY_CHANGED , //Went out of borders of nearby markers
251
+ LOCATION_SLIGHTLY_CHANGED , //User might be walking or driving
252
+ LOCATION_NOT_CHANGED
253
+ }
233
254
}
0 commit comments