summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Paczos <lukas.paczos@gmail.com>2018-11-12 17:11:51 +0100
committerŁukasz Paczos <lukasz.paczos@mapbox.com>2018-11-29 19:26:21 +0100
commit216b0d8a936c4d3f3ff221ff3a2bd52f6d4d1964 (patch)
tree89eef40ed7027804709be7faa1a25d3f8c626c23
parent2c70f4b6dc7d9c9c67f7a78e4290335f137392d9 (diff)
downloadqtlocation-mapboxgl-216b0d8a936c4d3f3ff221ff3a2bd52f6d4d1964.tar.gz
[android] refactor LocationComponent to utilize LocationEngineRequest
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java286
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt140
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle1
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java86
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.java117
-rw-r--r--platform/android/build.gradle2
-rw-r--r--platform/android/gradle/dependencies.gradle2
10 files changed, 421 insertions, 224 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
index d0b0bb733d..b2f1206d06 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
@@ -9,6 +9,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import android.support.annotation.StyleRes;
+import android.support.annotation.VisibleForTesting;
import android.view.WindowManager;
import com.mapbox.android.core.location.LocationEngine;
@@ -28,13 +29,13 @@ import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener;
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener;
import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener;
+import java.lang.ref.WeakReference;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_FASTEST_INTERVAL_MILLIS;
+import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_INTERVAL_MILLIS;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_TILT_ANIM_DURATION;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_ZOOM_ANIM_DURATION;
@@ -60,14 +61,23 @@ import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_T
* <p>
* Using this component requires you to request permission beforehand manually or using
* {@link com.mapbox.android.core.permissions.PermissionsManager}. Either
- * {@code ACCESS_COARSE_LOCATION} or {@code ACCESS_FINE_LOCATION} permissions can be requested and
- * this plugin work as expected.
+ * {@code ACCESS_COARSE_LOCATION} or {@code ACCESS_FINE_LOCATION} permissions can be requested for
+ * this component to work as expected.
* <p>
* This component offers a default, built-in {@link LocationEngine} with some of the activation methods.
* This engine will be obtained by {@link LocationEngineProvider#getBestLocationEngine(Context, boolean)} which defaults
- * to the {@link com.mapbox.android.core.location.MapboxFusedLocationEngineImpl}. If you'd like to utilize Google Play Services
+ * to the {@link com.mapbox.android.core.location.MapboxFusedLocationEngineImpl}. If you'd like to utilize Google
+ * Play Services
* for more precise location updates, simply add the Google Play Location Services dependency in your build script.
* This will make the default engine the {@link com.mapbox.android.core.location.GoogleLocationEngineImpl} instead.
+ * After a custom engine is passed to the component, or the built-in is initialized,
+ * the location updates are going to be requested with the {@link LocationEngineRequest}, either a default one,
+ * or the one passed during the activation.
+ * When using any engine, requesting/removing the location updates is going to be managed internally.
+ * <p>
+ * You can also push location updates to the component without any internal engine management.
+ * To achieve that, use {@link #activateLocationComponent(Context, boolean)} with false.
+ * No engine is going to be initialized and you can push location updates with {@link #forceLocationUpdate(Location)}.
* <p>
* For location puck animation purposes, like navigation,
* we recommend limiting the maximum zoom level of the map for the best user experience.
@@ -76,17 +86,26 @@ import static com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_T
*/
public final class LocationComponent {
private static final String TAG = "Mbgl-LocationComponent";
- private static final long DEFAULT_INTERVAL_MILLIS = 1000;
- private static final long DEFAULT_FASTEST_INTERVAL_MILLIS = 1000;
@NonNull
private final MapboxMap mapboxMap;
private LocationComponentOptions options;
+ @NonNull
+ private InternalLocationEngineProvider internalLocationEngineProvider = new InternalLocationEngineProvider();
@Nullable
private LocationEngine locationEngine;
- @Nullable
+ @NonNull
+ private LocationEngineRequest locationEngineRequest =
+ new LocationEngineRequest.Builder(DEFAULT_INTERVAL_MILLIS)
+ .setFastestInterval(DEFAULT_FASTEST_INTERVAL_MILLIS)
+ .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
+ .build();
+ private LocationEngineCallback<LocationEngineResult> currentLocationEngineListener
+ = new CurrentLocationEngineCallback(this);
+ private LocationEngineCallback<LocationEngineResult> lastLocationEngineListener
+ = new LastLocationEngineCallback(this);
+
private CompassEngine compassEngine;
- private boolean usingInternalLocationEngine;
private LocationLayerController locationLayerController;
private LocationCameraController locationCameraController;
@@ -144,6 +163,28 @@ public final class LocationComponent {
this.mapboxMap = mapboxMap;
}
+ @VisibleForTesting
+ LocationComponent(@NonNull MapboxMap mapboxMap,
+ @NonNull LocationEngineCallback<LocationEngineResult> currentlistener,
+ @NonNull LocationEngineCallback<LocationEngineResult> lastListener,
+ @NonNull LocationLayerController locationLayerController,
+ @NonNull LocationCameraController locationCameraController,
+ @NonNull LocationAnimatorCoordinator locationAnimatorCoordinator,
+ @NonNull StaleStateManager staleStateManager,
+ @NonNull CompassEngine compassEngine,
+ @NonNull InternalLocationEngineProvider internalLocationEngineProvider) {
+ this.mapboxMap = mapboxMap;
+ this.currentLocationEngineListener = currentlistener;
+ this.lastLocationEngineListener = lastListener;
+ this.locationLayerController = locationLayerController;
+ this.locationCameraController = locationCameraController;
+ this.locationAnimatorCoordinator = locationAnimatorCoordinator;
+ this.staleStateManager = staleStateManager;
+ this.compassEngine = compassEngine;
+ this.internalLocationEngineProvider = internalLocationEngineProvider;
+ isInitialized = true;
+ }
+
/**
* This method initializes the component and needs to be called before any other operations are performed.
* Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
@@ -154,8 +195,8 @@ public final class LocationComponent {
*/
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void activateLocationComponent(@NonNull Context context) {
- activateLocationComponent(context, LocationComponentOptions.createFromAttributes(context, R.style
- .mapbox_LocationComponent));
+ activateLocationComponent(context,
+ LocationComponentOptions.createFromAttributes(context, R.style.mapbox_LocationComponent));
}
/**
@@ -178,6 +219,26 @@ public final class LocationComponent {
/**
* This method initializes the component and needs to be called before any other operations are performed.
* Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
+ *
+ * @param context the context
+ * @param useDefaultLocationEngine true if you want to initialize and use the built-in location engine or false if
+ * there should be no location engine initialized
+ * @param locationEngineRequest the location request
+ */
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+ public void activateLocationComponent(@NonNull Context context, boolean useDefaultLocationEngine,
+ @NonNull LocationEngineRequest locationEngineRequest) {
+ setLocationEngineRequest(locationEngineRequest);
+ if (useDefaultLocationEngine) {
+ activateLocationComponent(context, R.style.mapbox_LocationComponent);
+ } else {
+ activateLocationComponent(context, null, R.style.mapbox_LocationComponent);
+ }
+ }
+
+ /**
+ * This method initializes the component and needs to be called before any other operations are performed.
+ * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
* <p>
* <strong>Note</strong>: This method will initialize and use an internal {@link LocationEngine} when enabled.
*
@@ -214,6 +275,7 @@ public final class LocationComponent {
* @param locationEngine the engine, or null if you'd like to only force location updates
* @param styleRes the LocationComponent style res
*/
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void activateLocationComponent(@NonNull Context context, @Nullable LocationEngine locationEngine,
@StyleRes int styleRes) {
activateLocationComponent(context, locationEngine,
@@ -221,22 +283,53 @@ public final class LocationComponent {
}
/**
+ * This method initializes the component and needs to be called before any other operations are performed.
+ * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
+ *
+ * @param context the context
+ * @param locationEngine the engine, or null if you'd like to only force location updates
+ * @param locationEngineRequest the location request
+ * @param styleRes the LocationComponent style res
+ */
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+ public void activateLocationComponent(@NonNull Context context, @Nullable LocationEngine locationEngine,
+ @NonNull LocationEngineRequest locationEngineRequest, @StyleRes int styleRes) {
+ activateLocationComponent(context, locationEngine, locationEngineRequest,
+ LocationComponentOptions.createFromAttributes(context, styleRes));
+ }
+
+ /**
* This method will show the location icon and enable the camera tracking the location.
*
* @param context the context
* @param locationEngine the engine
*/
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void activateLocationComponent(@NonNull Context context, @NonNull LocationEngine locationEngine) {
activateLocationComponent(context, locationEngine, R.style.mapbox_LocationComponent);
}
/**
+ * This method will show the location icon and enable the camera tracking the location.
+ *
+ * @param context the context
+ * @param locationEngine the engine
+ * @param locationEngineRequest the location request
+ */
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+ public void activateLocationComponent(@NonNull Context context, @NonNull LocationEngine locationEngine,
+ @NonNull LocationEngineRequest locationEngineRequest) {
+ activateLocationComponent(context, locationEngine, locationEngineRequest, R.style.mapbox_LocationComponent);
+ }
+
+ /**
* This method initializes the component and needs to be called before any other operations are performed.
* Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
*
* @param locationEngine the engine, or null if you'd like to only force location updates
* @param options the options
*/
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void activateLocationComponent(@NonNull Context context, @Nullable LocationEngine locationEngine,
@NonNull LocationComponentOptions options) {
initialize(context, options);
@@ -245,6 +338,24 @@ public final class LocationComponent {
}
/**
+ * This method initializes the component and needs to be called before any other operations are performed.
+ * Afterwards, you can manage component's visibility by {@link #setLocationComponentEnabled(boolean)}.
+ *
+ * @param context the context
+ * @param locationEngine the engine, or null if you'd like to only force location updates
+ * @param locationEngineRequest the location request
+ * @param options the options
+ */
+ public void activateLocationComponent(@NonNull Context context, @Nullable LocationEngine locationEngine,
+ @NonNull LocationEngineRequest locationEngineRequest,
+ @NonNull LocationComponentOptions options) {
+ initialize(context, options);
+ setLocationEngineRequest(locationEngineRequest);
+ setLocationEngine(locationEngine);
+ applyStyle(options);
+ }
+
+ /**
* Manage component's visibility after activation.
*
* @param isEnabled true if the plugin should be visible and listen for location updates, false otherwise.
@@ -491,23 +602,46 @@ public final class LocationComponent {
*
* @param locationEngine a {@link LocationEngine} this component should use to handle updates
*/
+ @SuppressLint("MissingPermission")
public void setLocationEngine(@Nullable LocationEngine locationEngine) {
if (this.locationEngine != null) {
// If internal location engines being used, extra steps need to be taken to deconstruct the
// instance.
- if (usingInternalLocationEngine) {
- usingInternalLocationEngine = false;
- }
- this.locationEngine.removeLocationUpdates(locationEngineListener);
+ this.locationEngine.removeLocationUpdates(currentLocationEngineListener);
this.locationEngine = null;
}
if (locationEngine != null) {
this.locationEngine = locationEngine;
+ if (isLayerReady && isEnabled) {
+ setLastLocation();
+ locationEngine.requestLocationUpdates(
+ locationEngineRequest, currentLocationEngineListener, Looper.getMainLooper());
+ }
}
}
/**
+ * Set the location request that's going to be used when requesting location updates.
+ *
+ * @param locationEngineRequest the location request
+ */
+ public void setLocationEngineRequest(@NonNull LocationEngineRequest locationEngineRequest) {
+ this.locationEngineRequest = locationEngineRequest;
+
+ // reset internal LocationEngine ref to re-request location updates if needed
+ setLocationEngine(locationEngine);
+ }
+
+ /**
+ * Get the location request that's going to be used when requesting location updates.
+ */
+ @NonNull
+ public LocationEngineRequest getLocationEngineRequest() {
+ return locationEngineRequest;
+ }
+
+ /**
* Returns the current {@link LocationEngine} being used for updating the user location.
*
* @return the {@link LocationEngine} being used to update the user location
@@ -546,31 +680,7 @@ public final class LocationComponent {
@Nullable
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public Location getLastKnownLocation() {
- if (locationEngine == null) {
- return null;
- }
- // TODO: decide if we want to change signature of this method, for now make it work as is
- final AtomicReference<LocationEngineResult> resultRef = new AtomicReference<>();
- CountDownLatch latch = new CountDownLatch(1);
- locationEngine.getLastLocation(new LocationEngineCallback<LocationEngineResult>() {
- @Override
- public void onSuccess(LocationEngineResult result) {
- resultRef.set(result);
- latch.countDown();
- }
-
- @Override
- public void onFailure(@NonNull Exception exception) {
- // TODO: log exception
- }
- });
- try {
- latch.await(2, TimeUnit.SECONDS);
- } catch (InterruptedException ie) {
- ie.printStackTrace();
- }
- LocationEngineResult result = resultRef.get();
- return result != null ? result.getLastLocation() : null;
+ return lastLocation;
}
/**
@@ -750,13 +860,11 @@ public final class LocationComponent {
if (isEnabled) {
if (locationEngine != null) {
- if (usingInternalLocationEngine) {
- try {
- locationEngine.requestLocationUpdates(getLocationRequst(DEFAULT_INTERVAL_MILLIS),
- locationEngineListener, Looper.getMainLooper());
- } catch (SecurityException se) {
- se.printStackTrace();
- }
+ try {
+ locationEngine.requestLocationUpdates(
+ locationEngineRequest, currentLocationEngineListener, Looper.getMainLooper());
+ } catch (SecurityException se) {
+ Logger.e(TAG, "Unable to request location updates", se);
}
}
setCameraMode(locationCameraController.getCameraMode());
@@ -776,9 +884,7 @@ public final class LocationComponent {
compassEngine.onStop();
locationAnimatorCoordinator.cancelAllAnimations();
if (locationEngine != null) {
- if (usingInternalLocationEngine) {
- locationEngine.removeLocationUpdates(locationEngineListener);
- }
+ locationEngine.removeLocationUpdates(currentLocationEngineListener);
}
mapboxMap.removeOnCameraMoveListener(onCameraMoveListener);
mapboxMap.removeOnCameraIdleListener(onCameraIdleListener);
@@ -823,17 +929,9 @@ public final class LocationComponent {
private void initializeLocationEngine(@NonNull Context context) {
if (this.locationEngine != null) {
- this.locationEngine.removeLocationUpdates(locationEngineListener);
+ this.locationEngine.removeLocationUpdates(currentLocationEngineListener);
}
- usingInternalLocationEngine = true;
- locationEngine = LocationEngineProvider.getBestLocationEngine(context, false);
- }
-
- private static LocationEngineRequest getLocationRequst(long interval) {
- return new LocationEngineRequest.Builder(interval)
- .setFastestInterval(DEFAULT_FASTEST_INTERVAL_MILLIS)
- .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
- .build();
+ locationEngine = internalLocationEngineProvider.getBestLocationEngine(context, false);
}
private void enableLocationComponent() {
@@ -846,10 +944,13 @@ public final class LocationComponent {
onLocationLayerStop();
}
- private void updateMapWithOptions(final LocationComponentOptions options) {
- mapboxMap.setPadding(
- options.padding()[0], options.padding()[1], options.padding()[2], options.padding()[3]
- );
+ private void updateMapWithOptions(@NonNull LocationComponentOptions options) {
+ int[] padding = options.padding();
+ if (padding != null) {
+ mapboxMap.setPadding(
+ padding[0], padding[1], padding[2], padding[3]
+ );
+ }
}
/**
@@ -894,7 +995,11 @@ public final class LocationComponent {
*/
@SuppressLint("MissingPermission")
private void setLastLocation() {
- updateLocation(getLastKnownLocation(), true);
+ if (locationEngine != null) {
+ locationEngine.getLastLocation(lastLocationEngineListener);
+ } else {
+ updateLocation(getLastKnownLocation(), true);
+ }
}
private void setLastCompassHeading() {
@@ -1005,22 +1110,49 @@ public final class LocationComponent {
}
};
- @NonNull
- private LocationEngineCallback<LocationEngineResult> locationEngineListener =
- new LocationEngineCallback<LocationEngineResult>() {
+ @VisibleForTesting
+ static final class CurrentLocationEngineCallback implements LocationEngineCallback<LocationEngineResult> {
+ private final WeakReference<LocationComponent> componentWeakReference;
+
+ CurrentLocationEngineCallback(LocationComponent component) {
+ this.componentWeakReference = new WeakReference<>(component);
+ }
+
@Override
public void onSuccess(LocationEngineResult result) {
- Location location = result.getLastLocation();
- if (location != null) {
- updateLocation(location, false);
+ LocationComponent component = componentWeakReference.get();
+ if (component != null) {
+ component.updateLocation(result.getLastLocation(), false);
}
}
@Override
public void onFailure(@NonNull Exception exception) {
- // TODO: handle error
+ Logger.e(TAG, "Failed to obtain location update", exception);
+ }
+ }
+
+ @VisibleForTesting
+ static final class LastLocationEngineCallback implements LocationEngineCallback<LocationEngineResult> {
+ private final WeakReference<LocationComponent> componentWeakReference;
+
+ LastLocationEngineCallback(LocationComponent component) {
+ this.componentWeakReference = new WeakReference<>(component);
}
- };
+
+ @Override
+ public void onSuccess(LocationEngineResult result) {
+ LocationComponent component = componentWeakReference.get();
+ if (component != null) {
+ component.updateLocation(result.getLastLocation(), true);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Exception exception) {
+ Logger.e(TAG, "Failed to obtain last location update", exception);
+ }
+ }
@NonNull
private OnCameraTrackingChangedListener cameraTrackingChangedListener = new OnCameraTrackingChangedListener() {
@@ -1040,4 +1172,10 @@ public final class LocationComponent {
}
}
};
+
+ static class InternalLocationEngineProvider {
+ LocationEngine getBestLocationEngine(@NonNull Context context, boolean background) {
+ return LocationEngineProvider.getBestLocationEngine(context, background);
+ }
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
index 4376ef4e60..29fe413a22 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java
@@ -26,6 +26,12 @@ final class LocationComponentConstants {
// Threshold value to perform immediate camera/layer position update.
static final double INSTANT_LOCATION_TRANSITION_THRESHOLD = 500_000;
+ // Default interval between location updates
+ static final long DEFAULT_INTERVAL_MILLIS = 1000;
+
+ // Default fastest acceptable interval between location updates
+ static final long DEFAULT_FASTEST_INTERVAL_MILLIS = 1000;
+
// Sources
static final String LOCATION_SOURCE = "mapbox-location-source";
static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing";
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java
index 25666895aa..db86db925c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java
@@ -187,7 +187,7 @@ public class LocationComponentOptions implements Parcelable {
* @return a new {@link LocationComponentOptions} object with the settings you defined in your style
* resource
*/
- @Nullable
+ @NonNull
public static LocationComponentOptions createFromAttributes(@NonNull Context context,
@StyleRes int styleRes) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
new file mode 100644
index 0000000000..a1c7164d53
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt
@@ -0,0 +1,140 @@
+package com.mapbox.mapboxsdk.location
+
+import android.content.Context
+import android.content.res.Resources
+import android.content.res.TypedArray
+import android.os.Looper
+import com.mapbox.android.core.location.LocationEngine
+import com.mapbox.android.core.location.LocationEngineRequest
+import com.mapbox.mapboxsdk.R
+import com.mapbox.mapboxsdk.maps.MapboxMap
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.*
+import org.mockito.MockitoAnnotations
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class LocationComponentTest {
+ private lateinit var locationComponent: LocationComponent
+
+ @Mock
+ private lateinit var locationComponentOptions: LocationComponentOptions
+
+ @Mock
+ private lateinit var mapboxMap: MapboxMap
+
+ @Mock
+ private lateinit var context: Context
+
+ @Mock
+ private lateinit var locationEngine: LocationEngine
+
+ @Mock
+ private lateinit var locationEngineRequest: LocationEngineRequest
+
+ @Mock
+ private lateinit var currentListener: LocationComponent.CurrentLocationEngineCallback
+
+ @Mock
+ private lateinit var lastListener: LocationComponent.LastLocationEngineCallback
+
+ @Mock
+ private lateinit var compassEngine: CompassEngine
+
+ @Mock
+ private lateinit var locationLayerController: LocationLayerController
+
+ @Mock
+ private lateinit var locationCameraController: LocationCameraController
+
+ @Mock
+ private lateinit var locationAnimatorCoordinator: LocationAnimatorCoordinator
+
+ @Mock
+ private lateinit var staleStateManager: StaleStateManager
+
+ @Mock
+ private lateinit var locationEngineProvider: LocationComponent.InternalLocationEngineProvider
+
+ @Before
+ fun before() {
+ MockitoAnnotations.initMocks(this)
+ locationComponent = LocationComponent(mapboxMap, currentListener, lastListener, locationLayerController, locationCameraController, locationAnimatorCoordinator, staleStateManager, compassEngine, locationEngineProvider)
+ doReturn(locationEngine).`when`(locationEngineProvider).getBestLocationEngine(context, false)
+ }
+
+ @Test
+ fun activateWithRequestTest() {
+ locationComponent.activateLocationComponent(context, locationEngine, locationEngineRequest, locationComponentOptions)
+ Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest)
+
+ doReturn(mock(TypedArray::class.java)).`when`(context)
+ .obtainStyledAttributes(R.style.mapbox_LocationComponent, R.styleable.mapbox_LocationComponent)
+
+ val resources = mock(Resources::class.java)
+
+ doReturn(resources).`when`(context).resources
+ doReturn(0f).`when`(resources)
+ .getDimension(R.dimen.mapbox_locationComponentTrackingMultiFingerMoveThreshold)
+ doReturn(0f).`when`(resources)
+ .getDimension(R.dimen.mapbox_locationComponentTrackingMultiFingerMoveThreshold)
+ locationComponent.activateLocationComponent(context, true, locationEngineRequest)
+ Assert.assertEquals(locationEngineRequest, locationComponent.locationEngineRequest)
+ }
+
+ @Test
+ fun locationUpdatesWhenEnabledDisableTest() {
+ locationComponent.activateLocationComponent(context, locationEngine, locationEngineRequest, locationComponentOptions)
+ verify(locationEngine, times(0)).removeLocationUpdates(currentListener)
+ verify(locationEngine, times(0)).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java))
+
+ locationComponent.onStart()
+ verify(locationEngine, times(0)).removeLocationUpdates(currentListener)
+ verify(locationEngine, times(0)).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java))
+
+ locationComponent.isLocationComponentEnabled = true
+ verify(locationEngine).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java))
+
+ locationComponent.isLocationComponentEnabled = false
+ verify(locationEngine).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java))
+ verify(locationEngine).removeLocationUpdates(currentListener)
+ }
+
+ @Test
+ fun locationUpdatesWhenStartedStoppedTest() {
+ locationComponent.activateLocationComponent(context, locationEngine, locationEngineRequest, locationComponentOptions)
+ locationComponent.onStart()
+ locationComponent.isLocationComponentEnabled = true
+
+ locationComponent.onStop()
+ verify(locationEngine).removeLocationUpdates(currentListener)
+
+ locationComponent.onStart()
+ verify(locationEngine, times(2)).requestLocationUpdates(eq(locationEngineRequest), eq(currentListener), any(Looper::class.java))
+ }
+
+ @Test
+ fun locationUpdatesWhenNewRequestTest() {
+ locationComponent.activateLocationComponent(context, locationEngine, locationEngineRequest, locationComponentOptions)
+ locationComponent.onStart()
+ locationComponent.isLocationComponentEnabled = true
+
+ val newRequest = mock(LocationEngineRequest::class.java)
+ locationComponent.locationEngineRequest = newRequest
+ verify(locationEngine).removeLocationUpdates(currentListener)
+ verify(locationEngine).requestLocationUpdates(eq(newRequest), eq(currentListener), any(Looper::class.java))
+ }
+
+ @Test
+ fun lastLocationUpdateOnStartTest() {
+ locationComponent.activateLocationComponent(context, locationEngine, locationEngineRequest, locationComponentOptions)
+ locationComponent.onStart()
+ locationComponent.isLocationComponentEnabled = true
+
+ verify(locationEngine).getLastLocation(lastListener)
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index 5588db5fc9..384c49eb7f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -65,7 +65,6 @@ dependencies {
implementation dependenciesList.supportDesign
implementation dependenciesList.supportConstraintLayout
- // implementation dependenciesList.lost
implementation dependenciesList.gmsLocation
implementation dependenciesList.timber
debugImplementation dependenciesList.leakCanaryDebug
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
index 98fe13e8eb..5626b82ccc 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationFragmentActivity.kt
@@ -105,8 +105,7 @@ class LocationFragmentActivity : AppCompatActivity() {
mapView.getMapAsync {
mapboxMap = it
component = mapboxMap.locationComponent
- component?.activateLocationComponent(activity,
- LocationEngineProvider.getBestLocationEngine(activity, false))
+ component?.activateLocationComponent(activity)
component?.isLocationComponentEnabled = true
component?.locationEngine?.getLastLocation(this)
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java
index 078b5c7ab5..25d87c32c7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/LocationModesActivity.java
@@ -4,45 +4,36 @@ import android.annotation.SuppressLint;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Bundle;
-import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ListPopupWindow;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Toast;
-import com.mapbox.android.core.location.LocationEngine;
-import com.mapbox.android.core.location.LocationEngineCallback;
-import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.android.core.location.LocationEngineRequest;
-import com.mapbox.android.core.location.LocationEngineResult;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
-import com.mapbox.mapboxsdk.location.OnLocationClickListener;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.location.LocationComponentOptions;
import com.mapbox.mapboxsdk.location.LocationComponent;
+import com.mapbox.mapboxsdk.location.LocationComponentOptions;
import com.mapbox.mapboxsdk.location.OnCameraTrackingChangedListener;
+import com.mapbox.mapboxsdk.location.OnLocationClickListener;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
import java.util.ArrayList;
import java.util.List;
public class LocationModesActivity extends AppCompatActivity implements OnMapReadyCallback,
- OnLocationClickListener, OnCameraTrackingChangedListener {
-
- private static final long DEFAULT_INTERVAL_MILLIS = 1000;
- private static final long DEFAULT_FASTEST_INTERVAL_MILLIS = 1000;
+ OnLocationClickListener, OnCameraTrackingChangedListener {
private MapView mapView;
private Button locationModeBtn;
@@ -51,7 +42,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
private PermissionsManager permissionsManager;
private LocationComponent locationComponent;
- private LocationEngine locationEngine;
private MapboxMap mapboxMap;
private boolean customStyle;
@@ -67,8 +57,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
private Location lastLocation;
- private LocationEngineCallback<LocationEngineResult> locationEngineCallback;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -77,25 +65,19 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
mapView = findViewById(R.id.mapView);
locationModeBtn = findViewById(R.id.button_location_mode);
- locationModeBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (locationComponent == null) {
- return;
- }
- showModeListDialog();
+ locationModeBtn.setOnClickListener(v -> {
+ if (locationComponent == null) {
+ return;
}
+ showModeListDialog();
});
locationTrackingBtn = findViewById(R.id.button_location_tracking);
- locationTrackingBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (locationComponent == null) {
- return;
- }
- showTrackingListDialog();
+ locationTrackingBtn.setOnClickListener(v -> {
+ if (locationComponent == null) {
+ return;
}
+ showTrackingListDialog();
});
@@ -141,20 +123,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
public void onMapReady(@NonNull MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
- locationEngine = LocationEngineProvider.getBestLocationEngine(getApplicationContext(),
- false);
- locationEngineCallback = new LocationEngineCallback<LocationEngineResult>() {
- @Override
- public void onSuccess(LocationEngineResult result) {
- // noop
- }
-
- @Override
- public void onFailure(@NonNull Exception exception) {
- // noop
- }
- };
-
int[] padding;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
padding = new int[] {0, 750, 0, 0};
@@ -168,7 +136,13 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
.build();
locationComponent = mapboxMap.getLocationComponent();
- locationComponent.activateLocationComponent(this, locationEngine, options);
+ locationComponent.activateLocationComponent(this, true,
+ new LocationEngineRequest.Builder(750)
+ .setFastestInterval(750)
+ .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
+ .build()
+ );
+ locationComponent.applyStyle(options);
locationComponent.setLocationComponentEnabled(true);
locationComponent.addOnLocationClickListener(this);
locationComponent.addOnCameraTrackingChangedListener(this);
@@ -248,14 +222,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
protected void onStart() {
super.onStart();
mapView.onStart();
- if (locationEngine != null) {
- try {
- locationEngine.requestLocationUpdates(getLocationRequst(DEFAULT_INTERVAL_MILLIS),
- locationEngineCallback, Looper.getMainLooper());
- } catch (SecurityException se) {
- se.printStackTrace();
- }
- }
}
@Override
@@ -274,9 +240,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
protected void onStop() {
super.onStop();
mapView.onStop();
- if (locationEngine != null) {
- locationEngine.removeLocationUpdates(locationEngineCallback);
- }
}
@SuppressLint("MissingPermission")
@@ -303,13 +266,6 @@ public class LocationModesActivity extends AppCompatActivity implements OnMapRea
mapView.onLowMemory();
}
- private static LocationEngineRequest getLocationRequst(long interval) {
- return new LocationEngineRequest.Builder(interval)
- .setFastestInterval(DEFAULT_FASTEST_INTERVAL_MILLIS)
- .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
- .build();
- }
-
@Override
public void onLocationComponentClick() {
Toast.makeText(this, "OnLocationComponentClick", Toast.LENGTH_LONG).show();
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.java
index ee65b97570..50f86efbbd 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/location/ManualLocationUpdatesActivity.java
@@ -1,38 +1,28 @@
package com.mapbox.mapboxsdk.testapp.activity.location;
-import android.location.Location;
+import android.annotation.SuppressLint;
import android.os.Bundle;
-import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
-import android.view.View;
import android.widget.Toast;
import com.mapbox.android.core.location.LocationEngine;
-import com.mapbox.android.core.location.LocationEngineCallback;
import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.android.core.location.LocationEngineRequest;
-import com.mapbox.android.core.location.LocationEngineResult;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.location.LocationComponent;
+import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.location.LocationComponent;
-import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.testapp.R;
import java.util.List;
-import timber.log.Timber;
-
-public class ManualLocationUpdatesActivity extends AppCompatActivity implements OnMapReadyCallback,
- LocationEngineCallback<LocationEngineResult> {
-
- private static final long DEFAULT_INTERVAL_MILLIS = 1000;
- private static final long DEFAULT_FASTEST_INTERVAL_MILLIS = 1000;
+public class ManualLocationUpdatesActivity extends AppCompatActivity implements OnMapReadyCallback {
private MapView mapView;
private LocationComponent locationComponent;
@@ -44,43 +34,38 @@ public class ManualLocationUpdatesActivity extends AppCompatActivity implements
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_manual_update);
+ locationEngine = LocationEngineProvider.getBestLocationEngine(this, false);
+
FloatingActionButton fabManualUpdate = findViewById(R.id.fabManualLocationChange);
- fabManualUpdate.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (locationComponent != null && locationComponent.getLocationEngine() == null) {
- locationComponent.forceLocationUpdate(
- Utils.getRandomLocation(LatLngBounds.from(60, 25, 40, -5)));
- }
+ fabManualUpdate.setOnClickListener(v -> {
+ if (locationComponent != null && locationComponent.getLocationEngine() == null) {
+ locationComponent.forceLocationUpdate(
+ Utils.getRandomLocation(LatLngBounds.from(60, 25, 40, -5)));
}
});
fabManualUpdate.setEnabled(false);
FloatingActionButton fabToggle = findViewById(R.id.fabToggleManualLocation);
- fabToggle.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (locationComponent != null) {
- locationComponent.setLocationEngine(locationComponent.getLocationEngine() == null ? locationEngine :
- null);
-
- if (locationComponent.getLocationEngine() == null) {
- fabToggle.setImageResource(R.drawable.ic_layers_clear);
- fabManualUpdate.setEnabled(true);
- fabManualUpdate.setAlpha(1f);
- Toast.makeText(
- ManualLocationUpdatesActivity.this.getApplicationContext(),
- "LocationEngine disable, use manual updates",
- Toast.LENGTH_SHORT).show();
- } else {
- fabToggle.setImageResource(R.drawable.ic_layers);
- fabManualUpdate.setEnabled(false);
- fabManualUpdate.setAlpha(0.5f);
- Toast.makeText(
- ManualLocationUpdatesActivity.this.getApplicationContext(),
- "LocationEngine enabled",
- Toast.LENGTH_SHORT).show();
- }
+ fabToggle.setOnClickListener(v -> {
+ if (locationComponent != null) {
+ locationComponent.setLocationEngine(locationComponent.getLocationEngine() == null ? locationEngine : null);
+
+ if (locationComponent.getLocationEngine() == null) {
+ fabToggle.setImageResource(R.drawable.ic_layers_clear);
+ fabManualUpdate.setEnabled(true);
+ fabManualUpdate.setAlpha(1f);
+ Toast.makeText(
+ ManualLocationUpdatesActivity.this.getApplicationContext(),
+ "LocationEngine disabled, use manual updates",
+ Toast.LENGTH_SHORT).show();
+ } else {
+ fabToggle.setImageResource(R.drawable.ic_layers);
+ fabManualUpdate.setEnabled(false);
+ fabManualUpdate.setAlpha(0.5f);
+ Toast.makeText(
+ ManualLocationUpdatesActivity.this.getApplicationContext(),
+ "LocationEngine enabled",
+ Toast.LENGTH_SHORT).show();
}
}
});
@@ -119,35 +104,25 @@ public class ManualLocationUpdatesActivity extends AppCompatActivity implements
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
+ @SuppressLint("MissingPermission")
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
- locationEngine = LocationEngineProvider.getBestLocationEngine(getApplicationContext(),
- false);
locationComponent = mapboxMap.getLocationComponent();
- locationComponent.activateLocationComponent(this, locationEngine);
+ locationComponent.activateLocationComponent(
+ this,
+ locationEngine,
+ new LocationEngineRequest.Builder(500)
+ .setFastestInterval(500)
+ .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
+ .build());
locationComponent.setLocationComponentEnabled(true);
locationComponent.setRenderMode(RenderMode.COMPASS);
}
- private static LocationEngineRequest getLocationRequst(long interval) {
- return new LocationEngineRequest.Builder(interval)
- .setFastestInterval(DEFAULT_FASTEST_INTERVAL_MILLIS)
- .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
- .build();
- }
-
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
- if (locationEngine != null) {
- try {
- locationEngine.requestLocationUpdates(getLocationRequst(DEFAULT_INTERVAL_MILLIS),
- this, Looper.getMainLooper());
- } catch (SecurityException se) {
- se.printStackTrace();
- }
- }
}
@Override
@@ -166,9 +141,6 @@ public class ManualLocationUpdatesActivity extends AppCompatActivity implements
protected void onStop() {
super.onStop();
mapView.onStop();
- if (locationEngine != null) {
- locationEngine.removeLocationUpdates(this);
- }
}
@Override
@@ -188,17 +160,4 @@ public class ManualLocationUpdatesActivity extends AppCompatActivity implements
super.onLowMemory();
mapView.onLowMemory();
}
-
- @Override
- public void onSuccess(LocationEngineResult result) {
- Location location = result.getLastLocation();
- if (location != null) {
- Timber.d("Location change occurred: %s", location.toString());
- }
- }
-
- @Override
- public void onFailure(@NonNull Exception exception) {
- Timber.d("Location engine error occurred: %s", exception.getMessage());
- }
} \ No newline at end of file
diff --git a/platform/android/build.gradle b/platform/android/build.gradle
index 86e4f4f5f8..c2bcde180d 100644
--- a/platform/android/build.gradle
+++ b/platform/android/build.gradle
@@ -18,7 +18,7 @@ allprojects {
google()
jcenter()
// Snapshot repository
- //maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
+ maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
}
}
diff --git a/platform/android/gradle/dependencies.gradle b/platform/android/gradle/dependencies.gradle
index 296572d214..61f619964f 100644
--- a/platform/android/gradle/dependencies.gradle
+++ b/platform/android/gradle/dependencies.gradle
@@ -9,7 +9,7 @@ ext {
versions = [
mapboxServices : '4.1.0',
- mapboxTelemetry : '4.0.0',
+ mapboxTelemetry : '4.1.0-SNAPSHOT',
mapboxGestures : '0.3.0',
supportLib : '27.1.1',
constraintLayout: '1.1.2',