From cb771f6aca2ef3cd0d1bf686139e18ce7cc0e233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 3 Sep 2018 15:48:32 +0200 Subject: [android] initialize LocationLayerPlugin with Map --- .../java/com/mapbox/mapboxsdk/maps/MapView.java | 23 ++- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 35 ++++ .../plugins/locationlayer/LocationLayerPlugin.java | 220 ++++++++++----------- 3 files changed, 153 insertions(+), 125 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 6fcc2c199a..76870e44d9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -44,6 +44,7 @@ import com.mapbox.mapboxsdk.net.ConnectivityReceiver; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition; +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.utils.BitmapUtils; @@ -178,9 +179,9 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(), cameraChangeDispatcher); + // MapboxMap mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, proj, registerTouchListener, annotationManager, cameraChangeDispatcher); - mapCallback.attachMapboxMap(mapboxMap); // user input @@ -194,8 +195,13 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { mapGestureDetector, cameraChangeDispatcher, getWidth(), getHeight()); mapZoomButtonController.bind(uiSettings, zoomListener); + // compass compassView.injectCompassAnimationListener(createCompassAnimationListener(cameraChangeDispatcher)); compassView.setOnClickListener(createCompassClickListener(cameraChangeDispatcher)); + + // LocationLayerPlugin + mapboxMap.injectLocationLayerPlugin(new LocationLayerPlugin(context, mapboxMap)); + // inject widgets with MapboxMap attrView.setOnClickListener(new AttributionClickListener(context, mapboxMap)); @@ -1214,11 +1220,16 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { @Override public void onMapChanged(@MapChange int change) { - if (change == DID_FINISH_LOADING_STYLE && initialLoad) { - initialLoad = false; - mapboxMap.onPreMapReady(); - onMapReady(); - mapboxMap.onPostMapReady(); + if (change == WILL_START_LOADING_MAP) { + mapboxMap.onStartLoadingMap(); + } else if (change == DID_FINISH_LOADING_STYLE) { + if (initialLoad) { + initialLoad = false; + mapboxMap.onPreMapReady(); + onMapReady(); + mapboxMap.onPostMapReady(); + } + mapboxMap.onFinishLoadingStyle(); } else if (change == DID_FINISH_RENDERING_FRAME || change == DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) { mapboxMap.onUpdateFullyRendered(); } else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 08369bb566..8892aa45fe 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -43,6 +43,7 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.log.Logger; +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.light.Light; @@ -75,6 +76,7 @@ public final class MapboxMap { private final OnGesturesManagerInteractionListener onGesturesManagerInteractionListener; + private LocationLayerPlugin locationLayerPlugin; private MapboxMap.OnFpsChangedListener onFpsChangedListener; MapboxMap(NativeMapView map, Transform transform, UiSettings ui, Projection projection, @@ -110,12 +112,14 @@ public final class MapboxMap { // if user hasn't loaded a Style yet nativeMapView.setStyleUrl(Style.MAPBOX_STREETS); } + locationLayerPlugin.onStart(); } /** * Called when the hosting Activity/Fragment onStop() method is called. */ void onStop() { + locationLayerPlugin.onStop(); } /** @@ -174,6 +178,20 @@ public final class MapboxMap { invalidateCameraPosition(); } + /** + * Called when the map will start loading style. + */ + void onStartLoadingMap() { + locationLayerPlugin.onStartLoadingMap(); + } + + /** + * Called the map finished loading style. + */ + void onFinishLoadingStyle() { + locationLayerPlugin.onFinishLoadingStyle(); + } + /** * Called when the region is changing or has changed. */ @@ -2283,6 +2301,23 @@ public final class MapboxMap { return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } + // + // LocationLayerPlugin + // + + void injectLocationLayerPlugin(LocationLayerPlugin locationLayerPlugin) { + this.locationLayerPlugin = locationLayerPlugin; + } + + /** + * Returns an object that can be used to display user's location on the Map. + * @return the location layer + */ + @NonNull + public LocationLayerPlugin getLocationLayerPlugin() { + return locationLayerPlugin; + } + // // Interfaces // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 70fc2ae298..988f01dce8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -1,9 +1,6 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; import android.annotation.SuppressLint; -import android.arch.lifecycle.Lifecycle; -import android.arch.lifecycle.LifecycleObserver; -import android.arch.lifecycle.OnLifecycleEvent; import android.content.Context; import android.hardware.SensorManager; import android.location.Location; @@ -22,8 +19,7 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.maps.MapView; -import com.mapbox.mapboxsdk.maps.MapView.OnMapChangedListener; +import com.mapbox.mapboxsdk.log.Logger; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener; import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; @@ -33,8 +29,6 @@ import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import java.util.concurrent.CopyOnWriteArrayList; -import timber.log.Timber; - import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.DEFAULT_TRACKING_TILT_ANIMATION_DURATION; @@ -66,10 +60,10 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants. * {@link LocationLayerOptions#MAX_ZOOM_DEFAULT} and {@link LocationLayerOptions#MIN_ZOOM_DEFAULT} respectively. * You can adjust the zoom range with {@link LocationLayerOptions#maxZoom()} and {@link LocationLayerOptions#minZoom()}. */ -public final class LocationLayerPlugin implements LifecycleObserver { +public final class LocationLayerPlugin { + private static final String TAG = "Mbgl-LocationLayerPlugin"; private final MapboxMap mapboxMap; - private final MapView mapView; private LocationLayerOptions options; private LocationEngine locationEngine; private CompassEngine compassEngine; @@ -101,7 +95,7 @@ public final class LocationLayerPlugin implements LifecycleObserver { * Initialized in a started state because the plugin can be instantiated after lifecycle's onStart() and * the developer might not register the lifecycle observer but call lifecycle methods manually instead. */ - private boolean isPluginStarted = true; + private boolean isPluginStarted; /** * Indicates if Mapbox components are ready to be interacted with. This can differ from {@link #isPluginStarted} @@ -121,116 +115,107 @@ public final class LocationLayerPlugin implements LifecycleObserver { /** * Construct a LocationLayerPlugin - *

- * Note: This constructor will initialize and use an internal {@link LocationEngine}. - *

* - * @param mapView the MapView to apply the LocationLayerPlugin to * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap) { + public LocationLayerPlugin(@NonNull Context context, @NonNull MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - this.mapView = mapView; - options = LocationLayerOptions.createFromAttributes(mapView.getContext(), R.style.mapbox_LocationLayer); - initializeLocationEngine(); - initialize(); + options = LocationLayerOptions.createFromAttributes(context, R.style.mapbox_LocationLayer); + initialize(context); } /** - * Construct a LocationLayerPlugin + * This method will show or hide the location icon and enable or disable the camera + * tracking the location. + * + * @param isEnabled true to show layers and enable camera, false otherwise + */ + private void setLocationLayerEnabled(boolean isEnabled) { + if (isEnabled) { + enableLocationLayerPlugin(); + } else { + disableLocationLayerPlugin(); + } + } + + /** + * This method will show the location icon and enable the camera tracking the location. *

* Note: This constructor will initialize and use an internal {@link LocationEngine}. - *

* - * @param mapView the MapView to apply the LocationLayerPlugin to - * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with - * @param options to customize the user location icons inside your apps + * @param context the context */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, - @NonNull LocationLayerOptions options) { - this.mapboxMap = mapboxMap; - this.mapView = mapView; - this.options = options; - initializeLocationEngine(); - initialize(); + @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}) + public void activateLocationLayerPlugin(@NonNull Context context) { + activateLocationLayerPlugin(context, LocationLayerOptions.createFromAttributes(context, R.style + .mapbox_LocationLayer)); } /** - * Construct a LocationLayerPlugin + * This method will show the location icon and enable the camera tracking the location. *

* Note: This constructor will initialize and use an internal {@link LocationEngine}. - *

* - * @param mapView the MapView to apply the LocationLayerPlugin to - * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with + * @param context the context + * @param styleRes the LocationLayerPlugin style res */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, - @StyleRes int styleRes) { - this.mapboxMap = mapboxMap; - this.mapView = mapView; - this.options = LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes); - initializeLocationEngine(); - initialize(); + @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}) + public void activateLocationLayerPlugin(@NonNull Context context, @StyleRes int styleRes) { + activateLocationLayerPlugin(context, LocationLayerOptions.createFromAttributes(context, styleRes)); } /** - * Construct a LocationLayerPlugin + * This method will show the location icon and enable the camera tracking the location. + *

+ * Note: This constructor will initialize and use an internal {@link LocationEngine}. + *

* - * @param mapView the MapView to apply the LocationLayerPlugin to - * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with - * @param locationEngine the {@link LocationEngine} this plugin should use to update + * @param context the context + * @param options the options */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, - @Nullable LocationEngine locationEngine) { - this(mapView, mapboxMap, locationEngine, - LocationLayerOptions.createFromAttributes(mapView.getContext(), - R.style.mapbox_LocationLayer)); + @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}) + public void activateLocationLayerPlugin(@NonNull Context context, @NonNull LocationLayerOptions options) { + applyStyle(options); + initializeLocationEngine(context); + setLocationLayerEnabled(true); } /** - * Construct a LocationLayerPlugin + * This method will show the location icon and enable the camera tracking the location. + *

+ * Note: This constructor will initialize and use an internal {@link LocationEngine}. + *

* - * @param mapView the MapView to apply the LocationLayerPlugin to - * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with - * @param locationEngine the {@link LocationEngine} this plugin should use to update - * @param styleRes customize the user location icons inside your apps {@code style.xml} + * @param context the context + * @param locationEngine the engine, or null if you'd like to only force location updates + * @param styleRes the LocationLayerPlugin style res */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, - @Nullable LocationEngine locationEngine, @StyleRes int styleRes) { - this(mapView, mapboxMap, locationEngine, - LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes)); + public void activateLocationLayerPlugin(@NonNull Context context, @Nullable LocationEngine locationEngine, + @StyleRes int styleRes) { + activateLocationLayerPlugin(locationEngine, LocationLayerOptions.createFromAttributes(context, styleRes)); } /** - * Construct a LocationLayerPlugin + * This method will show the location icon and enable the camera tracking the location. + *

+ * Note: This constructor will initialize and use an internal {@link LocationEngine}. + *

* - * @param mapView the MapView to apply the LocationLayerPlugin to - * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with - * @param locationEngine the {@link LocationEngine} this plugin should use to update - * @param options to customize the user location icons inside your apps + * @param locationEngine the engine, or null if you'd like to only force location updates + * @param options the options */ - public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, - @Nullable LocationEngine locationEngine, - @NonNull LocationLayerOptions options) { - this.locationEngine = locationEngine; - this.mapboxMap = mapboxMap; - this.mapView = mapView; - this.options = options; - initialize(); + public void activateLocationLayerPlugin(@Nullable LocationEngine locationEngine, + @NonNull LocationLayerOptions options) { + setLocationEngine(locationEngine); + applyStyle(options); + setLocationLayerEnabled(true); } /** - * This method will show or hide the location icon and enable or disable the camera - * tracking the location. - * - * @param isEnabled true to show layers and enable camera, false otherwise + * This method will hide the location icon and disable the camera tracking the location. */ - public void setLocationLayerEnabled(boolean isEnabled) { - if (isEnabled) { - enableLocationLayerPlugin(); - } else { - disableLocationLayerPlugin(); - } + public void deactivateLocationLayerPlugin() { + setLocationLayerEnabled(false); } /** @@ -315,8 +300,8 @@ public final class LocationLayerPlugin implements LifecycleObserver { * * @param styleRes a XML style overriding some or all the options */ - public void applyStyle(@StyleRes int styleRes) { - applyStyle(LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes)); + public void applyStyle(@NonNull Context context, @StyleRes int styleRes) { + applyStyle(LocationLayerOptions.createFromAttributes(context, styleRes)); } /** @@ -350,9 +335,9 @@ public final class LocationLayerPlugin implements LifecycleObserver { if (!isLocationLayerStarted) { return; } else if (getCameraMode() == CameraMode.NONE) { - Timber.e("%s%s", + Logger.e(TAG, String.format("%s%s", "LocationLayerPlugin#zoomWhileTracking method can only be used", - " when a camera mode other than CameraMode#NONE is engaged."); + " when a camera mode other than CameraMode#NONE is engaged.")); return; } pluginAnimatorCoordinator.feedNewZoomLevel(zoomLevel, mapboxMap.getCameraPosition(), animationDuration, callback); @@ -408,9 +393,9 @@ public final class LocationLayerPlugin implements LifecycleObserver { if (!isLocationLayerStarted) { return; } else if (getCameraMode() == CameraMode.NONE) { - Timber.e("%s%s", + Logger.e(TAG, String.format("%s%s", "LocationLayerPlugin#tiltWhileTracking method can only be used", - " when a camera mode other than CameraMode#NONE is engaged."); + " when a camera mode other than CameraMode#NONE is engaged.")); return; } pluginAnimatorCoordinator.feedNewTilt(tilt, mapboxMap.getCameraPosition(), animationDuration, callback); @@ -645,28 +630,43 @@ public final class LocationLayerPlugin implements LifecycleObserver { } /** - * You must call this method from the parent's Activity#onStart() or Fragment#onStart() + * Internal use. */ - @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onStart() { - if (mapView.isDestroyed()) { - Timber.e("You are calling plugins #onStart after the map was destroyed. Re-create the plugin before using it."); + // TODO: 03.09.18 LLP when map destroyed + /*if (context.isDestroyed()) { + Logger.e("You are calling plugins #onStart after the map was destroyed. Re-create the plugin before using it."); return; - } + }*/ isPluginStarted = true; onLocationLayerStart(); } /** - * You must call this method from the parent's Activity#onStop() or Fragment#onStop(). + * Internal use. */ - @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onStop() { onLocationLayerStop(); isPluginStarted = false; } + /** + * Internal use. + */ + public void onStartLoadingMap() { + onLocationLayerStop(); + } + + /** + * Internal use. + */ + public void onFinishLoadingStyle() { + locationLayer.initializeComponents(options); + locationLayerCamera.initializeOptions(options); + onLocationLayerStart(); + } + @SuppressLint("MissingPermission") private void onLocationLayerStart() { if (!isPluginStarted) { @@ -720,25 +720,22 @@ public final class LocationLayerPlugin implements LifecycleObserver { } } - private void initialize() { + private void initialize(@NonNull Context context) { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); - mapView.addOnMapChangedListener(onMapChangedListener); - mapboxMap.addOnMapClickListener(onMapClickListener); mapboxMap.addOnMapLongClickListener(onMapLongClickListener); LayerSourceProvider sourceProvider = new LayerSourceProvider(); LayerFeatureProvider featureProvider = new LayerFeatureProvider(); - LayerBitmapProvider bitmapProvider = new LayerBitmapProvider(mapView.getContext()); + LayerBitmapProvider bitmapProvider = new LayerBitmapProvider(context); locationLayer = new LocationLayer(mapboxMap, sourceProvider, featureProvider, bitmapProvider, options); locationLayerCamera = new LocationLayerCamera( - mapView.getContext(), mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener); + context, mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener); pluginAnimatorCoordinator = new PluginAnimatorCoordinator(); pluginAnimatorCoordinator.addLayerListener(locationLayer); pluginAnimatorCoordinator.addCameraListener(locationLayerCamera); - Context context = mapView.getContext(); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); compassEngine = new LocationLayerCompassEngine(windowManager, sensorManager); @@ -747,14 +744,13 @@ public final class LocationLayerPlugin implements LifecycleObserver { updateMapWithOptions(options); - enableLocationLayerPlugin(); setRenderMode(RenderMode.NORMAL); setCameraMode(CameraMode.NONE); } - private void initializeLocationEngine() { + private void initializeLocationEngine(@NonNull Context context) { usingInternalLocationEngine = true; - locationEngine = new LocationEngineProvider(mapView.getContext()).obtainBestLocationEngineAvailable(); + locationEngine = new LocationEngineProvider(context).obtainBestLocationEngineAvailable(); locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.setFastestInterval(1000); locationEngine.addLocationEngineListener(locationEngineListener); @@ -898,20 +894,6 @@ public final class LocationLayerPlugin implements LifecycleObserver { } }; - private OnMapChangedListener onMapChangedListener = new OnMapChangedListener() { - @SuppressLint("MissingPermission") - @Override - public void onMapChanged(int change) { - if (change == MapView.WILL_START_LOADING_MAP) { - onLocationLayerStop(); - } else if (change == MapView.DID_FINISH_LOADING_STYLE) { - locationLayer.initializeComponents(options); - locationLayerCamera.initializeOptions(options); - onLocationLayerStart(); - } - } - }; - private OnCameraMoveInvalidateListener onCameraMoveInvalidateListener = new OnCameraMoveInvalidateListener() { @Override public void onInvalidateCameraMove() { -- cgit v1.2.1