io.appium.settings 3.5.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -120,6 +120,10 @@ $ adb shell am broadcast -a io.appium.settings.location -n io.appium.settings/.r
120
120
 
121
121
  The first value in the returned `data` string is the current latitude, the second is the longitude and the last one is the altitude. An empty string is returned if the data cannot be retrieved (more details on the failure cause can be found in the logcat output).
122
122
 
123
+ Since version 3.6.0 it is also possible to provide `forceUpdate` boolean argument. If it is set to
124
+ `true` then location update request is going to be send asynchronously every time when the
125
+ current location is requested. By default the cached location value is returned instead.
126
+
123
127
  ## Setting Mock Locations
124
128
 
125
129
  Start sending scheduled updates (every 2s) for mock location with the specified values by executing:
Binary file
package/app/build.gradle CHANGED
@@ -1,13 +1,13 @@
1
1
  apply plugin: 'com.android.application'
2
2
 
3
3
  android {
4
- compileSdkVersion 29
4
+ compileSdkVersion 30
5
5
 
6
6
  defaultConfig {
7
7
  minSdkVersion 18
8
- targetSdkVersion 29
9
- versionCode 31
10
- versionName "3.5.0"
8
+ targetSdkVersion 30
9
+ versionCode 32
10
+ versionName "3.6.0"
11
11
  applicationId "io.appium.settings"
12
12
  }
13
13
 
@@ -27,7 +27,7 @@ android {
27
27
  }
28
28
 
29
29
  dependencies {
30
- implementation 'com.google.android.gms:play-services-location:16.0.0'
30
+ implementation 'com.google.android.gms:play-services-location:19.0.0'
31
31
  }
32
32
 
33
33
  static def renameAPK(variant) {
@@ -16,6 +16,7 @@
16
16
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
17
17
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
18
18
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
19
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
19
20
  <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
20
21
  tools:ignore="MockLocation,ProtectedPermissions" />
21
22
  <uses-permission android:name="android.permission.SET_ANIMATION_SCALE"
@@ -52,9 +52,11 @@ public class ForegroundService extends Service {
52
52
  private void startForegroundService() {
53
53
  startForeground(NotificationHelpers.APPIUM_NOTIFICATION_IDENTIFIER,
54
54
  NotificationHelpers.getNotification(this));
55
+ LocationTracker.getInstance().start(this);
55
56
  }
56
57
 
57
58
  private void stopForegroundService() {
59
+ LocationTracker.getInstance().stop();
58
60
  stopForeground(true);
59
61
  stopSelf();
60
62
  }
@@ -27,7 +27,8 @@ import android.os.Build;
27
27
  import android.os.IBinder;
28
28
  import android.util.Log;
29
29
 
30
- import com.google.android.gms.common.api.GoogleApiClient;
30
+ import androidx.annotation.Nullable;
31
+
31
32
  import com.google.android.gms.location.FusedLocationProviderClient;
32
33
  import com.google.android.gms.location.LocationServices;
33
34
 
@@ -181,9 +182,10 @@ public class LocationService extends Service {
181
182
  return mockProviders;
182
183
  }
183
184
 
185
+ @Nullable
184
186
  private MockLocationProvider createLocationManagerMockProvider(LocationManager locationManager, String providerName) {
185
187
  LocationProvider provider = locationManager.getProvider(providerName);
186
- return createLocationManagerMockProvider(locationManager, provider);
188
+ return provider == null ? null : createLocationManagerMockProvider(locationManager, provider);
187
189
  }
188
190
 
189
191
  private MockLocationProvider createLocationManagerMockProvider(LocationManager locationManager, LocationProvider locationProvider) {
@@ -201,11 +203,8 @@ public class LocationService extends Service {
201
203
  }
202
204
 
203
205
  private FusedLocationProvider createFusedLocationProvider() {
204
- GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
205
- .addApi(LocationServices.API)
206
- .build();
207
206
  FusedLocationProviderClient locationProviderClient = LocationServices.getFusedLocationProviderClient(this);
208
- return new FusedLocationProvider(googleApiClient, locationProviderClient, this);
207
+ return new FusedLocationProvider(locationProviderClient, this);
209
208
  }
210
209
 
211
210
  private void finishForegroundSetup() {
@@ -20,32 +20,44 @@ import android.content.Context;
20
20
  import android.location.Location;
21
21
  import android.location.LocationListener;
22
22
  import android.location.LocationManager;
23
+ import android.os.Build;
23
24
  import android.os.Bundle;
24
- import android.support.annotation.NonNull;
25
- import android.support.annotation.Nullable;
25
+ import android.os.Looper;
26
26
  import android.util.Log;
27
27
 
28
- import com.google.android.gms.common.ConnectionResult;
29
- import com.google.android.gms.common.api.GoogleApiClient;
28
+ import com.google.android.gms.location.FusedLocationProviderClient;
29
+ import com.google.android.gms.location.LocationCallback;
30
30
  import com.google.android.gms.location.LocationRequest;
31
+ import com.google.android.gms.location.LocationResult;
31
32
  import com.google.android.gms.location.LocationServices;
33
+ import com.google.android.gms.tasks.CancellationTokenSource;
32
34
 
33
35
  import io.appium.settings.helpers.PlayServicesHelpers;
34
36
 
35
37
  import static android.content.Context.LOCATION_SERVICE;
36
38
 
37
- public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
38
- GoogleApiClient.OnConnectionFailedListener,
39
- com.google.android.gms.location.LocationListener, LocationListener {
39
+ import androidx.annotation.NonNull;
40
+ import androidx.annotation.Nullable;
41
+
42
+ import java.util.concurrent.atomic.AtomicBoolean;
43
+
44
+ public class LocationTracker implements LocationListener {
40
45
  private static final String TAG = LocationTracker.class.getSimpleName();
41
- private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
42
- private static final long LOCATION_UPDATES_INTERVAL = 1000 * 60; // 1 minute
43
- private static final long FAST_INTERVAL = 5000; // 5 seconds
46
+ private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 1 meter
47
+ private static final long LOCATION_UPDATES_INTERVAL_MS = 1000 * 60; // 1 minute
48
+ private static final long FAST_INTERVAL_MS = 5000;
44
49
 
45
50
  private volatile LocationManager mLocationManager;
46
- private volatile GoogleApiClient mGoogleApiClient;
51
+ private volatile FusedLocationProviderClient mFusedLocationProviderClient;
52
+ private final LocationCallback locationCallback = new LocationCallback() {
53
+ @Override
54
+ public void onLocationResult(@NonNull LocationResult locationResult) {
55
+ Log.d(TAG, "Got a location update from Play Services");
56
+ mLocation = locationResult.getLastLocation();
57
+ }
58
+ };
47
59
  private volatile Location mLocation;
48
- private volatile boolean isStarted = false;
60
+ private final AtomicBoolean isStarted = new AtomicBoolean(false);
49
61
  private String mLocationProvider;
50
62
 
51
63
  private static LocationTracker instance = null;
@@ -60,96 +72,84 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
60
72
  return instance;
61
73
  }
62
74
 
63
- @Override
64
- public void onLocationChanged(Location location) {
65
- if (location != null) {
66
- Log.d(TAG, "Got an updated location");
67
- mLocation = location;
68
- }
75
+ public boolean isRunning() {
76
+ return isStarted.get();
69
77
  }
70
78
 
71
- @Override
72
- public void onProviderDisabled(String provider) {
79
+ private void setIsRunning(boolean value) {
80
+ isStarted.set(value);
73
81
  }
74
82
 
75
83
  @Override
76
- public void onProviderEnabled(String provider) {
77
- }
84
+ public void onLocationChanged(@Nullable Location location) {
85
+ if (location == null) {
86
+ return;
87
+ }
78
88
 
79
- @Override
80
- public void onStatusChanged(String provider, int status, Bundle extras) {
89
+ Log.d(TAG, "Got a location update from Location Manager");
90
+ mLocation = location;
81
91
  }
82
92
 
83
93
  @Override
84
- public void onConnected(@Nullable Bundle bundle) {
85
- if (mGoogleApiClient == null) {
86
- return;
87
- }
88
- if (!mGoogleApiClient.isConnected()) {
89
- // This should never happen, but it's happening on some phones
90
- Log.e(TAG, "Google API is still connecting being inside onConnected callback");
91
- mGoogleApiClient = null;
92
- return;
93
- }
94
- LocationRequest locationRequest = new LocationRequest();
95
- locationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
96
- locationRequest.setInterval(LOCATION_UPDATES_INTERVAL);
97
- locationRequest.setFastestInterval(FAST_INTERVAL);
98
- try {
99
- //noinspection deprecation
100
- LocationServices.FusedLocationApi
101
- .requestLocationUpdates(mGoogleApiClient, locationRequest, this);
102
- Log.d(TAG, "Google Play Services location provider is connected");
103
- return;
104
- } catch (SecurityException e) {
105
- Log.e(TAG, "Appium Settings has no access to location permission", e);
106
- } catch (Exception e) {
107
- Log.e(TAG, "Cannot connect to Google location service", e);
108
- }
109
- stopLocationUpdatesWithPlayServices();
94
+ public void onProviderDisabled(@NonNull String provider) {
110
95
  }
111
96
 
112
97
  @Override
113
- public void onConnectionSuspended(int i) {
98
+ public void onProviderEnabled(@NonNull String provider) {
114
99
  }
115
100
 
116
101
  @Override
117
- public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
118
- if (mGoogleApiClient == null) {
119
- return;
120
- }
121
-
122
- Log.e(TAG, String.format("Google Play Services location provider has failed to connect (code %s)",
123
- connectionResult.toString()));
124
- stopLocationUpdatesWithPlayServices();
102
+ public void onStatusChanged(String provider, int status, Bundle extras) {
125
103
  }
126
104
 
127
105
  synchronized void start(Context context) {
128
- if (isStarted) {
106
+ if (isRunning()) {
129
107
  return;
130
108
  }
131
- isStarted = true;
109
+ setIsRunning(true);
132
110
 
133
- boolean isPlayServicesAvailable = PlayServicesHelpers.isAvailable(context);
134
- if (isPlayServicesAvailable) {
111
+ if (PlayServicesHelpers.isAvailable(context)) {
135
112
  initializePlayServices(context);
136
113
  } else {
137
114
  initializeLocationManager(context);
138
115
  }
139
116
  }
140
117
 
118
+ synchronized void stop() {
119
+ if (!isRunning()) {
120
+ return;
121
+ }
122
+
123
+ try {
124
+ stopLocationUpdatesWithPlayServices();
125
+ stopLocationUpdatesWithoutPlayServices();
126
+ } finally {
127
+ setIsRunning(false);
128
+ }
129
+ }
130
+
141
131
  private void initializePlayServices(Context context) {
142
- if (isPlayServicesConnected()) {
132
+ if (isFusedLocationProviderInitialized()) {
143
133
  return;
144
134
  }
145
135
 
146
136
  Log.d(TAG, "Configuring location provider for Google Play Services");
147
- mGoogleApiClient = new GoogleApiClient.Builder(context)
148
- .addApi(LocationServices.API)
149
- .addConnectionCallbacks(this)
150
- .addOnConnectionFailedListener(this)
151
- .build();
152
- mGoogleApiClient.connect();
137
+ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
138
+ LocationRequest locationRequest = LocationRequest.create()
139
+ .setPriority(LocationRequest.PRIORITY_LOW_POWER)
140
+ .setInterval(LOCATION_UPDATES_INTERVAL_MS)
141
+ .setFastestInterval(FAST_INTERVAL_MS);
142
+ try {
143
+ mFusedLocationProviderClient.requestLocationUpdates(
144
+ locationRequest, locationCallback, Looper.getMainLooper());
145
+ Log.d(TAG, "Google Play Services location provider is connected");
146
+ return;
147
+ } catch (SecurityException e) {
148
+ Log.e(TAG, "Appium Settings has no access to location permission", e);
149
+ } catch (Exception e) {
150
+ Log.e(TAG, "Cannot connect to Google location service", e);
151
+ }
152
+ stopLocationUpdatesWithPlayServices();
153
153
  }
154
154
 
155
155
  private void initializeLocationManager(Context context) {
@@ -168,17 +168,16 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
168
168
  }
169
169
 
170
170
  private void stopLocationUpdatesWithPlayServices() {
171
- if (mGoogleApiClient == null) {
171
+ if (!isFusedLocationProviderInitialized()) {
172
172
  return;
173
173
  }
174
174
 
175
175
  Log.d(TAG, "Stopping Google Play Services location provider");
176
- if (mGoogleApiClient.isConnected()) {
177
- //noinspection deprecation
178
- LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
179
- mGoogleApiClient.disconnect();
176
+ mFusedLocationProviderClient.removeLocationUpdates(locationCallback);
177
+ if (mFusedLocationProviderClient.asGoogleApiClient().isConnected()) {
178
+ mFusedLocationProviderClient.asGoogleApiClient().disconnect();
180
179
  }
181
- mGoogleApiClient = null;
180
+ mFusedLocationProviderClient = null;
182
181
  }
183
182
 
184
183
  private void startLocationUpdatesWithoutPlayServices() {
@@ -199,7 +198,7 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
199
198
  try {
200
199
  mLocationManager.requestLocationUpdates(
201
200
  LocationManager.GPS_PROVIDER,
202
- LOCATION_UPDATES_INTERVAL,
201
+ LOCATION_UPDATES_INTERVAL_MS,
203
202
  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
204
203
  mLocationProvider = LocationManager.GPS_PROVIDER;
205
204
  Log.d(TAG, "GPS location provider is enabled. Getting FINE location");
@@ -211,7 +210,7 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
211
210
  try {
212
211
  mLocationManager.requestLocationUpdates(
213
212
  LocationManager.NETWORK_PROVIDER,
214
- LOCATION_UPDATES_INTERVAL,
213
+ LOCATION_UPDATES_INTERVAL_MS,
215
214
  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
216
215
  mLocationProvider = LocationManager.NETWORK_PROVIDER;
217
216
  Log.d(TAG, "NETWORK location provider is enabled. Getting COARSE location");
@@ -230,8 +229,8 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
230
229
  mLocationManager = null;
231
230
  }
232
231
 
233
- private boolean isPlayServicesConnected() {
234
- return mGoogleApiClient != null && mGoogleApiClient.isConnected();
232
+ private boolean isFusedLocationProviderInitialized() {
233
+ return mFusedLocationProviderClient != null;
235
234
  }
236
235
 
237
236
  private boolean isLocationManagerConnected() {
@@ -239,52 +238,76 @@ public class LocationTracker implements GoogleApiClient.ConnectionCallbacks,
239
238
  }
240
239
 
241
240
  @Nullable
242
- public synchronized Location getLocation(Context context) {
241
+ private Location getCachedLocation() {
243
242
  if (mLocation != null) {
243
+ Log.d(TAG, "The cached location has been successfully retrieved");
244
244
  return mLocation;
245
245
  }
246
+ Log.d(TAG, "The cached location has not been retrieved");
247
+ return null;
248
+ }
246
249
 
247
- // Make sure the service has been started
248
- start(context);
250
+ public synchronized void forceLocationUpdate(Context context) {
251
+ if (!isRunning()) {
252
+ Log.e(TAG, "The location tracker is not running");
253
+ return;
254
+ }
249
255
 
250
- if (isPlayServicesConnected()) {
256
+ if (isFusedLocationProviderInitialized()) {
251
257
  try {
252
- mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
253
- if (mLocation == null) {
254
- // If GPS didn't work, try location manager
255
- if (!isLocationManagerConnected()) {
256
- initializeLocationManager(context);
257
- }
258
- } else {
259
- // Make sure the fallback is removed after play services connection succeeds
260
- if (isLocationManagerConnected()) {
261
- stopLocationUpdatesWithoutPlayServices();
262
- }
263
- return mLocation;
264
- }
258
+ mFusedLocationProviderClient.getCurrentLocation(
259
+ LocationRequest.PRIORITY_HIGH_ACCURACY, new CancellationTokenSource().getToken())
260
+ .addOnCompleteListener(t -> {
261
+ if (t.isSuccessful()) {
262
+ mLocation = t.getResult();
263
+ Log.d(TAG, "The current location has been successfully retrieved from " +
264
+ "Play Services");
265
+ } else {
266
+ Log.w(TAG, "Failed to retrieve the current location from Play Services",
267
+ t.getException());
268
+ }
269
+ });
265
270
  } catch (SecurityException e) {
266
271
  Log.e(TAG, "Appium Settings has no access to location permission", e);
267
272
  }
273
+ } else if (isLocationManagerConnected() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
274
+ try {
275
+ mLocationManager.getCurrentLocation(mLocationProvider, null,
276
+ context.getMainExecutor(), location -> {
277
+ mLocation = location;
278
+ Log.d(TAG, "The current location has been successfully retrieved " +
279
+ "from Location Manager");
280
+ });
281
+ } catch (SecurityException e) {
282
+ Log.e(TAG, "Appium Settings has no access to location permission", e);
283
+ }
284
+ }
285
+ }
286
+
287
+ @Nullable
288
+ public synchronized Location getLocation(Context context) {
289
+ if (!isRunning()) {
290
+ Log.e(TAG, "The location tracker is not running");
291
+ return null;
268
292
  }
269
- if (isLocationManagerConnected() || mGoogleApiClient != null) {
270
- // Try fallback to the default provider if Google API is available but is still not connected
271
- if (mGoogleApiClient != null && !isLocationManagerConnected()) {
272
- Object locationManager = context.getSystemService(LOCATION_SERVICE);
273
- if (locationManager != null) {
274
- mLocationManager = (LocationManager) locationManager;
275
- startLocationUpdatesWithoutPlayServices();
276
- }
293
+
294
+ if (isFusedLocationProviderInitialized()) {
295
+ Location location = getCachedLocation();
296
+ if (location != null) {
297
+ // If Play services worked, make sure location manager is disabled
298
+ stopLocationUpdatesWithoutPlayServices();
299
+ return location;
277
300
  }
278
- if (mLocationManager != null && mLocationProvider != null) {
279
- try {
280
- mLocation = mLocationManager.getLastKnownLocation(mLocationProvider);
281
- return mLocation;
282
- } catch (SecurityException e) {
283
- Log.e(TAG, String.format("Appium Settings has no access to %s location permission",
284
- mLocationProvider), e);
285
- }
301
+ }
302
+
303
+ // If Play services didn't work, try location manager
304
+ try {
305
+ if (!isLocationManagerConnected()) {
306
+ initializeLocationManager(context);
286
307
  }
308
+ } catch (SecurityException e) {
309
+ Log.e(TAG, "Appium Settings has no access to location permission", e);
287
310
  }
288
- return null;
311
+ return isLocationManagerConnected() ? getCachedLocation() : null;
289
312
  }
290
313
  }
@@ -20,8 +20,10 @@ import android.content.Intent;
20
20
  import android.os.IBinder;
21
21
  import android.service.notification.NotificationListenerService;
22
22
  import android.service.notification.StatusBarNotification;
23
- import android.support.annotation.Nullable;
24
23
  import android.util.Log;
24
+
25
+ import androidx.annotation.Nullable;
26
+
25
27
  import io.appium.settings.notifications.StoredNotification;
26
28
  import io.appium.settings.notifications.StoredNotifications;
27
29
 
@@ -49,8 +49,6 @@ public class Settings extends Activity {
49
49
  setContentView(R.layout.main);
50
50
  Log.d(TAG, "Entering the app");
51
51
 
52
- LocationTracker.getInstance().start(this);
53
-
54
52
  registerSettingsReceivers(Arrays.asList(
55
53
  WiFiConnectionSettingReceiver.class,
56
54
  AnimationSettingReceiver.class,
@@ -68,15 +66,13 @@ public class Settings extends Activity {
68
66
  // https://developer.android.com/about/versions/oreo/background-location-limits
69
67
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
70
68
  startForegroundService(ForegroundService.getForegroundServiceIntent(Settings.this));
69
+ } else {
70
+ LocationTracker.getInstance().start(this);
71
71
  }
72
72
 
73
73
  Log.d(TAG, "Closing the app");
74
74
  Handler handler = new Handler();
75
- handler.postDelayed(new Runnable() {
76
- public void run() {
77
- Settings.this.finish();
78
- }
79
- }, 1000);
75
+ handler.postDelayed(Settings.this::finish, 1000);
80
76
  }
81
77
 
82
78
  private void registerSettingsReceivers(List<Class<? extends BroadcastReceiver>> receiverClasses) {
@@ -22,13 +22,14 @@ import android.app.NotificationManager;
22
22
  import android.content.Context;
23
23
  import android.graphics.BitmapFactory;
24
24
  import android.os.Build;
25
- import android.support.annotation.RequiresApi;
26
- import android.support.v4.app.NotificationCompat;
27
25
 
28
26
  import io.appium.settings.R;
29
27
 
30
28
  import static android.content.Context.NOTIFICATION_SERVICE;
31
29
 
30
+ import androidx.annotation.RequiresApi;
31
+ import androidx.core.app.NotificationCompat;
32
+
32
33
  public class NotificationHelpers {
33
34
  public static final int APPIUM_NOTIFICATION_IDENTIFIER = 1;
34
35
  private static final String CHANNEL_ID = "main_channel";
@@ -22,11 +22,12 @@ import android.content.Context;
22
22
  import android.location.Location;
23
23
  import android.util.Log;
24
24
 
25
- import com.google.android.gms.common.api.GoogleApiClient;
26
25
  import com.google.android.gms.location.FusedLocationProviderClient;
27
26
 
28
- import static android.content.pm.PackageManager.PERMISSION_GRANTED;
29
- import static android.support.v4.content.ContextCompat.checkSelfPermission;
27
+ import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED;
28
+ import static androidx.core.content.PermissionChecker.checkSelfPermission;
29
+
30
+ import androidx.annotation.NonNull;
30
31
 
31
32
  public class FusedLocationProvider implements MockLocationProvider {
32
33
 
@@ -34,12 +35,10 @@ public class FusedLocationProvider implements MockLocationProvider {
34
35
 
35
36
  private final static String PROVIDER_NAME = "fused";
36
37
 
37
- private final GoogleApiClient googleApiClient;
38
38
  private final FusedLocationProviderClient fusedLocationProviderClient;
39
39
  private final Context context;
40
40
 
41
- public FusedLocationProvider(GoogleApiClient googleApiClient, FusedLocationProviderClient fusedLocationProviderClient, Context context) {
42
- this.googleApiClient = googleApiClient;
41
+ public FusedLocationProvider(FusedLocationProviderClient fusedLocationProviderClient, Context context) {
43
42
  this.fusedLocationProviderClient = fusedLocationProviderClient;
44
43
  this.context = context;
45
44
  }
@@ -55,7 +54,7 @@ public class FusedLocationProvider implements MockLocationProvider {
55
54
  if (!hasPermissions()) {
56
55
  return;
57
56
  }
58
- if (!googleApiClient.isConnected()) {
57
+ if (!fusedLocationProviderClient.asGoogleApiClient().isConnected()) {
59
58
  Log.d(TAG, "GoogleApiClient is not connected");
60
59
  return;
61
60
  }
@@ -68,7 +67,7 @@ public class FusedLocationProvider implements MockLocationProvider {
68
67
  if (!hasPermissions()) {
69
68
  return;
70
69
  }
71
- googleApiClient.connect();
70
+ fusedLocationProviderClient.asGoogleApiClient().connect();
72
71
  fusedLocationProviderClient.setMockMode(true);
73
72
  }
74
73
 
@@ -79,10 +78,11 @@ public class FusedLocationProvider implements MockLocationProvider {
79
78
  return;
80
79
  }
81
80
  fusedLocationProviderClient.setMockMode(false);
82
- googleApiClient.disconnect();
81
+ fusedLocationProviderClient.asGoogleApiClient().disconnect();
83
82
  }
84
83
 
85
84
  @Override
85
+ @NonNull
86
86
  public String toString() {
87
87
  return "FusedLocationProvider{" +
88
88
  "name='" + PROVIDER_NAME + '\'' +
@@ -19,11 +19,10 @@ package io.appium.settings.location;
19
19
  import android.content.Intent;
20
20
  import android.location.Criteria;
21
21
  import android.location.Location;
22
- import android.os.Build;
23
22
  import android.os.SystemClock;
24
- import android.support.annotation.Nullable;
25
23
  import android.util.Log;
26
24
 
25
+ import androidx.annotation.Nullable;
27
26
 
28
27
  public class LocationBuilder {
29
28
 
@@ -75,9 +74,7 @@ public class LocationBuilder {
75
74
  }
76
75
 
77
76
  location.setTime(System.currentTimeMillis());
78
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
79
- location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
80
- }
77
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
81
78
  return location;
82
79
  }
83
80
  }
@@ -28,8 +28,9 @@ import java.util.Locale;
28
28
  import io.appium.settings.LocationTracker;
29
29
 
30
30
  public class LocationInfoReceiver extends BroadcastReceiver
31
- implements HasAction {
31
+ implements HasAction {
32
32
  private static final String TAG = LocationInfoReceiver.class.getSimpleName();
33
+ private static final String FORCE_UPDATE = "forceUpdate";
33
34
 
34
35
  private static final String ACTION = "io.appium.settings.location";
35
36
 
@@ -41,7 +42,13 @@ public class LocationInfoReceiver extends BroadcastReceiver
41
42
  @Override
42
43
  public void onReceive(Context context, Intent intent) {
43
44
  Log.d(TAG, "Getting current location");
44
- final Location location = LocationTracker.getInstance().getLocation(context);
45
+ LocationTracker tracker = LocationTracker.getInstance();
46
+ if (intent.hasExtra(FORCE_UPDATE)
47
+ && intent.getBooleanExtra(FORCE_UPDATE, false)) {
48
+ Log.d(TAG, "Initiating forced location update");
49
+ tracker.forceLocationUpdate(context);
50
+ }
51
+ final Location location = tracker.getLocation(context);
45
52
  if (location != null) {
46
53
  setResultCode(Activity.RESULT_OK);
47
54
  // Decimal separator is a dot
@@ -22,9 +22,11 @@ import android.content.ComponentName;
22
22
  import android.content.Context;
23
23
  import android.content.Intent;
24
24
  import android.provider.Settings;
25
- import android.support.annotation.Nullable;
26
25
  import android.text.TextUtils;
27
26
  import android.util.Log;
27
+
28
+ import androidx.annotation.Nullable;
29
+
28
30
  import io.appium.settings.notifications.StoredNotifications;
29
31
  import org.json.JSONArray;
30
32
  import org.json.JSONException;
@@ -0,0 +1,15 @@
1
+ ## For more details on how to configure your build environment visit
2
+ # http://www.gradle.org/docs/current/userguide/build_environment.html
3
+ #
4
+ # Specifies the JVM arguments used for the daemon process.
5
+ # The setting is particularly useful for tweaking memory settings.
6
+ # Default value: -Xmx1024m -XX:MaxPermSize=256m
7
+ # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8
+ #
9
+ # When configured, Gradle will run in incubating parallel mode.
10
+ # This option should only be used with decoupled projects. More details, visit
11
+ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12
+ # org.gradle.parallel=true
13
+ #Fri Dec 17 09:25:55 CET 2021
14
+ android.useAndroidX=true
15
+ android.enableJetifier=true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "io.appium.settings",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "description": "App for dealing with Android settings",
5
5
  "main": "index.js",
6
6
  "scripts": {