From ca00b5afcfefb1bd178d0346ef8e9b1ee7245731 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Wed, 17 Apr 2019 13:01:55 -0400 Subject: [PATCH 01/19] Add option to load offline maps database for NavigationView --- .../navigation/ui/v5/MapOfflineManager.java | 85 +++++++++++++++++++ .../ui/v5/NavigationLauncherOptions.java | 11 +++ .../v5/NavigationOfflineDatabaseCallback.java | 28 ++++++ .../navigation/ui/v5/NavigationUiOptions.java | 3 + .../navigation/ui/v5/NavigationViewModel.java | 44 +++++++--- ...gationViewModelProgressChangeListener.java | 21 +++++ .../ui/v5/NavigationViewOptions.java | 11 +++ .../ui/v5/OfflineDatabaseLoadedCallback.java | 8 ++ .../ui/v5/OfflineMetadataProvider.java | 26 ++++++ .../v5/OfflineRegionDefinitionProvider.java | 27 ++++++ .../ui/v5/OfflineRegionDownloadCallback.java | 8 ++ 11 files changed, 258 insertions(+), 14 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListener.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineDatabaseLoadedCallback.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProvider.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDownloadCallback.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java new file mode 100644 index 00000000000..5f29b56ddb5 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -0,0 +1,85 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.location.Location; +import android.support.annotation.NonNull; + +import com.mapbox.geojson.Geometry; +import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; +import com.mapbox.mapboxsdk.offline.OfflineManager; +import com.mapbox.mapboxsdk.offline.OfflineRegion; +import com.mapbox.mapboxsdk.offline.OfflineRegionError; +import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; +import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +class MapOfflineManager implements ProgressChangeListener { + + private final OfflineManager offlineManager; + private final OfflineRegionDefinitionProvider definitionProvider; + private final OfflineMetadataProvider metadataProvider; + + MapOfflineManager(OfflineManager offlineManager, OfflineRegionDefinitionProvider definitionProvider, + OfflineMetadataProvider metadataProvider) { + this.offlineManager = offlineManager; + this.definitionProvider = definitionProvider; + this.metadataProvider = metadataProvider; + } + + @Override + public void onProgressChange(Location location, RouteProgress routeProgress) { + // TODO look to download new geometries based on change in route + } + + void loadDatabase(@NonNull String offlineDatabasePath, final OfflineDatabaseLoadedCallback callback) { + offlineManager.mergeOfflineRegions(offlineDatabasePath, new OfflineManager.MergeOfflineRegionsCallback() { + @Override + public void onMerge(OfflineRegion[] offlineRegions) { + callback.onComplete(); + } + + @Override + public void onError(String error) { + callback.onError(error); + } + }); + } + + private void download(@NonNull String routeSummary, @NonNull Geometry routeGeometry, + final OfflineRegionDownloadCallback callback) { + OfflineGeometryRegionDefinition definition = definitionProvider.buildRegionFor(routeGeometry); + byte[] metadata = metadataProvider.buildMetaDataFor(routeSummary); + if (metadata == null) { + callback.onError("An error occurred processing the offline metadata"); + return; + } + offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() { + @Override + public void onCreate(OfflineRegion offlineRegion) { + offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE); + offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() { + @Override + public void onStatusChanged(OfflineRegionStatus status) { + if (status.isComplete()) { + callback.onComplete(); + } + } + + @Override + public void onError(OfflineRegionError error) { + callback.onError(String.format("%s %s", error.getMessage(), error.getReason())); + } + + @Override + public void mapboxTileCountLimitExceeded(long limit) { + callback.onError(String.format("Offline map tile limit reached %s", limit)); + } + }); + } + + @Override + public void onError(String error) { + callback.onError(error); + } + }); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java index b2efa24d252..7e4a0a17b79 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java @@ -49,6 +49,17 @@ public abstract static class Builder { */ public abstract Builder offlineRoutingTilesVersion(String offlineVersion); + /** + * Add an offline path for loading an offline map database. + *

+ * When added, the {@link NavigationView} will try to initialize and use this data + * for offline maps while navigating. + * + * @param offlinePath to offline database on device + * @return this builder + */ + public abstract Builder offlineMapDatabasePath(String offlinePath); + public abstract NavigationLauncherOptions build(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java new file mode 100644 index 00000000000..94c5355a9cb --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java @@ -0,0 +1,28 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.Mapbox; +import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation; + +import timber.log.Timber; + +class NavigationOfflineDatabaseCallback implements OfflineDatabaseLoadedCallback { + + private final MapboxNavigation navigation; + private final MapOfflineManager mapOfflineManager; + + NavigationOfflineDatabaseCallback(MapboxNavigation navigation, MapOfflineManager mapOfflineManager) { + this.navigation = navigation; + this.mapOfflineManager = mapOfflineManager; + } + + @Override + public void onComplete() { + Mapbox.setConnected(false); + navigation.addProgressChangeListener(mapOfflineManager); + } + + @Override + public void onError(String error) { + Timber.e(error); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java index 2dd93fb0701..e4e5b6be6bc 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java @@ -23,4 +23,7 @@ public abstract class NavigationUiOptions { @Nullable public abstract String offlineRoutingTilesVersion(); + + @Nullable + public abstract String offlineMapDatabasePath(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 1518ac83366..637c3f0f8ea 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -15,6 +15,7 @@ import com.mapbox.api.directions.v5.models.RouteOptions; import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.Mapbox; +import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.services.android.navigation.ui.v5.camera.DynamicCamera; import com.mapbox.services.android.navigation.ui.v5.feedback.FeedbackItem; import com.mapbox.services.android.navigation.ui.v5.instruction.BannerInstructionModel; @@ -38,7 +39,6 @@ import com.mapbox.services.android.navigation.v5.offroute.OffRouteListener; import com.mapbox.services.android.navigation.v5.route.FasterRouteListener; import com.mapbox.services.android.navigation.v5.route.RouteFetcher; -import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; import com.mapbox.services.android.navigation.v5.utils.DistanceFormatter; import com.mapbox.services.android.navigation.v5.utils.LocaleUtils; @@ -201,6 +201,7 @@ void initialize(NavigationViewOptions options) { initializeVoiceInstructionLoader(); initializeVoiceInstructionCache(); initializeNavigationSpeechPlayer(options); + initializeMapOfflineManager(options); } router.extractRouteOptions(options); } @@ -248,6 +249,18 @@ void updateRoute(DirectionsRoute route) { resetConfigurationFlag(); } + void updateRouteProgress(RouteProgress routeProgress) { + this.routeProgress = routeProgress; + sendEventArrival(routeProgress); + instructionModel.setValue(new InstructionModel(distanceFormatter, routeProgress)); + summaryModel.setValue(new SummaryModel(getApplication(), distanceFormatter, routeProgress, timeFormatType)); + } + + void updateLocation(Location location) { + router.updateLocation(location); + navigationLocation.setValue(location); + } + void sendEventFailedReroute(String errorMessage) { if (navigationViewEventDispatcher != null) { navigationViewEventDispatcher.onFailedReroute(errorMessage); @@ -312,6 +325,21 @@ private void initializeNavigationSpeechPlayer(NavigationViewOptions options) { this.speechPlayer = new NavigationSpeechPlayer(speechPlayerProvider); } + private void initializeMapOfflineManager(NavigationViewOptions options) { + if (TextUtils.isEmpty(options.offlineMapDatabasePath())) { + return; + } + Context applicationContext = getApplication().getApplicationContext(); + OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); + String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); + float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; + OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); + OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); + MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider); + NavigationOfflineDatabaseCallback callback = new NavigationOfflineDatabaseCallback(navigation, mapOfflineManager); + mapOfflineManager.loadDatabase(options.offlineMapDatabasePath(), callback); + } + private void initializeVoiceInstructionLoader() { Cache cache = new Cache(new File(getApplication().getCacheDir(), OKHTTP_INSTRUCTION_CACHE), TEN_MEGABYTE_CACHE_SIZE); @@ -341,7 +369,7 @@ private void initializeNavigation(Context context, MapboxNavigationOptions optio } private void addNavigationListeners() { - navigation.addProgressChangeListener(progressChangeListener); + navigation.addProgressChangeListener(new NavigationViewModelProgressChangeListener(this)); navigation.addOffRouteListener(offRouteListener); navigation.addMilestoneEventListener(milestoneEventListener); navigation.addNavigationEventListener(navigationEventListener); @@ -355,18 +383,6 @@ private void addMilestones(NavigationViewOptions options) { } } - private ProgressChangeListener progressChangeListener = new ProgressChangeListener() { - @Override - public void onProgressChange(Location location, RouteProgress routeProgress) { - NavigationViewModel.this.routeProgress = routeProgress; - router.updateLocation(location); - instructionModel.setValue(new InstructionModel(distanceFormatter, routeProgress)); - summaryModel.setValue(new SummaryModel(getApplication(), distanceFormatter, routeProgress, timeFormatType)); - navigationLocation.setValue(location); - sendEventArrival(routeProgress); - } - }; - private OffRouteListener offRouteListener = new OffRouteListener() { @Override public void userOffRoute(Location location) { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListener.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListener.java new file mode 100644 index 00000000000..51b769f33cf --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListener.java @@ -0,0 +1,21 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.location.Location; + +import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +class NavigationViewModelProgressChangeListener implements ProgressChangeListener { + + private final NavigationViewModel viewModel; + + NavigationViewModelProgressChangeListener(NavigationViewModel viewModel) { + this.viewModel = viewModel; + } + + @Override + public void onProgressChange(Location location, RouteProgress routeProgress) { + viewModel.updateRouteProgress(routeProgress); + viewModel.updateLocation(location); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java index 63e34f8e006..fdbc5884e85 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java @@ -122,6 +122,17 @@ public abstract static class Builder { */ public abstract Builder offlineRoutingTilesVersion(String offlineVersion); + /** + * Add an offline path for loading an offline map database. + *

+ * When added, the {@link NavigationView} will try to initialize and use this data + * for offline maps while navigating. + * + * @param offlinePath to offline database on device + * @return this builder + */ + public abstract Builder offlineMapDatabasePath(String offlinePath); + public abstract NavigationViewOptions build(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineDatabaseLoadedCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineDatabaseLoadedCallback.java new file mode 100644 index 00000000000..dd10d781ee4 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineDatabaseLoadedCallback.java @@ -0,0 +1,8 @@ +package com.mapbox.services.android.navigation.ui.v5; + +interface OfflineDatabaseLoadedCallback { + + void onComplete(); + + void onError(String error); +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java new file mode 100644 index 00000000000..1b78084018c --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java @@ -0,0 +1,26 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.support.annotation.Nullable; + +import org.json.JSONObject; + +import timber.log.Timber; + +class OfflineMetadataProvider { + + private static final String ROUTE_SUMMARY = "route_summary"; + private static final String JSON_CHARSET = "UTF-8"; + + @Nullable + byte[] buildMetaDataFor(String routeSummary) { + try { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(ROUTE_SUMMARY, routeSummary); + String json = jsonObject.toString(); + return json.getBytes(JSON_CHARSET); + } catch (Exception exception) { + Timber.e("Failed to encode metadata: %s", exception.getMessage()); + return null; + } + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProvider.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProvider.java new file mode 100644 index 00000000000..f028aea25d6 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProvider.java @@ -0,0 +1,27 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.geojson.Geometry; +import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; + +class OfflineRegionDefinitionProvider { + + private static final int MIN_ZOOM = 11; + private static final int MAX_ZOOM = 17; + private final String styleUrl; + private final float pixelRatio; + + OfflineRegionDefinitionProvider(String styleUrl, float pixelRatio) { + this.styleUrl = styleUrl; + this.pixelRatio = pixelRatio; + } + + OfflineGeometryRegionDefinition buildRegionFor(Geometry routeGeometry) { + return new OfflineGeometryRegionDefinition( + styleUrl, + routeGeometry, + MIN_ZOOM, + MAX_ZOOM, + pixelRatio + ); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDownloadCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDownloadCallback.java new file mode 100644 index 00000000000..fd6d731217b --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDownloadCallback.java @@ -0,0 +1,8 @@ +package com.mapbox.services.android.navigation.ui.v5; + +interface OfflineRegionDownloadCallback { + + void onComplete(); + + void onError(String error); +} \ No newline at end of file From 4237e1b320b71f18e3c7e567babf37e15274f4c8 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Fri, 19 Apr 2019 17:24:19 -0400 Subject: [PATCH 02/19] add download offline map tiles support into offline region download activity to help testing --- .../activity/OfflineRegionDownloadActivity.kt | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt index bdd7cbb2fa0..50b653ec052 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt @@ -19,14 +19,17 @@ import android.widget.ArrayAdapter import android.widget.Toast import com.mapbox.geojson.BoundingBox import com.mapbox.mapboxsdk.Mapbox +import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.Style +import com.mapbox.mapboxsdk.offline.* import com.mapbox.mapboxsdk.style.layers.FillLayer import com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import com.mapbox.services.android.navigation.testapp.R import com.mapbox.services.android.navigation.v5.navigation.* import kotlinx.android.synthetic.main.activity_offline_region_download.* +import org.json.JSONObject import timber.log.Timber class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadListener, OnOfflineTilesRemovedCallback { @@ -55,6 +58,40 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList get() { return MapboxOfflineRouter(obtainOfflineDirectory()) } + private lateinit var offlineManager: OfflineManager + private var offlineRegion: OfflineRegion? = null + private val offlineRegionCallback = object : OfflineManager.CreateOfflineRegionCallback { + override fun onCreate(offlineRegion: OfflineRegion?) { + Timber.d("Offline region created: %s", "NavigationOfflineMapsRegion") + this@OfflineRegionDownloadActivity.offlineRegion = offlineRegion + launchMapsDownload() + } + + override fun onError(error: String?) { + Timber.e("Error: %s", error) + } + } + + private val offlineRegionObserver = object : OfflineRegion.OfflineRegionObserver { + override fun mapboxTileCountLimitExceeded(limit: Long) { + Timber.e("Mapbox tile count limit exceeded: %s", limit) + } + + override fun onStatusChanged(status: OfflineRegionStatus?) { + Timber.d("%s/%s resources; %s bytes downloaded.", + status?.completedResourceCount, + status?.requiredResourceCount, + status?.completedResourceSize) + if (status?.isComplete!!) { + downloadSelectedRegion() + } + } + + override fun onError(error: OfflineRegionError?) { + Timber.e("onError reason: %s", error?.reason) + Timber.e("onError message: %s", error?.message) + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -124,6 +161,7 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList it.addSource(GeoJsonSource("bounding-box-source")) it.addLayer(FillLayer("bounding-box-layer", "bounding-box-source") .withProperties(fillColor(Color.parseColor("#50667F")))) + offlineManager = OfflineManager.getInstance(this) } this.mapboxMap = mapboxMap mapboxMap.uiSettings.isRotateGesturesEnabled = false @@ -140,7 +178,7 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(WRITE_EXTERNAL_STORAGE), 1) } else { - downloadSelectedRegion() + downloadMapsRegion() } } @@ -157,7 +195,7 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList when (requestCode) { EXTERNAL_STORAGE_PERMISSION -> { if ((grantResults.isNotEmpty() && grantResults[0] == PERMISSION_GRANTED)) { - downloadSelectedRegion() + downloadMapsRegion() } else { setDownloadButtonEnabled(false) } @@ -165,8 +203,30 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList } } - private fun downloadSelectedRegion() { + private fun downloadMapsRegion() { showDownloading(false, "Requesting tiles....") + val styleUrl: String? = mapboxMap.style?.url + val bounds: LatLngBounds = LatLngBounds.from(boundingBox.north(), boundingBox.east(), boundingBox.south(), boundingBox.west()) + val minZoom: Double = mapboxMap.cameraPosition.zoom + val maxZoom: Double = mapboxMap.maxZoomLevel + val pixelRatio: Float = this.resources.displayMetrics.density + val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( + styleUrl, bounds, minZoom, maxZoom, pixelRatio) + + val metadata: ByteArray + val jsonObject: JSONObject = JSONObject() + jsonObject.put("FIELD_REGION_NAME", "NavigationOfflineMapsRegion") + val json: String = jsonObject.toString() + metadata = json.toByteArray() + offlineManager.createOfflineRegion(definition, metadata, offlineRegionCallback) + } + + private fun launchMapsDownload() { + offlineRegion?.setObserver(offlineRegionObserver) + offlineRegion?.setDownloadState(OfflineRegion.STATE_ACTIVE) + } + + private fun downloadSelectedRegion() { val builder = OfflineTiles.builder() .accessToken(Mapbox.getAccessToken()) .version(versionSpinner.selectedItem as String) @@ -278,6 +338,7 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList override fun onDestroy() { super.onDestroy() + offlineRegion?.setObserver(null) mapView.onDestroy() } From 1cbcceff86d464a63d40a651d1fff4fdbb05eaee Mon Sep 17 00:00:00 2001 From: danesfeder Date: Fri, 19 Apr 2019 17:01:45 -0400 Subject: [PATCH 03/19] Wire up geometry and route geometry with buffer --- gradle/dependencies.gradle | 2 +- .../navigation/ui/v5/MapOfflineManager.java | 19 +++++++++++++- .../v5/navigation/MapboxNavigator.java | 25 +++++++++++++++++++ .../navigation/NavigationRouteProcessor.java | 14 +++++++++-- .../v5/routeprogress/RouteProgress.java | 14 +++++++++++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 6aa5325149a..7151a7f5911 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -12,7 +12,7 @@ ext { mapboxSdkServices : '4.8.0', mapboxEvents : '4.3.0', mapboxCore : '1.2.0', - mapboxNavigator : '6.1.3', + mapboxNavigator : 'route_buffer-SNAPSHOT-6', mapboxCrashMonitor : '2.0.0', mapboxAnnotationPlugin : '0.6.0', mapboxSearchSdk : '0.1.0-SNAPSHOT', diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 5f29b56ddb5..2934bf28f74 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -3,6 +3,7 @@ import android.location.Location; import android.support.annotation.NonNull; +import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.Geometry; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineManager; @@ -17,6 +18,7 @@ class MapOfflineManager implements ProgressChangeListener { private final OfflineManager offlineManager; private final OfflineRegionDefinitionProvider definitionProvider; private final OfflineMetadataProvider metadataProvider; + private Geometry currentRouteGeometry; MapOfflineManager(OfflineManager offlineManager, OfflineRegionDefinitionProvider definitionProvider, OfflineMetadataProvider metadataProvider) { @@ -27,7 +29,22 @@ class MapOfflineManager implements ProgressChangeListener { @Override public void onProgressChange(Location location, RouteProgress routeProgress) { - // TODO look to download new geometries based on change in route + FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); + if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometryWithBuffer)) { + currentRouteGeometry = routeGeometryWithBuffer.features().get(0).geometry(); + String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); // TODO unique identifier for download metadata? + download(routeSummary, currentRouteGeometry, new OfflineRegionDownloadCallback() { + @Override + public void onComplete() { + // TODO good to go? + } + + @Override + public void onError(String error) { + // TODO fail silently? + } + }); + } } void loadDatabase(@NonNull String offlineDatabasePath, final OfflineDatabaseLoadedCallback callback) { diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java index a40419db5ba..3b5aa99bd4c 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java @@ -2,8 +2,12 @@ import android.location.Location; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import com.mapbox.api.directions.v5.models.DirectionsRoute; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; +import com.mapbox.geojson.LineString; import com.mapbox.geojson.Point; import com.mapbox.navigator.BannerInstruction; import com.mapbox.navigator.FixLocation; @@ -11,11 +15,14 @@ import com.mapbox.navigator.Navigator; import com.mapbox.navigator.VoiceInstruction; +import java.util.ArrayList; import java.util.Date; class MapboxNavigator { private static final int INDEX_FIRST_ROUTE = 0; + private static final float GRID_SIZE = 0.315f; // TODO do these make sense? + private static final short BUFFER_DILATION = 1; private final Navigator navigator; private final RouteHandler routeHandler; @@ -89,6 +96,24 @@ synchronized BannerInstruction retrieveBannerInstruction(int index) { return navigator.getBannerInstruction(index); } + @Nullable + synchronized Geometry retrieveRouteGeometry() { + ArrayList routeGeometry = navigator.getRouteGeometry(); + if (routeGeometry != null) { + return LineString.fromLngLats(routeGeometry); + } + return null; + } + + @Nullable + synchronized FeatureCollection retrieveRouteGeometryWithBuffer() { + String routeGeometryWithBuffer = navigator.getRouteBufferGeoJson(GRID_SIZE, BUFFER_DILATION); + if (routeGeometryWithBuffer != null) { + return FeatureCollection.fromJson(routeGeometryWithBuffer); + } + return null; + } + private FixLocation buildFixLocationFromLocation(Location location) { Date time = new Date(); Point rawPoint = Point.fromLngLat(location.getLongitude(), location.getLatitude()); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java index 9e23f44fa16..9fb14fe7e40 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java @@ -7,6 +7,8 @@ import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; import com.mapbox.api.directions.v5.models.StepIntersection; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.navigator.BannerInstruction; import com.mapbox.navigator.NavigationStatus; @@ -44,10 +46,12 @@ class NavigationRouteProcessor { private List currentIntersections; private List> currentIntersectionDistances; private CurrentLegAnnotation currentLegAnnotation; + private Geometry routeGeometry; + private FeatureCollection routeGeometryWithBuffer; RouteProgress buildNewRouteProgress(MapboxNavigator navigator, NavigationStatus status, DirectionsRoute route) { previousStatus = status; - updateRoute(route); + updateRoute(route, navigator); return buildRouteProgressFrom(status, navigator); } @@ -65,9 +69,11 @@ NavigationStatus retrievePreviousStatus() { return previousStatus; } - private void updateRoute(DirectionsRoute route) { + private void updateRoute(DirectionsRoute route, MapboxNavigator navigator) { if (this.route == null || !this.route.equals(route)) { this.route = route; + routeGeometry = navigator.retrieveRouteGeometry(); + routeGeometryWithBuffer = navigator.retrieveRouteGeometryWithBuffer(); } } @@ -114,6 +120,10 @@ private RouteProgress buildRouteProgressFrom(NavigationStatus status, MapboxNavi .inTunnel(status.getInTunnel()) .currentState(currentRouteState); + // TODO extract to private? + progressBuilder.routeGeometry(routeGeometry); + progressBuilder.routeGeometryWithBuffer(routeGeometryWithBuffer); + addVoiceInstructions(status, progressBuilder); addBannerInstructions(status, navigator, progressBuilder); addUpcomingStepPoints(progressBuilder); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java index a7658d481f6..9f1bbd99421 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java @@ -9,6 +9,8 @@ import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; import com.mapbox.api.directions.v5.models.StepIntersection; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.navigator.BannerInstruction; import com.mapbox.navigator.VoiceInstruction; @@ -188,6 +190,14 @@ public int remainingWaypoints() { @Nullable public abstract RouteProgressState currentState(); + // TODO javadoc + @Nullable + public abstract Geometry routeGeometry(); + + // TODO javadoc + @Nullable + public abstract FeatureCollection routeGeometryWithBuffer(); + public abstract RouteProgress.Builder toBuilder(); abstract LegStep currentStep(); @@ -285,6 +295,10 @@ public abstract Builder intersectionDistancesAlongStep( public abstract Builder currentState(@Nullable RouteProgressState currentState); + public abstract Builder routeGeometry(@Nullable Geometry routeGeometry); + + public abstract Builder routeGeometryWithBuffer(@Nullable FeatureCollection routeGeometryWithBuffer); + abstract RouteProgress autoBuild(); // not public public RouteProgress build() { From 553cc283db1afe69627f40ae71841d0d57a4be38 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Mon, 22 Apr 2019 11:05:21 -0400 Subject: [PATCH 04/19] [WIP] add offline map database path option to navigation launcher --- .../navigationui/NavigationLauncherActivity.java | 2 ++ .../android/navigation/ui/v5/MapOfflineManager.java | 9 ++++++++- .../navigation/ui/v5/MapboxNavigationActivity.java | 4 ++++ .../android/navigation/ui/v5/NavigationLauncher.java | 6 ++++++ .../ui/v5/NavigationOfflineDatabaseCallback.java | 4 ++++ .../android/navigation/ui/v5/NavigationViewModel.java | 4 +++- .../navigation/v5/navigation/NavigationConstants.java | 1 + 7 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index b26f521b9a1..9b301bb02c1 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -354,6 +354,8 @@ private void launchNavigationWithRoute() { if (!offlineVersion.isEmpty()) { optionsBuilder.offlineRoutingTilesVersion(offlineVersion); } + // TODO Testing merging previously downloaded region + optionsBuilder.offlineMapDatabasePath(getFilesDir().getPath() + "/" + "mbgl-offline.db"); NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 2934bf28f74..03dc44e37fb 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -13,6 +13,8 @@ import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; +import timber.log.Timber; + class MapOfflineManager implements ProgressChangeListener { private final OfflineManager offlineManager; @@ -32,16 +34,21 @@ public void onProgressChange(Location location, RouteProgress routeProgress) { FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometryWithBuffer)) { currentRouteGeometry = routeGeometryWithBuffer.features().get(0).geometry(); - String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); // TODO unique identifier for download metadata? + // TODO unique identifier for download metadata? + String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); download(routeSummary, currentRouteGeometry, new OfflineRegionDownloadCallback() { @Override public void onComplete() { // TODO good to go? + // TODO Remove debug log after testing + Timber.d("onComplete!"); } @Override public void onError(String error) { // TODO fail silently? + // TODO Remove debug log after testing + Timber.d("onError %s", error); } }); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java index 8ca73513876..9962665aa73 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java @@ -139,6 +139,10 @@ private void extractConfiguration(NavigationViewOptions.Builder options) { if (!offlineVersion.isEmpty()) { options.offlineRoutingTilesVersion(offlineVersion); } + String offlineMapDatabasePath = preferences.getString(NavigationConstants.MAP_DATABASE_PATH_KEY, ""); + if (!offlineMapDatabasePath.isEmpty()) { + options.offlineMapDatabasePath(offlineMapDatabasePath); + } } private void finishNavigation() { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java index cb80e1637ea..bb70bb828c3 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java @@ -40,6 +40,7 @@ public static void startNavigation(Activity activity, NavigationLauncherOptions storeThemePreferences(options, editor); storeOfflinePath(options, editor); storeOfflineVersion(options, editor); + storeOfflineMapDatabasePath(options, editor); editor.apply(); @@ -75,6 +76,7 @@ static void cleanUpPreferences(Context context) { .remove(NavigationConstants.NAVIGATION_VIEW_DARK_THEME) .remove(NavigationConstants.OFFLINE_PATH_KEY) .remove(NavigationConstants.OFFLINE_VERSION_KEY) + .remove(NavigationConstants.MAP_DATABASE_PATH_KEY) .apply(); } @@ -116,4 +118,8 @@ private static void storeOfflineVersion(NavigationLauncherOptions options, Share editor.putString(NavigationConstants.OFFLINE_VERSION_KEY, options.offlineRoutingTilesVersion()); } + private static void storeOfflineMapDatabasePath(NavigationLauncherOptions options, SharedPreferences.Editor editor) { + editor.putString(NavigationConstants.MAP_DATABASE_PATH_KEY, options.offlineMapDatabasePath()); + } + } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java index 94c5355a9cb..40096182402 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java @@ -17,12 +17,16 @@ class NavigationOfflineDatabaseCallback implements OfflineDatabaseLoadedCallback @Override public void onComplete() { + // TODO Remove debug log after testing + Timber.d("NavigationOfflineDatabaseCallback#onComplete"); Mapbox.setConnected(false); navigation.addProgressChangeListener(mapOfflineManager); } @Override public void onError(String error) { + // TODO Remove debug log after testing + Timber.d("NavigationOfflineDatabaseCallback#onError %s", error); Timber.e(error); } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 637c3f0f8ea..733da12d634 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -331,7 +331,9 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { } Context applicationContext = getApplication().getApplicationContext(); OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); - String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); + //String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); + // TODO Getting a runtime crash when retrieving the style, hardcoding the styleUrl for testing / debugging purposes + String styleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java index e728e0aacce..88eb972877d 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java @@ -153,6 +153,7 @@ private NavigationConstants() { public static final String NAVIGATION_VIEW_ROUTE_PROFILE_KEY = "navigation_view_route_profile"; public static final String OFFLINE_PATH_KEY = "offline_path_key"; public static final String OFFLINE_VERSION_KEY = "offline_version_key"; + public static final String MAP_DATABASE_PATH_KEY = "offline_map_database_path_key"; // Step Maneuver Types public static final String STEP_MANEUVER_TYPE_TURN = "turn"; From cf1ca222592a0d193d2efb215bb28c3f78ee8b49 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Wed, 24 Apr 2019 11:23:35 -0400 Subject: [PATCH 05/19] [WIP] fix route geometry comparison, extract callbacks into classes, hardcode offline tile pyramid region definition values to match offline region definition provider ones and release a snapshot to test / debug upstream in gl-native --- .../activity/OfflineRegionDownloadActivity.kt | 11 ++- .../NavigationLauncherActivity.java | 3 +- circle.yml | 2 +- .../ui/v5/CreateOfflineRegionCallback.java | 43 ++++++++++++ .../navigation/ui/v5/MapOfflineManager.java | 68 ++----------------- .../ui/v5/MergeOfflineRegionsCallback.java | 23 +++++++ .../navigation/ui/v5/NavigationViewModel.java | 2 + .../ui/v5/RegionDownloadCallback.java | 20 ++++++ .../v5/navigation/MapboxNavigator.java | 2 +- .../OnOfflineTilesRemovedCallback.java | 2 +- 10 files changed, 107 insertions(+), 69 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt index 50b653ec052..431dfe0ac67 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt @@ -205,10 +205,15 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList private fun downloadMapsRegion() { showDownloading(false, "Requesting tiles....") - val styleUrl: String? = mapboxMap.style?.url + // TODO Hardcoding OfflineRegionDefinitionProvider values for testing / debugging purposes + val styleUrl: String? = "mapbox://styles/mapbox/navigation-guidance-day-v4" + //val styleUrl: String? = mapboxMap.style?.url val bounds: LatLngBounds = LatLngBounds.from(boundingBox.north(), boundingBox.east(), boundingBox.south(), boundingBox.west()) - val minZoom: Double = mapboxMap.cameraPosition.zoom - val maxZoom: Double = mapboxMap.maxZoomLevel + // TODO Hardcoding OfflineRegionDefinitionProvider values for testing / debugging purposes + val minZoom: Double = 11.0 + val maxZoom: Double = 17.0 + //val minZoom: Double = mapboxMap.cameraPosition.zoom + //val maxZoom: Double = mapboxMap.maxZoomLevel val pixelRatio: Float = this.resources.displayMetrics.density val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( styleUrl, bounds, minZoom, maxZoom, pixelRatio) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index 9b301bb02c1..03af926ad5b 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -4,6 +4,7 @@ import android.content.SharedPreferences; import android.location.Location; import android.os.Bundle; +import android.os.Environment; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -355,7 +356,7 @@ private void launchNavigationWithRoute() { optionsBuilder.offlineRoutingTilesVersion(offlineVersion); } // TODO Testing merging previously downloaded region - optionsBuilder.offlineMapDatabasePath(getFilesDir().getPath() + "/" + "mbgl-offline.db"); + optionsBuilder.offlineMapDatabasePath(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + "kingfarm.db"); NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/circle.yml b/circle.yml index c825530af2f..1ba3f9294ad 100644 --- a/circle.yml +++ b/circle.yml @@ -130,7 +130,7 @@ jobs: - deploy: name: Publish Navigation SDK To Maven Central command: | - if [ "${CIRCLE_BRANCH}" == "master" ]; then + if [ "${CIRCLE_BRANCH}" == "dan-offline-maps-ui" ]; then make publish ; fi - store_artifacts: diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java new file mode 100644 index 00000000000..3c891166b54 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java @@ -0,0 +1,43 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineManager; +import com.mapbox.mapboxsdk.offline.OfflineRegion; +import com.mapbox.mapboxsdk.offline.OfflineRegionError; +import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; + +class CreateOfflineRegionCallback implements OfflineManager.CreateOfflineRegionCallback { + + private final OfflineRegionDownloadCallback callback; + + CreateOfflineRegionCallback(OfflineRegionDownloadCallback callback) { + this.callback = callback; + } + + @Override + public void onCreate(OfflineRegion offlineRegion) { + offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE); + offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() { + @Override + public void onStatusChanged(OfflineRegionStatus status) { + if (status.isComplete()) { + callback.onComplete(); + } + } + + @Override + public void onError(OfflineRegionError error) { + callback.onError(String.format("%s %s", error.getMessage(), error.getReason())); + } + + @Override + public void mapboxTileCountLimitExceeded(long limit) { + callback.onError(String.format("Offline map tile limit reached %s", limit)); + } + }); + } + + @Override + public void onError(String error) { + callback.onError(error); + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 03dc44e37fb..9eb21b5fb4f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -7,14 +7,9 @@ import com.mapbox.geojson.Geometry; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineManager; -import com.mapbox.mapboxsdk.offline.OfflineRegion; -import com.mapbox.mapboxsdk.offline.OfflineRegionError; -import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; -import timber.log.Timber; - class MapOfflineManager implements ProgressChangeListener { private final OfflineManager offlineManager; @@ -32,40 +27,17 @@ class MapOfflineManager implements ProgressChangeListener { @Override public void onProgressChange(Location location, RouteProgress routeProgress) { FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); - if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometryWithBuffer)) { - currentRouteGeometry = routeGeometryWithBuffer.features().get(0).geometry(); + Geometry routeGeometry = routeGeometryWithBuffer.features().get(0).geometry(); + if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometry)) { + currentRouteGeometry = routeGeometry; // TODO unique identifier for download metadata? String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); - download(routeSummary, currentRouteGeometry, new OfflineRegionDownloadCallback() { - @Override - public void onComplete() { - // TODO good to go? - // TODO Remove debug log after testing - Timber.d("onComplete!"); - } - - @Override - public void onError(String error) { - // TODO fail silently? - // TODO Remove debug log after testing - Timber.d("onError %s", error); - } - }); + download(routeSummary, currentRouteGeometry, new RegionDownloadCallback()); } } void loadDatabase(@NonNull String offlineDatabasePath, final OfflineDatabaseLoadedCallback callback) { - offlineManager.mergeOfflineRegions(offlineDatabasePath, new OfflineManager.MergeOfflineRegionsCallback() { - @Override - public void onMerge(OfflineRegion[] offlineRegions) { - callback.onComplete(); - } - - @Override - public void onError(String error) { - callback.onError(error); - } - }); + offlineManager.mergeOfflineRegions(offlineDatabasePath, new MergeOfflineRegionsCallback(callback)); } private void download(@NonNull String routeSummary, @NonNull Geometry routeGeometry, @@ -76,34 +48,6 @@ private void download(@NonNull String routeSummary, @NonNull Geometry routeGeome callback.onError("An error occurred processing the offline metadata"); return; } - offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() { - @Override - public void onCreate(OfflineRegion offlineRegion) { - offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE); - offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() { - @Override - public void onStatusChanged(OfflineRegionStatus status) { - if (status.isComplete()) { - callback.onComplete(); - } - } - - @Override - public void onError(OfflineRegionError error) { - callback.onError(String.format("%s %s", error.getMessage(), error.getReason())); - } - - @Override - public void mapboxTileCountLimitExceeded(long limit) { - callback.onError(String.format("Offline map tile limit reached %s", limit)); - } - }); - } - - @Override - public void onError(String error) { - callback.onError(error); - } - }); + offlineManager.createOfflineRegion(definition, metadata, new CreateOfflineRegionCallback(callback)); } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java new file mode 100644 index 00000000000..5e1f63ee5a0 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java @@ -0,0 +1,23 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineManager; +import com.mapbox.mapboxsdk.offline.OfflineRegion; + +class MergeOfflineRegionsCallback implements OfflineManager.MergeOfflineRegionsCallback { + + private final OfflineDatabaseLoadedCallback callback; + + MergeOfflineRegionsCallback(OfflineDatabaseLoadedCallback callback) { + this.callback = callback; + } + + @Override + public void onMerge(OfflineRegion[] offlineRegions) { + callback.onComplete(); + } + + @Override + public void onError(String error) { + callback.onError(error); + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 733da12d634..3e098772b38 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -331,6 +331,8 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { } Context applicationContext = getApplication().getApplicationContext(); OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); + // TODO Tried setting a higher limit + //offlineManager.setOfflineMapboxTileCountLimit(1000000); //String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); // TODO Getting a runtime crash when retrieving the style, hardcoding the styleUrl for testing / debugging purposes String styleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java new file mode 100644 index 00000000000..787eeae7887 --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java @@ -0,0 +1,20 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import timber.log.Timber; + +class RegionDownloadCallback implements OfflineRegionDownloadCallback { + + @Override + public void onComplete() { + // TODO good to go? + // TODO Remove debug log after testing + Timber.d("onComplete!"); + } + + @Override + public void onError(String error) { + // TODO fail silently? + // TODO Remove debug log after testing + Timber.d("onError %s", error); + } +} diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java index 3b5aa99bd4c..88fd6b32399 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java @@ -21,7 +21,7 @@ class MapboxNavigator { private static final int INDEX_FIRST_ROUTE = 0; - private static final float GRID_SIZE = 0.315f; // TODO do these make sense? + private static final float GRID_SIZE = 0.0025f; // TODO do these make sense? private static final short BUFFER_DILATION = 1; private final Navigator navigator; private final RouteHandler routeHandler; diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/OnOfflineTilesRemovedCallback.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/OnOfflineTilesRemovedCallback.java index 71fdc879cd5..dc8237ff372 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/OnOfflineTilesRemovedCallback.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/OnOfflineTilesRemovedCallback.java @@ -4,7 +4,7 @@ /** * Listener that needs to be added to - * {@link MapboxOfflineRouter#removeTiles(BoundingBox, OnOfflineTilesRemovedCallback)} to know when the routing + * {@link MapboxOfflineRouter#removeTiles(String, BoundingBox, OnOfflineTilesRemovedCallback)} to know when the routing * tiles within the provided {@link BoundingBox} have been removed */ public interface OnOfflineTilesRemovedCallback { From 76f76fdea097284b9ccb920ba3d3a832ba84b46c Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Wed, 24 Apr 2019 15:54:35 -0400 Subject: [PATCH 06/19] extract offline region observer into a separate class, bump nn to route_buffer-SNAPSHOT-7 version, retrieve a geometry from nn instead of a feature collection and test downloading a geometry using offline geometry region definition via offline region download activity --- .../activity/OfflineRegionDownloadActivity.kt | 11 +++++-- gradle/dependencies.gradle | 2 +- .../ui/v5/CreateOfflineRegionCallback.java | 21 +------------ .../navigation/ui/v5/MapOfflineManager.java | 6 ++-- .../ui/v5/OfflineRegionObserver.java | 31 +++++++++++++++++++ .../v5/navigation/MapboxNavigator.java | 6 ++-- .../navigation/NavigationRouteProcessor.java | 3 +- .../v5/routeprogress/RouteProgress.java | 4 +-- 8 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserver.java diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt index 431dfe0ac67..09ba06d2701 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt @@ -18,6 +18,8 @@ import android.widget.AdapterView.OnItemSelectedListener import android.widget.ArrayAdapter import android.widget.Toast import com.mapbox.geojson.BoundingBox +import com.mapbox.geojson.Geometry +import com.mapbox.geojson.gson.GeometryGeoJson import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.maps.MapboxMap @@ -209,14 +211,19 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList val styleUrl: String? = "mapbox://styles/mapbox/navigation-guidance-day-v4" //val styleUrl: String? = mapboxMap.style?.url val bounds: LatLngBounds = LatLngBounds.from(boundingBox.north(), boundingBox.east(), boundingBox.south(), boundingBox.west()) + // TODO Testing downloading a Geometry + val geometry: Geometry = GeometryGeoJson.fromJson("{\"type\":\"Polygon\",\"coordinates\":[[[-77.152533,39.085537],[-77.152533,39.083038],[-77.150031,39.083038],[-77.150031,39.085537],[-77.147529,39.085537],[-77.147529,39.088039],[-77.147529,39.090538],[-77.150031,39.090538],[-77.150031,39.093037],[-77.150031,39.095539],[-77.150031,39.098038],[-77.150031,39.100540],[-77.150031,39.103039],[-77.152533,39.103039],[-77.152533,39.105537],[-77.155028,39.105537],[-77.155028,39.108040],[-77.155028,39.110538],[-77.157531,39.110538],[-77.157531,39.113037],[-77.160033,39.113037],[-77.160033,39.115536],[-77.162528,39.115540],[-77.162528,39.118038],[-77.165030,39.118038],[-77.165030,39.115536],[-77.167533,39.115536],[-77.167533,39.113037],[-77.167533,39.110538],[-77.165030,39.110538],[-77.165030,39.108040],[-77.162536,39.108036],[-77.162536,39.105537],[-77.162536,39.103039],[-77.160033,39.103039],[-77.160033,39.100540],[-77.157531,39.100536],[-77.157531,39.098038],[-77.157531,39.095535],[-77.157531,39.093037],[-77.157531,39.090538],[-77.157531,39.088039],[-77.155036,39.088036],[-77.155036,39.085537],[-77.152533,39.085537]]]}") // TODO Hardcoding OfflineRegionDefinitionProvider values for testing / debugging purposes val minZoom: Double = 11.0 val maxZoom: Double = 17.0 //val minZoom: Double = mapboxMap.cameraPosition.zoom //val maxZoom: Double = mapboxMap.maxZoomLevel val pixelRatio: Float = this.resources.displayMetrics.density - val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( - styleUrl, bounds, minZoom, maxZoom, pixelRatio) + //val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( + // styleUrl, bounds, minZoom, maxZoom, pixelRatio) + // TODO Testing downloading a Geometry and using OfflineGeometryRegionDefinition as definition + val definition: OfflineGeometryRegionDefinition = OfflineGeometryRegionDefinition( + styleUrl, geometry, minZoom, maxZoom, pixelRatio) val metadata: ByteArray val jsonObject: JSONObject = JSONObject() diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 7151a7f5911..6174f757f3d 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -12,7 +12,7 @@ ext { mapboxSdkServices : '4.8.0', mapboxEvents : '4.3.0', mapboxCore : '1.2.0', - mapboxNavigator : 'route_buffer-SNAPSHOT-6', + mapboxNavigator : 'route_buffer-SNAPSHOT-7', mapboxCrashMonitor : '2.0.0', mapboxAnnotationPlugin : '0.6.0', mapboxSearchSdk : '0.1.0-SNAPSHOT', diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java index 3c891166b54..54cfb8fa247 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallback.java @@ -2,8 +2,6 @@ import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.offline.OfflineRegion; -import com.mapbox.mapboxsdk.offline.OfflineRegionError; -import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; class CreateOfflineRegionCallback implements OfflineManager.CreateOfflineRegionCallback { @@ -16,24 +14,7 @@ class CreateOfflineRegionCallback implements OfflineManager.CreateOfflineRegionC @Override public void onCreate(OfflineRegion offlineRegion) { offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE); - offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() { - @Override - public void onStatusChanged(OfflineRegionStatus status) { - if (status.isComplete()) { - callback.onComplete(); - } - } - - @Override - public void onError(OfflineRegionError error) { - callback.onError(String.format("%s %s", error.getMessage(), error.getReason())); - } - - @Override - public void mapboxTileCountLimitExceeded(long limit) { - callback.onError(String.format("Offline map tile limit reached %s", limit)); - } - }); + offlineRegion.setObserver(new OfflineRegionObserver(callback)); } @Override diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 9eb21b5fb4f..92de678199c 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -3,7 +3,6 @@ import android.location.Location; import android.support.annotation.NonNull; -import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.Geometry; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineManager; @@ -26,8 +25,9 @@ class MapOfflineManager implements ProgressChangeListener { @Override public void onProgressChange(Location location, RouteProgress routeProgress) { - FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); - Geometry routeGeometry = routeGeometryWithBuffer.features().get(0).geometry(); + //FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); + //Geometry routeGeometry = routeGeometryWithBuffer.features().get(0).geometry(); + Geometry routeGeometry = routeProgress.routeGeometryWithBuffer(); if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometry)) { currentRouteGeometry = routeGeometry; // TODO unique identifier for download metadata? diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserver.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserver.java new file mode 100644 index 00000000000..fb4f6d18cce --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserver.java @@ -0,0 +1,31 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineRegion; +import com.mapbox.mapboxsdk.offline.OfflineRegionError; +import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; + +class OfflineRegionObserver implements OfflineRegion.OfflineRegionObserver { + + private final OfflineRegionDownloadCallback callback; + + OfflineRegionObserver(OfflineRegionDownloadCallback callback) { + this.callback = callback; + } + + @Override + public void onStatusChanged(OfflineRegionStatus status) { + if (status.isComplete()) { + callback.onComplete(); + } + } + + @Override + public void onError(OfflineRegionError error) { + callback.onError(String.format("%s %s", error.getMessage(), error.getReason())); + } + + @Override + public void mapboxTileCountLimitExceeded(long limit) { + callback.onError(String.format("Offline map tile limit reached %s", limit)); + } +} diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java index 88fd6b32399..2543f461992 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java @@ -5,10 +5,10 @@ import android.support.annotation.Nullable; import com.mapbox.api.directions.v5.models.DirectionsRoute; -import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.Geometry; import com.mapbox.geojson.LineString; import com.mapbox.geojson.Point; +import com.mapbox.geojson.gson.GeometryGeoJson; import com.mapbox.navigator.BannerInstruction; import com.mapbox.navigator.FixLocation; import com.mapbox.navigator.NavigationStatus; @@ -106,10 +106,10 @@ synchronized Geometry retrieveRouteGeometry() { } @Nullable - synchronized FeatureCollection retrieveRouteGeometryWithBuffer() { + synchronized Geometry retrieveRouteGeometryWithBuffer() { String routeGeometryWithBuffer = navigator.getRouteBufferGeoJson(GRID_SIZE, BUFFER_DILATION); if (routeGeometryWithBuffer != null) { - return FeatureCollection.fromJson(routeGeometryWithBuffer); + return GeometryGeoJson.fromJson(routeGeometryWithBuffer); } return null; } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java index 9fb14fe7e40..41e16af625c 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java @@ -7,7 +7,6 @@ import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; import com.mapbox.api.directions.v5.models.StepIntersection; -import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.navigator.BannerInstruction; @@ -47,7 +46,7 @@ class NavigationRouteProcessor { private List> currentIntersectionDistances; private CurrentLegAnnotation currentLegAnnotation; private Geometry routeGeometry; - private FeatureCollection routeGeometryWithBuffer; + private Geometry routeGeometryWithBuffer; RouteProgress buildNewRouteProgress(MapboxNavigator navigator, NavigationStatus status, DirectionsRoute route) { previousStatus = status; diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java index 9f1bbd99421..2be86229e01 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java @@ -196,7 +196,7 @@ public int remainingWaypoints() { // TODO javadoc @Nullable - public abstract FeatureCollection routeGeometryWithBuffer(); + public abstract Geometry routeGeometryWithBuffer(); public abstract RouteProgress.Builder toBuilder(); @@ -297,7 +297,7 @@ public abstract Builder intersectionDistancesAlongStep( public abstract Builder routeGeometry(@Nullable Geometry routeGeometry); - public abstract Builder routeGeometryWithBuffer(@Nullable FeatureCollection routeGeometryWithBuffer); + public abstract Builder routeGeometryWithBuffer(@Nullable Geometry routeGeometryWithBuffer); abstract RouteProgress autoBuild(); // not public From d4f1a894eb05ed31440cfd3e8aadf9abf32e00ea Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Thu, 25 Apr 2019 11:24:06 -0400 Subject: [PATCH 07/19] fix maps connected state that was preventing the route buffer downloading to finish --- .../activity/navigationui/NavigationLauncherActivity.java | 4 +++- circle.yml | 2 +- .../android/navigation/ui/v5/MapOfflineManager.java | 4 ++-- .../ui/v5/NavigationOfflineDatabaseCallback.java | 2 -- .../android/navigation/ui/v5/NavigationViewModel.java | 8 ++++---- .../android/navigation/ui/v5/RegionDownloadCallback.java | 4 ++++ .../navigation/v5/routeprogress/RouteProgress.java | 1 - 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index 03af926ad5b..4ca2e5ec5eb 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -356,7 +356,9 @@ private void launchNavigationWithRoute() { optionsBuilder.offlineRoutingTilesVersion(offlineVersion); } // TODO Testing merging previously downloaded region - optionsBuilder.offlineMapDatabasePath(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + "kingfarm.db"); + optionsBuilder.offlineMapDatabasePath( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + "kingfarm.db" + ); NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/circle.yml b/circle.yml index 1ba3f9294ad..c825530af2f 100644 --- a/circle.yml +++ b/circle.yml @@ -130,7 +130,7 @@ jobs: - deploy: name: Publish Navigation SDK To Maven Central command: | - if [ "${CIRCLE_BRANCH}" == "dan-offline-maps-ui" ]; then + if [ "${CIRCLE_BRANCH}" == "master" ]; then make publish ; fi - store_artifacts: diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 92de678199c..d269ae17781 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -4,6 +4,7 @@ import android.support.annotation.NonNull; import com.mapbox.geojson.Geometry; +import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; @@ -25,8 +26,6 @@ class MapOfflineManager implements ProgressChangeListener { @Override public void onProgressChange(Location location, RouteProgress routeProgress) { - //FeatureCollection routeGeometryWithBuffer = routeProgress.routeGeometryWithBuffer(); - //Geometry routeGeometry = routeGeometryWithBuffer.features().get(0).geometry(); Geometry routeGeometry = routeProgress.routeGeometryWithBuffer(); if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometry)) { currentRouteGeometry = routeGeometry; @@ -48,6 +47,7 @@ private void download(@NonNull String routeSummary, @NonNull Geometry routeGeome callback.onError("An error occurred processing the offline metadata"); return; } + Mapbox.setConnected(null); offlineManager.createOfflineRegion(definition, metadata, new CreateOfflineRegionCallback(callback)); } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java index 40096182402..451b68de0f7 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java @@ -1,6 +1,5 @@ package com.mapbox.services.android.navigation.ui.v5; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation; import timber.log.Timber; @@ -19,7 +18,6 @@ class NavigationOfflineDatabaseCallback implements OfflineDatabaseLoadedCallback public void onComplete() { // TODO Remove debug log after testing Timber.d("NavigationOfflineDatabaseCallback#onComplete"); - Mapbox.setConnected(false); navigation.addProgressChangeListener(mapOfflineManager); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 3e098772b38..11fb6a13a31 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -331,10 +331,10 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { } Context applicationContext = getApplication().getApplicationContext(); OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); - // TODO Tried setting a higher limit - //offlineManager.setOfflineMapboxTileCountLimit(1000000); - //String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); - // TODO Getting a runtime crash when retrieving the style, hardcoding the styleUrl for testing / debugging purposes + /** + * TODO Getting a runtime crash when retrieving the style, hardcoding the styleUrl for testing / debugging purposes + * String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); + */ String styleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java index 787eeae7887..365c4d954dd 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java @@ -1,5 +1,7 @@ package com.mapbox.services.android.navigation.ui.v5; +import com.mapbox.mapboxsdk.Mapbox; + import timber.log.Timber; class RegionDownloadCallback implements OfflineRegionDownloadCallback { @@ -8,6 +10,7 @@ class RegionDownloadCallback implements OfflineRegionDownloadCallback { public void onComplete() { // TODO good to go? // TODO Remove debug log after testing + Mapbox.setConnected(false); Timber.d("onComplete!"); } @@ -15,6 +18,7 @@ public void onComplete() { public void onError(String error) { // TODO fail silently? // TODO Remove debug log after testing + Mapbox.setConnected(false); Timber.d("onError %s", error); } } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java index 2be86229e01..01cbd61df8d 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java @@ -9,7 +9,6 @@ import com.mapbox.api.directions.v5.models.LegStep; import com.mapbox.api.directions.v5.models.RouteLeg; import com.mapbox.api.directions.v5.models.StepIntersection; -import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.navigator.BannerInstruction; From 0b04dc64140ebbe2fafd827937566708d81c8013 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Fri, 26 Apr 2019 19:57:20 -0400 Subject: [PATCH 08/19] [WIP] add tests - create offline region callback and map offline manager tests (for now) --- gradle/dependencies.gradle | 4 +- libandroid-navigation-ui/build.gradle | 1 + .../ui/v5/MapConnectivityController.java | 10 + .../navigation/ui/v5/MapOfflineManager.java | 27 ++- .../navigation/ui/v5/NavigationViewModel.java | 5 +- .../ui/v5/OfflineMetadataProvider.java | 2 +- .../ui/v5/RegionDownloadCallback.java | 13 +- .../v5/CreateOfflineRegionCallbackTest.java | 49 +++++ .../ui/v5/MapOfflineManagerTest.java | 208 ++++++++++++++++++ 9 files changed, 301 insertions(+), 18 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapConnectivityController.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallbackTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 6174f757f3d..c7a1ea78f14 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -39,7 +39,8 @@ ext { ankoCommon : '0.10.0', firebaseCore : '16.0.7', crashlytics : '2.9.9', - multidex : '1.0.3' + multidex : '1.0.3', + json : '20180813' ] dependenciesList = [ @@ -100,6 +101,7 @@ ext { hamcrest : "org.hamcrest:hamcrest-junit:${version.hamcrest}", commonsIO : "commons-io:commons-io:${version.commonsIO}", robolectric : "org.robolectric:robolectric:${version.robolectric}", + json : "org.json:json:${version.json}", // play services gmsLocation : "com.google.android.gms:play-services-location:${version.gmsLocation}", diff --git a/libandroid-navigation-ui/build.gradle b/libandroid-navigation-ui/build.gradle index 234efdae2c4..4dd00c5f06d 100644 --- a/libandroid-navigation-ui/build.gradle +++ b/libandroid-navigation-ui/build.gradle @@ -76,6 +76,7 @@ dependencies { testImplementation dependenciesList.junit testImplementation dependenciesList.mockito testImplementation dependenciesList.robolectric + testImplementation dependenciesList.json } apply from: 'javadoc.gradle' diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapConnectivityController.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapConnectivityController.java new file mode 100644 index 00000000000..04b8beb78db --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapConnectivityController.java @@ -0,0 +1,10 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.Mapbox; + +class MapConnectivityController { + + void assign(Boolean state) { + Mapbox.setConnected(state); + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index d269ae17781..c4a83d90cb1 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -4,7 +4,6 @@ import android.support.annotation.NonNull; import com.mapbox.geojson.Geometry; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener; @@ -12,42 +11,48 @@ class MapOfflineManager implements ProgressChangeListener { + private static final String OFFLINE_METADATA_ERROR = "An error occurred processing the offline metadata"; private final OfflineManager offlineManager; private final OfflineRegionDefinitionProvider definitionProvider; private final OfflineMetadataProvider metadataProvider; - private Geometry currentRouteGeometry; + private final MapConnectivityController connectivityController; + private final RegionDownloadCallback regionDownloadCallback; + private Geometry previousRouteGeometry; MapOfflineManager(OfflineManager offlineManager, OfflineRegionDefinitionProvider definitionProvider, - OfflineMetadataProvider metadataProvider) { + OfflineMetadataProvider metadataProvider, MapConnectivityController connectivityController, + RegionDownloadCallback regionDownloadCallback) { this.offlineManager = offlineManager; this.definitionProvider = definitionProvider; this.metadataProvider = metadataProvider; + this.connectivityController = connectivityController; + this.regionDownloadCallback = regionDownloadCallback; } @Override public void onProgressChange(Location location, RouteProgress routeProgress) { - Geometry routeGeometry = routeProgress.routeGeometryWithBuffer(); - if (currentRouteGeometry == null || !currentRouteGeometry.equals(routeGeometry)) { - currentRouteGeometry = routeGeometry; + Geometry currentRouteGeometry = routeProgress.routeGeometryWithBuffer(); + if (previousRouteGeometry == null || !previousRouteGeometry.equals(currentRouteGeometry)) { + previousRouteGeometry = currentRouteGeometry; // TODO unique identifier for download metadata? String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); - download(routeSummary, currentRouteGeometry, new RegionDownloadCallback()); + download(routeSummary, previousRouteGeometry, regionDownloadCallback); } } - void loadDatabase(@NonNull String offlineDatabasePath, final OfflineDatabaseLoadedCallback callback) { + void loadDatabase(@NonNull String offlineDatabasePath, OfflineDatabaseLoadedCallback callback) { offlineManager.mergeOfflineRegions(offlineDatabasePath, new MergeOfflineRegionsCallback(callback)); } private void download(@NonNull String routeSummary, @NonNull Geometry routeGeometry, final OfflineRegionDownloadCallback callback) { OfflineGeometryRegionDefinition definition = definitionProvider.buildRegionFor(routeGeometry); - byte[] metadata = metadataProvider.buildMetaDataFor(routeSummary); + byte[] metadata = metadataProvider.buildMetadataFor(routeSummary); if (metadata == null) { - callback.onError("An error occurred processing the offline metadata"); + callback.onError(OFFLINE_METADATA_ERROR); return; } - Mapbox.setConnected(null); + connectivityController.assign(null); offlineManager.createOfflineRegion(definition, metadata, new CreateOfflineRegionCallback(callback)); } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 11fb6a13a31..56e3af2fa55 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -339,7 +339,10 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); - MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider); + MapConnectivityController connectivityController = new MapConnectivityController(); + RegionDownloadCallback regionDownloadCallback = new RegionDownloadCallback(connectivityController); + MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider, + connectivityController, regionDownloadCallback); NavigationOfflineDatabaseCallback callback = new NavigationOfflineDatabaseCallback(navigation, mapOfflineManager); mapOfflineManager.loadDatabase(options.offlineMapDatabasePath(), callback); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java index 1b78084018c..5ec7bad5b6e 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java @@ -12,7 +12,7 @@ class OfflineMetadataProvider { private static final String JSON_CHARSET = "UTF-8"; @Nullable - byte[] buildMetaDataFor(String routeSummary) { + byte[] buildMetadataFor(String routeSummary) { try { JSONObject jsonObject = new JSONObject(); jsonObject.put(ROUTE_SUMMARY, routeSummary); diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java index 365c4d954dd..c2d1d1538b2 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java @@ -1,16 +1,21 @@ package com.mapbox.services.android.navigation.ui.v5; -import com.mapbox.mapboxsdk.Mapbox; - import timber.log.Timber; class RegionDownloadCallback implements OfflineRegionDownloadCallback { + private static final Boolean DISCONNECT_STATE = false; + private final MapConnectivityController connectivityController; + + RegionDownloadCallback(MapConnectivityController connectivityController) { + this.connectivityController = connectivityController; + } + @Override public void onComplete() { // TODO good to go? // TODO Remove debug log after testing - Mapbox.setConnected(false); + connectivityController.assign(DISCONNECT_STATE); Timber.d("onComplete!"); } @@ -18,7 +23,7 @@ public void onComplete() { public void onError(String error) { // TODO fail silently? // TODO Remove debug log after testing - Mapbox.setConnected(false); + connectivityController.assign(DISCONNECT_STATE); Timber.d("onError %s", error); } } diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallbackTest.java new file mode 100644 index 00000000000..df174e5b5d7 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/CreateOfflineRegionCallbackTest.java @@ -0,0 +1,49 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineRegion; + +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class CreateOfflineRegionCallbackTest { + + @Test + public void checksOfflineRegionDownloadStateSetToActiveWhenOnCreate() { + OfflineRegionDownloadCallback mockedOfflineRegionDownloadCallback = mock(OfflineRegionDownloadCallback.class); + OfflineRegion mockedOfflineRegion = mock(OfflineRegion.class); + CreateOfflineRegionCallback theOfflineRegionCallback = + new CreateOfflineRegionCallback(mockedOfflineRegionDownloadCallback); + + theOfflineRegionCallback.onCreate(mockedOfflineRegion); + + verify(mockedOfflineRegion).setDownloadState(eq(OfflineRegion.STATE_ACTIVE)); + } + + @Test + public void checksOfflineRegionObserverIsSetWhenOnCreate() { + OfflineRegionDownloadCallback mockedOfflineRegionDownloadCallback = mock(OfflineRegionDownloadCallback.class); + OfflineRegion mockedOfflineRegion = mock(OfflineRegion.class); + CreateOfflineRegionCallback theOfflineRegionCallback = + new CreateOfflineRegionCallback(mockedOfflineRegionDownloadCallback); + + theOfflineRegionCallback.onCreate(mockedOfflineRegion); + + verify(mockedOfflineRegion).setObserver(any(OfflineRegion.OfflineRegionObserver.class)); + } + + @Test + public void checksOnErrorCallbackIsCalledWhenOnError() { + OfflineRegionDownloadCallback mockedOfflineRegionDownloadCallback = mock(OfflineRegionDownloadCallback.class); + CreateOfflineRegionCallback theOfflineRegionCallback = + new CreateOfflineRegionCallback(mockedOfflineRegionDownloadCallback); + String anErrorMessage = "an error message"; + + theOfflineRegionCallback.onError(anErrorMessage); + + verify(mockedOfflineRegionDownloadCallback).onError(eq(anErrorMessage)); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java new file mode 100644 index 00000000000..cbf658761ff --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java @@ -0,0 +1,208 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.location.Location; + +import com.mapbox.api.directions.v5.models.DirectionsRoute; +import com.mapbox.api.directions.v5.models.RouteOptions; +import com.mapbox.geojson.Geometry; +import com.mapbox.geojson.gson.GeometryGeoJson; +import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; +import com.mapbox.mapboxsdk.offline.OfflineManager; +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +import org.junit.Test; +import org.mockito.InOrder; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class MapOfflineManagerTest { + + @Test + public void checksDefaultMapConnectivityIsSetWhenDownloadingRouteBuffer() { + String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + MapOfflineManager theMapOfflineManager = buildMapOfflineManager(aRouteSummary, mockedMapConnectivityController); + Location mockedLocation = mock(Location.class); + Geometry aRouteBufferGeometry = buildARouteBufferGeometry(); + RouteProgress mockedRouteProgress = buildMockRouteProgress(aRouteSummary, aRouteBufferGeometry); + Boolean defaultState = null; + + theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); + + verify(mockedMapConnectivityController).assign(eq(defaultState)); + } + + @Test + public void checksCreateOfflineRegionIsCalledWhenWhenDownloadingRouteBuffer() { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + String guidanceStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; + float anyPixelRatio = 3.0f; + OfflineRegionDefinitionProvider anOfflineRegionDefinitionProvider = + new OfflineRegionDefinitionProvider(guidanceStyleUrl, anyPixelRatio); + Geometry aRouteBufferGeometry = buildARouteBufferGeometry(); + OfflineGeometryRegionDefinition routeBufferDefinition = + anOfflineRegionDefinitionProvider.buildRegionFor(aRouteBufferGeometry); + when(mockedOfflineRegionDefinitionProvider.buildRegionFor(eq(aRouteBufferGeometry))).thenReturn(routeBufferDefinition); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + OfflineMetadataProvider anOfflineMetadataProvider = new OfflineMetadataProvider(); + String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; + byte[] routeSummaryMetadata = anOfflineMetadataProvider.buildMetadataFor(aRouteSummary); + when(mockedOfflineMetadataProvider.buildMetadataFor(eq(aRouteSummary))).thenReturn(routeSummaryMetadata); + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, + mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, + mockedRegionDownloadCallback); + Location mockedLocation = mock(Location.class); + RouteProgress mockedRouteProgress = buildMockRouteProgress(aRouteSummary, aRouteBufferGeometry); + + theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); + + verify(mockedOfflineManager).createOfflineRegion(eq(routeBufferDefinition), eq(routeSummaryMetadata), + any(CreateOfflineRegionCallback.class)); + } + + @Test + public void checksOnErrorRegionDownloadCallbackIsCalledIfMetadataIsNull() { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + String guidanceStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; + float anyPixelRatio = 3.0f; + OfflineRegionDefinitionProvider anOfflineRegionDefinitionProvider = + new OfflineRegionDefinitionProvider(guidanceStyleUrl, anyPixelRatio); + Geometry aRouteBufferGeometry = buildARouteBufferGeometry(); + OfflineGeometryRegionDefinition routeBufferDefinition = + anOfflineRegionDefinitionProvider.buildRegionFor(aRouteBufferGeometry); + when(mockedOfflineRegionDefinitionProvider.buildRegionFor(eq(aRouteBufferGeometry))).thenReturn(routeBufferDefinition); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; + byte[] nullMetadata = null; + when(mockedOfflineMetadataProvider.buildMetadataFor(eq(aRouteSummary))).thenReturn(nullMetadata); + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, + mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, + mockedRegionDownloadCallback); + Location mockedLocation = mock(Location.class); + RouteProgress mockedRouteProgress = buildMockRouteProgress(aRouteSummary, aRouteBufferGeometry); + Boolean defaultState = null; + + theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); + + verify(mockedRegionDownloadCallback).onError(eq("An error occurred processing the offline metadata")); + verify(mockedMapConnectivityController, times(0)).assign(eq(defaultState)); + verify(mockedOfflineManager, times(0)).createOfflineRegion(eq(routeBufferDefinition), eq(nullMetadata), + any(CreateOfflineRegionCallback.class)); + } + + @Test + public void checksDownloadIfPreviousRouteGeometryIsNotNullAndIsNotEqualToCurrentRouteGeometry() { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + String guidanceStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; + float anyPixelRatio = 3.0f; + OfflineRegionDefinitionProvider anOfflineRegionDefinitionProvider = + new OfflineRegionDefinitionProvider(guidanceStyleUrl, anyPixelRatio); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + OfflineMetadataProvider anOfflineMetadataProvider = new OfflineMetadataProvider(); + String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; + byte[] routeSummaryMetadata = anOfflineMetadataProvider.buildMetadataFor(aRouteSummary); + when(mockedOfflineMetadataProvider.buildMetadataFor(eq(aRouteSummary))).thenReturn(routeSummaryMetadata); + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, + mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, + mockedRegionDownloadCallback); + Location mockedLocation = mock(Location.class); + Geometry aRouteBufferGeometry = buildARouteBufferGeometry(); + RouteProgress mockedRouteProgress = buildMockRouteProgress(aRouteSummary, aRouteBufferGeometry); + Geometry anotherRouteBufferGeometry = buildAnotherRouteBufferGeometry(); + when(mockedRouteProgress.routeGeometryWithBuffer()).thenReturn(aRouteBufferGeometry, anotherRouteBufferGeometry); + OfflineGeometryRegionDefinition aRouteBufferDefinition = + anOfflineRegionDefinitionProvider.buildRegionFor(aRouteBufferGeometry); + OfflineGeometryRegionDefinition anotherRouteBufferDefinition = + anOfflineRegionDefinitionProvider.buildRegionFor(anotherRouteBufferGeometry); + when(mockedOfflineRegionDefinitionProvider.buildRegionFor(any(Geometry.class))) + .thenReturn(aRouteBufferDefinition, anotherRouteBufferDefinition); + Boolean defaultState = null; + theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); + + theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); + + verify(mockedMapConnectivityController, times(2)).assign(eq(defaultState)); + InOrder inOrder = inOrder(mockedOfflineManager, mockedOfflineManager); + inOrder.verify(mockedOfflineManager).createOfflineRegion(eq(aRouteBufferDefinition), eq(routeSummaryMetadata), + any(CreateOfflineRegionCallback.class)); + inOrder.verify(mockedOfflineManager).createOfflineRegion(eq(anotherRouteBufferDefinition), eq(routeSummaryMetadata), + any(CreateOfflineRegionCallback.class)); + } + + @Test + public void checksMergeOfflineRegionsIsCalledWhenLoadDatabase() { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, + mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, + mockedRegionDownloadCallback); + String aDatabasePath = "a/database/path"; + OfflineDatabaseLoadedCallback mockedOfflineDatabaseLoadedCallback = mock(OfflineDatabaseLoadedCallback.class); + + theMapOfflineManager.loadDatabase(aDatabasePath, mockedOfflineDatabaseLoadedCallback); + + verify(mockedOfflineManager).mergeOfflineRegions(eq(aDatabasePath), any(MergeOfflineRegionsCallback.class)); + } + + private MapOfflineManager buildMapOfflineManager(String routeSummary, + MapConnectivityController mapConnectivityController) { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + OfflineMetadataProvider anOfflineMetadataProvider = new OfflineMetadataProvider(); + byte[] routeSummaryMetadata = anOfflineMetadataProvider.buildMetadataFor(routeSummary); + when(mockedOfflineMetadataProvider.buildMetadataFor(eq(routeSummary))).thenReturn(routeSummaryMetadata); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + return new MapOfflineManager(mockedOfflineManager, mockedOfflineRegionDefinitionProvider, + mockedOfflineMetadataProvider, mapConnectivityController, mockedRegionDownloadCallback); + } + + private RouteProgress buildMockRouteProgress(String routeSummary, Geometry routeBufferGeometry) { + RouteProgress mockedRouteProgress = mock(RouteProgress.class); + when(mockedRouteProgress.routeGeometryWithBuffer()).thenReturn(routeBufferGeometry); + DirectionsRoute mockedRoute = mock(DirectionsRoute.class); + RouteOptions mockedRouteOptions = mock(RouteOptions.class); + when(mockedRouteOptions.requestUuid()).thenReturn(routeSummary); + when(mockedRoute.routeOptions()).thenReturn(mockedRouteOptions); + when(mockedRouteProgress.directionsRoute()).thenReturn(mockedRoute); + return mockedRouteProgress; + } + + private Geometry buildARouteBufferGeometry() { + return GeometryGeoJson.fromJson("{\"type\":\"Polygon\",\"coordinates\":[[[-77" + + ".152533,39.085537],[-77.152533,39.083038],[-77.150031,39.083038],[-77.150031,39.085537],[-77.147529,39" + + ".085537],[-77.147529,39.088039],[-77.147529,39.090538],[-77.150031,39.090538],[-77.150031,39.093037],[-77" + + ".150031,39.095539],[-77.150031,39.098038],[-77.150031,39.100540],[-77.150031,39.103039],[-77.152533,39" + + ".103039],[-77.152533,39.105537],[-77.155028,39.105537],[-77.155028,39.108040],[-77.155028,39.110538],[-77" + + ".157531,39.110538],[-77.157531,39.113037],[-77.160033,39.113037],[-77.160033,39.115536],[-77.162528,39" + + ".115540],[-77.162528,39.118038],[-77.165030,39.118038],[-77.165030,39.115536],[-77.167533,39.115536],[-77" + + ".167533,39.113037],[-77.167533,39.110538],[-77.165030,39.110538],[-77.165030,39.108040],[-77.162536,39" + + ".108036],[-77.162536,39.105537],[-77.162536,39.103039],[-77.160033,39.103039],[-77.160033,39.100540],[-77" + + ".157531,39.100536],[-77.157531,39.098038],[-77.157531,39.095535],[-77.157531,39.093037],[-77.157531,39" + + ".090538],[-77.157531,39.088039],[-77.155036,39.088036],[-77.155036,39.085537],[-77.152533,39.085537]]]}"); + } + + private Geometry buildAnotherRouteBufferGeometry() { + return GeometryGeoJson.fromJson("{\"type\":\"Polygon\",\"coordinates\":[[[-77" + + ".152533,39.085537],[-77.152533,39.083038],[-77.150031,39.083038],[-77.150031,39.085537],[-77.147529,39" + + ".085537],[-77.147529,39.088039],[-77.147529,39.090538]]]}"); + } +} \ No newline at end of file From 59a12308ac5af142d3c56d45d86454d2d04611c5 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Mon, 29 Apr 2019 15:23:15 -0400 Subject: [PATCH 09/19] Add NavigationUiOption for offline map style URL --- .../navigationui/NavigationLauncherActivity.java | 1 + .../navigation/ui/v5/NavigationLauncher.java | 4 ++++ .../navigation/ui/v5/NavigationLauncherOptions.java | 11 +++++++++++ .../navigation/ui/v5/NavigationUiOptions.java | 3 +++ .../navigation/ui/v5/NavigationViewModel.java | 13 +++++-------- .../navigation/ui/v5/NavigationViewOptions.java | 11 +++++++++++ .../v5/navigation/NavigationConstants.java | 2 +- 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index 4ca2e5ec5eb..3e7aa5bdaa3 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -359,6 +359,7 @@ private void launchNavigationWithRoute() { optionsBuilder.offlineMapDatabasePath( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + "kingfarm.db" ); + optionsBuilder.offlineMapStyleUrl("mapbox://styles/mapbox/navigation-guidance-day-v4"); NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java index bb70bb828c3..2d62b659a37 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java @@ -41,6 +41,7 @@ public static void startNavigation(Activity activity, NavigationLauncherOptions storeOfflinePath(options, editor); storeOfflineVersion(options, editor); storeOfflineMapDatabasePath(options, editor); + storeOfflineMapStyleUrl(options, editor); editor.apply(); @@ -122,4 +123,7 @@ private static void storeOfflineMapDatabasePath(NavigationLauncherOptions option editor.putString(NavigationConstants.MAP_DATABASE_PATH_KEY, options.offlineMapDatabasePath()); } + private static void storeOfflineMapStyleUrl(NavigationLauncherOptions options, SharedPreferences.Editor editor) { + editor.putString(NavigationConstants.MAP_STYLE_URL_KEY, options.offlineMapStyleUrl()); + } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java index 7e4a0a17b79..c5fce7cebd4 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java @@ -60,6 +60,17 @@ public abstract static class Builder { */ public abstract Builder offlineMapDatabasePath(String offlinePath); + /** + * Add the map style URL an offline map database. + *

+ * When added, this URL must correspond the the offline maps database added in + * {@link NavigationViewOptions#builder()#offlineMapDatabasePath(String)}. + * + * @param offlineUrl for map style of offline data + * @return this builder + */ + public abstract Builder offlineMapStyleUrl(String offlineUrl); + public abstract NavigationLauncherOptions build(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java index e4e5b6be6bc..04860f5b768 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java @@ -26,4 +26,7 @@ public abstract class NavigationUiOptions { @Nullable public abstract String offlineMapDatabasePath(); + + @Nullable + public abstract String offlineMapStyleUrl(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 56e3af2fa55..6ae7c7f8e0f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -326,25 +326,22 @@ private void initializeNavigationSpeechPlayer(NavigationViewOptions options) { } private void initializeMapOfflineManager(NavigationViewOptions options) { - if (TextUtils.isEmpty(options.offlineMapDatabasePath())) { + String mapDatabasePath = options.offlineMapDatabasePath(); + String mapStyleUrl = options.offlineMapStyleUrl(); + if (TextUtils.isEmpty(mapDatabasePath) || TextUtils.isEmpty(mapStyleUrl)) { return; } Context applicationContext = getApplication().getApplicationContext(); OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); - /** - * TODO Getting a runtime crash when retrieving the style, hardcoding the styleUrl for testing / debugging purposes - * String styleUrl = ThemeSwitcher.retrieveMapStyle(applicationContext); - */ - String styleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; - OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); + OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(mapStyleUrl, pixelRatio); OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); MapConnectivityController connectivityController = new MapConnectivityController(); RegionDownloadCallback regionDownloadCallback = new RegionDownloadCallback(connectivityController); MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider, connectivityController, regionDownloadCallback); NavigationOfflineDatabaseCallback callback = new NavigationOfflineDatabaseCallback(navigation, mapOfflineManager); - mapOfflineManager.loadDatabase(options.offlineMapDatabasePath(), callback); + mapOfflineManager.loadDatabase(mapDatabasePath, callback); } private void initializeVoiceInstructionLoader() { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java index fdbc5884e85..1c956c6befb 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java @@ -133,6 +133,17 @@ public abstract static class Builder { */ public abstract Builder offlineMapDatabasePath(String offlinePath); + /** + * Add the map style URL an offline map database. + *

+ * When added, this URL must correspond the the offline maps database added in + * {@link NavigationViewOptions#builder()#offlineMapDatabasePath(String)}. + * + * @param offlineUrl for map style of offline data + * @return this builder + */ + public abstract Builder offlineMapStyleUrl(String offlineUrl); + public abstract NavigationViewOptions build(); } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java index 88eb972877d..315271a91ae 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationConstants.java @@ -150,10 +150,10 @@ private NavigationConstants() { // Bundle variable keys public static final String NAVIGATION_VIEW_ROUTE_KEY = "route_json"; public static final String NAVIGATION_VIEW_SIMULATE_ROUTE = "navigation_view_simulate_route"; - public static final String NAVIGATION_VIEW_ROUTE_PROFILE_KEY = "navigation_view_route_profile"; public static final String OFFLINE_PATH_KEY = "offline_path_key"; public static final String OFFLINE_VERSION_KEY = "offline_version_key"; public static final String MAP_DATABASE_PATH_KEY = "offline_map_database_path_key"; + public static final String MAP_STYLE_URL_KEY = "offline_map_style_url_key"; // Step Maneuver Types public static final String STEP_MANEUVER_TYPE_TURN = "turn"; From 53b986b4c08073176520274ee11da124076f85fd Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Mon, 29 Apr 2019 18:01:58 -0400 Subject: [PATCH 10/19] [WIP] add offline map style url option to mapbox navigation activity --- .../android/navigation/ui/v5/MapboxNavigationActivity.java | 4 ++++ .../services/android/navigation/ui/v5/NavigationLauncher.java | 1 + 2 files changed, 5 insertions(+) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java index 9962665aa73..94b22a0d4bf 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java @@ -143,6 +143,10 @@ private void extractConfiguration(NavigationViewOptions.Builder options) { if (!offlineMapDatabasePath.isEmpty()) { options.offlineMapDatabasePath(offlineMapDatabasePath); } + String offlineMapStyleUrl = preferences.getString(NavigationConstants.MAP_STYLE_URL_KEY, ""); + if (!offlineMapStyleUrl.isEmpty()) { + options.offlineMapStyleUrl(offlineMapStyleUrl); + } } private void finishNavigation() { diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java index 2d62b659a37..d67991b3526 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java @@ -78,6 +78,7 @@ static void cleanUpPreferences(Context context) { .remove(NavigationConstants.OFFLINE_PATH_KEY) .remove(NavigationConstants.OFFLINE_VERSION_KEY) .remove(NavigationConstants.MAP_DATABASE_PATH_KEY) + .remove(NavigationConstants.MAP_STYLE_URL_KEY) .apply(); } From 98e57c65f914a75d7a48f888cbfa4c42ee0fea9c Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Tue, 30 Apr 2019 15:30:38 -0400 Subject: [PATCH 11/19] reset map connectivity state when navigation is stopped --- .../navigation/ui/v5/NavigationViewModel.java | 20 +++++++++++---- .../ui/v5/NavigationViewModelTest.java | 25 ++++++++++++++++--- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index 6ae7c7f8e0f..e5444e9d942 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -84,20 +84,24 @@ public class NavigationViewModel extends AndroidViewModel { private int timeFormatType; private boolean isRunning; private boolean isChangingConfigurations; + private MapConnectivityController connectivityController; public NavigationViewModel(Application application) { super(application); this.accessToken = Mapbox.getAccessToken(); initializeLocationEngine(); initializeRouter(); - routeUtils = new RouteUtils(); - localeUtils = new LocaleUtils(); + this.routeUtils = new RouteUtils(); + this.localeUtils = new LocaleUtils(); + this.connectivityController = new MapConnectivityController(); } // Package private (no modifier) for testing purposes - NavigationViewModel(Application application, MapboxNavigation navigation) { + NavigationViewModel(Application application, MapboxNavigation navigation, + MapConnectivityController connectivityController) { super(application); this.navigation = navigation; + this.connectivityController = connectivityController; } // Package private (no modifier) for testing purposes @@ -115,8 +119,9 @@ public NavigationViewModel(Application application) { public void onDestroy(boolean isChangingConfigurations) { this.isChangingConfigurations = isChangingConfigurations; if (!isChangingConfigurations) { - router.onDestroy(); + destroyRouter(); endNavigation(); + connectivityController.assign(null); deactivateInstructionPlayer(); isRunning = false; } @@ -336,7 +341,6 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(mapStyleUrl, pixelRatio); OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); - MapConnectivityController connectivityController = new MapConnectivityController(); RegionDownloadCallback regionDownloadCallback = new RegionDownloadCallback(connectivityController); MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider, connectivityController, regionDownloadCallback); @@ -437,6 +441,12 @@ private void updateReplayEngine(DirectionsRoute route) { } } + private void destroyRouter() { + if (router != null) { + router.onDestroy(); + } + } + private void endNavigation() { if (navigation != null) { navigation.onDestroy(); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java index d488898e460..7b81d690459 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java @@ -10,8 +10,9 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -24,7 +25,8 @@ public class NavigationViewModelTest { public void stopNavigation_progressListenersAreRemoved() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation); + MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); viewModel.stopNavigation(); @@ -35,19 +37,34 @@ public void stopNavigation_progressListenersAreRemoved() { public void stopNavigation_milestoneListenersAreRemoved() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation); + MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); viewModel.stopNavigation(); verify(navigation).removeMilestoneEventListener(null); } + @Test + public void stopNavigation_mapConnectivityControllerStateIsReset() { + Application application = mock(Application.class); + MapboxNavigation navigation = mock(MapboxNavigation.class); + MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); + Boolean defaultState = null; + + viewModel.onDestroy(false); + + verify(mockedConnectivityController).assign(eq(defaultState)); + } + @Test public void updateRoute_navigationIsNotUpdatedWhenChangingConfigurations() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); DirectionsRoute route = mock(DirectionsRoute.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation); + MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); viewModel.onDestroy(true); viewModel.updateRoute(route); From c56491fb0ef0d143c1a2ac0b3ec25854ff1adaf1 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Tue, 30 Apr 2019 16:12:36 -0400 Subject: [PATCH 12/19] Add tests for OfflineRegion provider, observer, and region download callback --- .../ui/v5/RegionDownloadCallback.java | 8 --- .../OfflineRegionDefinitionProviderTest.java | 50 +++++++++++++++++++ .../ui/v5/OfflineRegionObserverTest.java | 49 ++++++++++++++++++ .../ui/v5/RegionDownloadCallbackTest.java | 32 ++++++++++++ 4 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProviderTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserverTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallbackTest.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java index c2d1d1538b2..c155d94cd97 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallback.java @@ -1,7 +1,5 @@ package com.mapbox.services.android.navigation.ui.v5; -import timber.log.Timber; - class RegionDownloadCallback implements OfflineRegionDownloadCallback { private static final Boolean DISCONNECT_STATE = false; @@ -13,17 +11,11 @@ class RegionDownloadCallback implements OfflineRegionDownloadCallback { @Override public void onComplete() { - // TODO good to go? - // TODO Remove debug log after testing connectivityController.assign(DISCONNECT_STATE); - Timber.d("onComplete!"); } @Override public void onError(String error) { - // TODO fail silently? - // TODO Remove debug log after testing connectivityController.assign(DISCONNECT_STATE); - Timber.d("onError %s", error); } } diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProviderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProviderTest.java new file mode 100644 index 00000000000..2889eef4d34 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionDefinitionProviderTest.java @@ -0,0 +1,50 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.geojson.Geometry; +import com.mapbox.mapboxsdk.offline.OfflineGeometryRegionDefinition; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +public class OfflineRegionDefinitionProviderTest { + + private static final double DELTA = 1E-10; + + @Test + public void buildRegionFor_geometryIsCorrectlySet() { + String styleUrl = "mapbox://style"; + float pixelRatio = 1f; + Geometry routeGeometry = mock(Geometry.class); + OfflineRegionDefinitionProvider provider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); + + OfflineGeometryRegionDefinition offlineRegionDefinition = provider.buildRegionFor(routeGeometry); + + assertEquals(routeGeometry, offlineRegionDefinition.getGeometry()); + } + + @Test + public void buildRegionFor_styleUrlIsCorrectlySet() { + String styleUrl = "mapbox://style"; + float pixelRatio = 1f; + Geometry routeGeometry = mock(Geometry.class); + OfflineRegionDefinitionProvider provider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); + + OfflineGeometryRegionDefinition offlineRegionDefinition = provider.buildRegionFor(routeGeometry); + + assertEquals(styleUrl, offlineRegionDefinition.getStyleURL()); + } + + @Test + public void buildRegionFor_pixelRatioIsCorrectlySet() { + String styleUrl = "mapbox://style"; + float pixelRatio = 1f; + Geometry routeGeometry = mock(Geometry.class); + OfflineRegionDefinitionProvider provider = new OfflineRegionDefinitionProvider(styleUrl, pixelRatio); + + OfflineGeometryRegionDefinition offlineRegionDefinition = provider.buildRegionFor(routeGeometry); + + assertEquals(pixelRatio, offlineRegionDefinition.getPixelRatio(), DELTA); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserverTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserverTest.java new file mode 100644 index 00000000000..b5176f8a11d --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineRegionObserverTest.java @@ -0,0 +1,49 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineRegionError; +import com.mapbox.mapboxsdk.offline.OfflineRegionStatus; + +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class OfflineRegionObserverTest { + + @Test + public void onStatusChanged_completeCallbackIsTriggeredWithCompleteStatus() { + OfflineRegionDownloadCallback callback = mock(OfflineRegionDownloadCallback.class); + OfflineRegionStatus status = mock(OfflineRegionStatus.class); + when(status.isComplete()).thenReturn(true); + OfflineRegionObserver offlineRegionObserver = new OfflineRegionObserver(callback); + + offlineRegionObserver.onStatusChanged(status); + + verify(callback).onComplete(); + } + + @Test + public void onError_errorCallbackIsTriggered() { + OfflineRegionDownloadCallback callback = mock(OfflineRegionDownloadCallback.class); + OfflineRegionError error = mock(OfflineRegionError.class); + when(error.getMessage()).thenReturn("an error occurred"); + when(error.getReason()).thenReturn("because xyz"); + OfflineRegionObserver offlineRegionObserver = new OfflineRegionObserver(callback); + + offlineRegionObserver.onError(error); + + verify(callback).onError(eq("an error occurred because xyz")); + } + + @Test + public void mapboxTileCountLimitExceeded_errorCallbackIsTriggered() { + OfflineRegionDownloadCallback callback = mock(OfflineRegionDownloadCallback.class); + OfflineRegionObserver offlineRegionObserver = new OfflineRegionObserver(callback); + + offlineRegionObserver.mapboxTileCountLimitExceeded(6000L); + + verify(callback).onError(eq("Offline map tile limit reached 6000")); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallbackTest.java new file mode 100644 index 00000000000..f23c4f355cc --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/RegionDownloadCallbackTest.java @@ -0,0 +1,32 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class RegionDownloadCallbackTest { + + @Test + public void onComplete_disconnectStateIsAssigned() { + MapConnectivityController mapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback callback = new RegionDownloadCallback(mapConnectivityController); + + callback.onComplete(); + + verify(mapConnectivityController).assign(eq(false)); + } + + @Test + public void onError_disconnectStateIsAssigned() { + MapConnectivityController mapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback callback = new RegionDownloadCallback(mapConnectivityController); + + callback.onError("some error message"); + + verify(mapConnectivityController).assign(eq(false)); + + } +} \ No newline at end of file From 62f84c8b9d6c79d14d036e1cdd7b9588a2804d12 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Tue, 30 Apr 2019 16:46:48 -0400 Subject: [PATCH 13/19] add missing merge offline regions callback, navigation offline database callback, navigation view model progress change listener and offline metadata provider tests --- .../navigation/ui/v5/MapOfflineManager.java | 5 --- .../ui/v5/OfflineMetadataProvider.java | 3 -- .../ui/v5/MapOfflineManagerTest.java | 35 +--------------- .../v5/MergeOfflineRegionsCallbackTest.java | 36 +++++++++++++++++ ...NavigationOfflineDatabaseCallbackTest.java | 25 ++++++++++++ ...onViewModelProgressChangeListenerTest.java | 40 +++++++++++++++++++ .../ui/v5/OfflineMetadataProviderTest.java | 18 +++++++++ 7 files changed, 120 insertions(+), 42 deletions(-) create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListenerTest.java create mode 100644 libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProviderTest.java diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index c4a83d90cb1..81cbca8f137 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -11,7 +11,6 @@ class MapOfflineManager implements ProgressChangeListener { - private static final String OFFLINE_METADATA_ERROR = "An error occurred processing the offline metadata"; private final OfflineManager offlineManager; private final OfflineRegionDefinitionProvider definitionProvider; private final OfflineMetadataProvider metadataProvider; @@ -48,10 +47,6 @@ private void download(@NonNull String routeSummary, @NonNull Geometry routeGeome final OfflineRegionDownloadCallback callback) { OfflineGeometryRegionDefinition definition = definitionProvider.buildRegionFor(routeGeometry); byte[] metadata = metadataProvider.buildMetadataFor(routeSummary); - if (metadata == null) { - callback.onError(OFFLINE_METADATA_ERROR); - return; - } connectivityController.assign(null); offlineManager.createOfflineRegion(definition, metadata, new CreateOfflineRegionCallback(callback)); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java index 5ec7bad5b6e..4c0941706c6 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProvider.java @@ -4,8 +4,6 @@ import org.json.JSONObject; -import timber.log.Timber; - class OfflineMetadataProvider { private static final String ROUTE_SUMMARY = "route_summary"; @@ -19,7 +17,6 @@ byte[] buildMetadataFor(String routeSummary) { String json = jsonObject.toString(); return json.getBytes(JSON_CHARSET); } catch (Exception exception) { - Timber.e("Failed to encode metadata: %s", exception.getMessage()); return null; } } diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java index cbf658761ff..3f253e0f26a 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java @@ -39,7 +39,7 @@ public void checksDefaultMapConnectivityIsSetWhenDownloadingRouteBuffer() { } @Test - public void checksCreateOfflineRegionIsCalledWhenWhenDownloadingRouteBuffer() { + public void checksCreateOfflineRegionIsCalledWhenDownloadingRouteBuffer() { OfflineManager mockedOfflineManager = mock(OfflineManager.class); OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); String guidanceStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; @@ -69,39 +69,6 @@ public void checksCreateOfflineRegionIsCalledWhenWhenDownloadingRouteBuffer() { any(CreateOfflineRegionCallback.class)); } - @Test - public void checksOnErrorRegionDownloadCallbackIsCalledIfMetadataIsNull() { - OfflineManager mockedOfflineManager = mock(OfflineManager.class); - OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); - String guidanceStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; - float anyPixelRatio = 3.0f; - OfflineRegionDefinitionProvider anOfflineRegionDefinitionProvider = - new OfflineRegionDefinitionProvider(guidanceStyleUrl, anyPixelRatio); - Geometry aRouteBufferGeometry = buildARouteBufferGeometry(); - OfflineGeometryRegionDefinition routeBufferDefinition = - anOfflineRegionDefinitionProvider.buildRegionFor(aRouteBufferGeometry); - when(mockedOfflineRegionDefinitionProvider.buildRegionFor(eq(aRouteBufferGeometry))).thenReturn(routeBufferDefinition); - OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); - String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; - byte[] nullMetadata = null; - when(mockedOfflineMetadataProvider.buildMetadataFor(eq(aRouteSummary))).thenReturn(nullMetadata); - MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); - RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); - MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, - mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, - mockedRegionDownloadCallback); - Location mockedLocation = mock(Location.class); - RouteProgress mockedRouteProgress = buildMockRouteProgress(aRouteSummary, aRouteBufferGeometry); - Boolean defaultState = null; - - theMapOfflineManager.onProgressChange(mockedLocation, mockedRouteProgress); - - verify(mockedRegionDownloadCallback).onError(eq("An error occurred processing the offline metadata")); - verify(mockedMapConnectivityController, times(0)).assign(eq(defaultState)); - verify(mockedOfflineManager, times(0)).createOfflineRegion(eq(routeBufferDefinition), eq(nullMetadata), - any(CreateOfflineRegionCallback.class)); - } - @Test public void checksDownloadIfPreviousRouteGeometryIsNotNullAndIsNotEqualToCurrentRouteGeometry() { OfflineManager mockedOfflineManager = mock(OfflineManager.class); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java new file mode 100644 index 00000000000..ecf6f86c967 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java @@ -0,0 +1,36 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.mapboxsdk.offline.OfflineRegion; + +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class MergeOfflineRegionsCallbackTest { + + @Test + public void checksOfflineDatabaseLoadedOnCompleteCallbackIsCalledWhenOnMerge() { + OfflineDatabaseLoadedCallback mockedOfflineDatabaseLoadedCallback = mock(OfflineDatabaseLoadedCallback.class); + MergeOfflineRegionsCallback theMergeOfflineRegionsCallback = + new MergeOfflineRegionsCallback(mockedOfflineDatabaseLoadedCallback); + OfflineRegion[] anyOfflineRegion = new OfflineRegion[0]; + + theMergeOfflineRegionsCallback.onMerge(anyOfflineRegion); + + verify(mockedOfflineDatabaseLoadedCallback).onComplete(); + } + + @Test + public void checksOfflineDatabaseLoadedOnErrorCallbackIsCalledWhenOnError() { + OfflineDatabaseLoadedCallback mockedOfflineDatabaseLoadedCallback = mock(OfflineDatabaseLoadedCallback.class); + MergeOfflineRegionsCallback theMergeOfflineRegionsCallback = + new MergeOfflineRegionsCallback(mockedOfflineDatabaseLoadedCallback); + String anyError = "any error message"; + + theMergeOfflineRegionsCallback.onError(anyError); + + verify(mockedOfflineDatabaseLoadedCallback).onError(eq(anyError)); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java new file mode 100644 index 00000000000..7e0e60dd5be --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java @@ -0,0 +1,25 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import com.mapbox.services.android.navigation.v5.navigation.MapboxNavigation; + +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class NavigationOfflineDatabaseCallbackTest { + + @Test + public void checksMapOfflineManagerProgressChangeListenerIsAddedWhenOnComplete() { + MapboxNavigation mockedNavigation = mock(MapboxNavigation.class); + MapOfflineManager mockedMapOfflineManager = mock(MapOfflineManager.class); + NavigationOfflineDatabaseCallback theNavigationOfflineDatabaseCallback = + new NavigationOfflineDatabaseCallback(mockedNavigation, mockedMapOfflineManager); + + theNavigationOfflineDatabaseCallback.onComplete(); + + verify(mockedNavigation).addProgressChangeListener(eq(mockedMapOfflineManager)); + } + +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListenerTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListenerTest.java new file mode 100644 index 00000000000..a562521f573 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelProgressChangeListenerTest.java @@ -0,0 +1,40 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.location.Location; + +import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress; + +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class NavigationViewModelProgressChangeListenerTest { + + @Test + public void checksNavigationViewModelRouteProgressIsUpdatedWhenOnProgressChange() { + NavigationViewModel mockedNavigationViewModel = mock(NavigationViewModel.class); + NavigationViewModelProgressChangeListener theNavigationViewModelProgressChangeListener = + new NavigationViewModelProgressChangeListener(mockedNavigationViewModel); + Location anyLocation = mock(Location.class); + RouteProgress theRouteProgress = mock(RouteProgress.class); + + theNavigationViewModelProgressChangeListener.onProgressChange(anyLocation, theRouteProgress); + + verify(mockedNavigationViewModel).updateRouteProgress(eq(theRouteProgress)); + } + + @Test + public void checksNavigationViewModelLocationIsUpdatedWhenOnProgressChange() { + NavigationViewModel mockedNavigationViewModel = mock(NavigationViewModel.class); + NavigationViewModelProgressChangeListener theNavigationViewModelProgressChangeListener = + new NavigationViewModelProgressChangeListener(mockedNavigationViewModel); + Location theLocation = mock(Location.class); + RouteProgress anyRouteProgress = mock(RouteProgress.class); + + theNavigationViewModelProgressChangeListener.onProgressChange(theLocation, anyRouteProgress); + + verify(mockedNavigationViewModel).updateLocation(eq(theLocation)); + } +} \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProviderTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProviderTest.java new file mode 100644 index 00000000000..5cd60651781 --- /dev/null +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/OfflineMetadataProviderTest.java @@ -0,0 +1,18 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class OfflineMetadataProviderTest { + + @Test + public void checksOfflineRouteMetadataCreation() { + String aRouteSummary = "cjuykbm4705v26pnpvqlbjm5n"; + OfflineMetadataProvider theOfflineMetadataProvider = new OfflineMetadataProvider(); + + byte[] routeSummaryMetadata = theOfflineMetadataProvider.buildMetadataFor(aRouteSummary); + + assertEquals("{\"route_summary\":\"cjuykbm4705v26pnpvqlbjm5n\"}", new String(routeSummaryMetadata)); + } +} \ No newline at end of file From eee81b27121e854bb106003c5f4b4a02364d9f01 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Wed, 1 May 2019 10:45:49 -0400 Subject: [PATCH 14/19] Add MapOfflineOptions to make sure offline path and style URL are provided together --- .../NavigationLauncherActivity.java | 9 +++-- .../navigation/ui/v5/MapOfflineOptions.java | 40 +++++++++++++++++++ .../ui/v5/MapboxNavigationActivity.java | 8 ++-- .../navigation/ui/v5/NavigationLauncher.java | 10 +++-- .../ui/v5/NavigationLauncherOptions.java | 20 ++-------- .../navigation/ui/v5/NavigationUiOptions.java | 5 +-- .../navigation/ui/v5/NavigationViewModel.java | 7 ++-- .../ui/v5/NavigationViewOptions.java | 20 ++-------- 8 files changed, 65 insertions(+), 54 deletions(-) create mode 100644 libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineOptions.java diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index 3e7aa5bdaa3..9e4ccd130d4 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -44,6 +44,7 @@ import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.services.android.navigation.testapp.NavigationSettingsActivity; import com.mapbox.services.android.navigation.testapp.R; +import com.mapbox.services.android.navigation.ui.v5.MapOfflineOptions; import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher; import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions; import com.mapbox.services.android.navigation.ui.v5.camera.CameraUpdateMode; @@ -356,10 +357,10 @@ private void launchNavigationWithRoute() { optionsBuilder.offlineRoutingTilesVersion(offlineVersion); } // TODO Testing merging previously downloaded region - optionsBuilder.offlineMapDatabasePath( - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + "kingfarm.db" - ); - optionsBuilder.offlineMapStyleUrl("mapbox://styles/mapbox/navigation-guidance-day-v4"); + File downloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + String databaseFilePath = downloadDirectory + "/" + "kingfarm.db"; + String offlineStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; + optionsBuilder.offlineMapOptions(new MapOfflineOptions(databaseFilePath, offlineStyleUrl)); NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineOptions.java new file mode 100644 index 00000000000..2163cdc23dc --- /dev/null +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineOptions.java @@ -0,0 +1,40 @@ +package com.mapbox.services.android.navigation.ui.v5; + +import android.support.annotation.NonNull; + +public class MapOfflineOptions { + + private final String databasePath; + private final String styleUrl; + + /** + * Add an offline path and style URL for loading an offline map database. + * + * @param databaseFilePath to the offline database on the device + * @param styleUrl for the offline database data + */ + public MapOfflineOptions(@NonNull String databaseFilePath, @NonNull String styleUrl) { + this.databasePath = databaseFilePath; + this.styleUrl = styleUrl; + } + + /** + * The offline path to the offline map database. + * + * @return the database path + */ + @NonNull + public String getDatabasePath() { + return databasePath; + } + + /** + * The map style URL for the offline map database. + * + * @return the style URL + */ + @NonNull + public String getStyleUrl() { + return styleUrl; + } +} diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java index 94b22a0d4bf..34f7dbfa851 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapboxNavigationActivity.java @@ -140,12 +140,10 @@ private void extractConfiguration(NavigationViewOptions.Builder options) { options.offlineRoutingTilesVersion(offlineVersion); } String offlineMapDatabasePath = preferences.getString(NavigationConstants.MAP_DATABASE_PATH_KEY, ""); - if (!offlineMapDatabasePath.isEmpty()) { - options.offlineMapDatabasePath(offlineMapDatabasePath); - } String offlineMapStyleUrl = preferences.getString(NavigationConstants.MAP_STYLE_URL_KEY, ""); - if (!offlineMapStyleUrl.isEmpty()) { - options.offlineMapStyleUrl(offlineMapStyleUrl); + if (!offlineMapDatabasePath.isEmpty() && !offlineMapStyleUrl.isEmpty()) { + MapOfflineOptions mapOfflineOptions = new MapOfflineOptions(offlineMapDatabasePath, offlineMapStyleUrl); + options.offlineMapOptions(mapOfflineOptions); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java index d67991b3526..ada5e739896 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncher.java @@ -40,8 +40,10 @@ public static void startNavigation(Activity activity, NavigationLauncherOptions storeThemePreferences(options, editor); storeOfflinePath(options, editor); storeOfflineVersion(options, editor); - storeOfflineMapDatabasePath(options, editor); - storeOfflineMapStyleUrl(options, editor); + if (options.offlineMapOptions() != null) { + storeOfflineMapDatabasePath(options, editor); + storeOfflineMapStyleUrl(options, editor); + } editor.apply(); @@ -121,10 +123,10 @@ private static void storeOfflineVersion(NavigationLauncherOptions options, Share } private static void storeOfflineMapDatabasePath(NavigationLauncherOptions options, SharedPreferences.Editor editor) { - editor.putString(NavigationConstants.MAP_DATABASE_PATH_KEY, options.offlineMapDatabasePath()); + editor.putString(NavigationConstants.MAP_DATABASE_PATH_KEY, options.offlineMapOptions().getDatabasePath()); } private static void storeOfflineMapStyleUrl(NavigationLauncherOptions options, SharedPreferences.Editor editor) { - editor.putString(NavigationConstants.MAP_STYLE_URL_KEY, options.offlineMapStyleUrl()); + editor.putString(NavigationConstants.MAP_STYLE_URL_KEY, options.offlineMapOptions().getStyleUrl()); } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java index c5fce7cebd4..8a4cd9a938b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationLauncherOptions.java @@ -50,26 +50,12 @@ public abstract static class Builder { public abstract Builder offlineRoutingTilesVersion(String offlineVersion); /** - * Add an offline path for loading an offline map database. - *

- * When added, the {@link NavigationView} will try to initialize and use this data - * for offline maps while navigating. - * - * @param offlinePath to offline database on device - * @return this builder - */ - public abstract Builder offlineMapDatabasePath(String offlinePath); - - /** - * Add the map style URL an offline map database. - *

- * When added, this URL must correspond the the offline maps database added in - * {@link NavigationViewOptions#builder()#offlineMapDatabasePath(String)}. + * Add options to configure offline maps. * - * @param offlineUrl for map style of offline data + * @param mapOfflineOptions for offline configuration * @return this builder */ - public abstract Builder offlineMapStyleUrl(String offlineUrl); + public abstract Builder offlineMapOptions(MapOfflineOptions mapOfflineOptions); public abstract NavigationLauncherOptions build(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java index 04860f5b768..4a26127a1e5 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationUiOptions.java @@ -25,8 +25,5 @@ public abstract class NavigationUiOptions { public abstract String offlineRoutingTilesVersion(); @Nullable - public abstract String offlineMapDatabasePath(); - - @Nullable - public abstract String offlineMapStyleUrl(); + public abstract MapOfflineOptions offlineMapOptions(); } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index e5444e9d942..bf903e04317 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -331,11 +331,12 @@ private void initializeNavigationSpeechPlayer(NavigationViewOptions options) { } private void initializeMapOfflineManager(NavigationViewOptions options) { - String mapDatabasePath = options.offlineMapDatabasePath(); - String mapStyleUrl = options.offlineMapStyleUrl(); - if (TextUtils.isEmpty(mapDatabasePath) || TextUtils.isEmpty(mapStyleUrl)) { + MapOfflineOptions mapOfflineOptions = options.offlineMapOptions(); + if (mapOfflineOptions == null) { return; } + String mapDatabasePath = mapOfflineOptions.getDatabasePath(); + String mapStyleUrl = mapOfflineOptions.getStyleUrl(); Context applicationContext = getApplication().getApplicationContext(); OfflineManager offlineManager = OfflineManager.getInstance(applicationContext); float pixelRatio = applicationContext.getResources().getDisplayMetrics().density; diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java index 1c956c6befb..c7c4b404b2b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewOptions.java @@ -123,26 +123,12 @@ public abstract static class Builder { public abstract Builder offlineRoutingTilesVersion(String offlineVersion); /** - * Add an offline path for loading an offline map database. - *

- * When added, the {@link NavigationView} will try to initialize and use this data - * for offline maps while navigating. - * - * @param offlinePath to offline database on device - * @return this builder - */ - public abstract Builder offlineMapDatabasePath(String offlinePath); - - /** - * Add the map style URL an offline map database. - *

- * When added, this URL must correspond the the offline maps database added in - * {@link NavigationViewOptions#builder()#offlineMapDatabasePath(String)}. + * Add options to configure offline maps. * - * @param offlineUrl for map style of offline data + * @param mapOfflineOptions for offline configuration * @return this builder */ - public abstract Builder offlineMapStyleUrl(String offlineUrl); + public abstract Builder offlineMapOptions(MapOfflineOptions mapOfflineOptions); public abstract NavigationViewOptions build(); } From 820a2107184b263c4cef8bb71930cf14c2127124 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Wed, 1 May 2019 11:29:54 -0400 Subject: [PATCH 15/19] convert mapbox navigator retrieve route geometry and retrieve route geometry with buffer checks into guard clauses --- .../navigation/v5/navigation/MapboxNavigator.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java index 2543f461992..0817710cfcc 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java @@ -99,19 +99,19 @@ synchronized BannerInstruction retrieveBannerInstruction(int index) { @Nullable synchronized Geometry retrieveRouteGeometry() { ArrayList routeGeometry = navigator.getRouteGeometry(); - if (routeGeometry != null) { - return LineString.fromLngLats(routeGeometry); + if (routeGeometry == null) { + return null; } - return null; + return LineString.fromLngLats(routeGeometry); } @Nullable synchronized Geometry retrieveRouteGeometryWithBuffer() { String routeGeometryWithBuffer = navigator.getRouteBufferGeoJson(GRID_SIZE, BUFFER_DILATION); - if (routeGeometryWithBuffer != null) { - return GeometryGeoJson.fromJson(routeGeometryWithBuffer); + if (routeGeometryWithBuffer == null) { + return null; } - return null; + return GeometryGeoJson.fromJson(routeGeometryWithBuffer); } private FixLocation buildFixLocationFromLocation(Location location) { From 9f64e87e943e2e9f9f485999df397bba83c8eed7 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Mon, 13 May 2019 12:30:25 -0400 Subject: [PATCH 16/19] fix offline map callbacks issue --- build.gradle | 2 ++ gradle/dependencies.gradle | 2 +- .../navigation/ui/v5/MapOfflineManager.java | 23 +++++++++++++- .../ui/v5/MergeOfflineRegionsCallback.java | 15 ++++++++-- .../v5/NavigationOfflineDatabaseCallback.java | 4 +++ .../navigation/ui/v5/NavigationViewModel.java | 15 ++++++++-- .../ui/v5/MapOfflineManagerTest.java | 17 +++++++++++ .../v5/MergeOfflineRegionsCallbackTest.java | 12 ++++++++ ...NavigationOfflineDatabaseCallbackTest.java | 11 +++++++ .../ui/v5/NavigationViewModelTest.java | 30 ++++++++++++++++--- 10 files changed, 119 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 6a2cb71232e..bee52a4bd72 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,8 @@ task testReport(type: TestReport, group: 'Build') { allprojects { repositories { + // TODO Remove when Maps SDK is released + maven { url 'https://oss.jfrog.org/artifactory/oss-snapshot-local/' } google() mavenCentral() jcenter() diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index c7a1ea78f14..ad8fe41249d 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -10,7 +10,7 @@ ext { version = [ mapboxMapSdk : '7.4.0', mapboxSdkServices : '4.8.0', - mapboxEvents : '4.3.0', + mapboxEvents : '4.4.1', mapboxCore : '1.2.0', mapboxNavigator : 'route_buffer-SNAPSHOT-7', mapboxCrashMonitor : '2.0.0', diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index 81cbca8f137..be980d2a3bb 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -17,6 +17,7 @@ class MapOfflineManager implements ProgressChangeListener { private final MapConnectivityController connectivityController; private final RegionDownloadCallback regionDownloadCallback; private Geometry previousRouteGeometry; + private MergeOfflineRegionsCallback mergeOfflineRegionsCallback; MapOfflineManager(OfflineManager offlineManager, OfflineRegionDefinitionProvider definitionProvider, OfflineMetadataProvider metadataProvider, MapConnectivityController connectivityController, @@ -28,6 +29,19 @@ class MapOfflineManager implements ProgressChangeListener { this.regionDownloadCallback = regionDownloadCallback; } + // Package private (no modifier) for testing purposes + MapOfflineManager(OfflineManager offlineManager, OfflineRegionDefinitionProvider definitionProvider, + OfflineMetadataProvider metadataProvider, MapConnectivityController connectivityController, + RegionDownloadCallback regionDownloadCallback, + MergeOfflineRegionsCallback mergeOfflineRegionsCallback) { + this.offlineManager = offlineManager; + this.definitionProvider = definitionProvider; + this.metadataProvider = metadataProvider; + this.connectivityController = connectivityController; + this.regionDownloadCallback = regionDownloadCallback; + this.mergeOfflineRegionsCallback = mergeOfflineRegionsCallback; + } + @Override public void onProgressChange(Location location, RouteProgress routeProgress) { Geometry currentRouteGeometry = routeProgress.routeGeometryWithBuffer(); @@ -40,7 +54,14 @@ public void onProgressChange(Location location, RouteProgress routeProgress) { } void loadDatabase(@NonNull String offlineDatabasePath, OfflineDatabaseLoadedCallback callback) { - offlineManager.mergeOfflineRegions(offlineDatabasePath, new MergeOfflineRegionsCallback(callback)); + mergeOfflineRegionsCallback = new MergeOfflineRegionsCallback(callback); + offlineManager.mergeOfflineRegions(offlineDatabasePath, mergeOfflineRegionsCallback); + } + + void onDestroy() { + if (mergeOfflineRegionsCallback != null) { + mergeOfflineRegionsCallback.onDestroy(); + } } private void download(@NonNull String routeSummary, @NonNull Geometry routeGeometry, diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java index 5e1f63ee5a0..4cbde297931 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallback.java @@ -5,7 +5,7 @@ class MergeOfflineRegionsCallback implements OfflineManager.MergeOfflineRegionsCallback { - private final OfflineDatabaseLoadedCallback callback; + private OfflineDatabaseLoadedCallback callback; MergeOfflineRegionsCallback(OfflineDatabaseLoadedCallback callback) { this.callback = callback; @@ -13,11 +13,20 @@ class MergeOfflineRegionsCallback implements OfflineManager.MergeOfflineRegionsC @Override public void onMerge(OfflineRegion[] offlineRegions) { - callback.onComplete(); + if (callback != null) { + callback.onComplete(); + } } @Override public void onError(String error) { - callback.onError(error); + if (callback != null) { + callback.onError(error); + } + } + + OfflineDatabaseLoadedCallback onDestroy() { + callback = null; + return callback; } } diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java index 451b68de0f7..e89b6c56d3b 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java @@ -27,4 +27,8 @@ public void onError(String error) { Timber.d("NavigationOfflineDatabaseCallback#onError %s", error); Timber.e(error); } + + void onDestroy() { + mapOfflineManager.onDestroy(); + } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java index bf903e04317..999a4b88346 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModel.java @@ -85,6 +85,7 @@ public class NavigationViewModel extends AndroidViewModel { private boolean isRunning; private boolean isChangingConfigurations; private MapConnectivityController connectivityController; + private MapOfflineManager mapOfflineManager; public NavigationViewModel(Application application) { super(application); @@ -98,10 +99,11 @@ public NavigationViewModel(Application application) { // Package private (no modifier) for testing purposes NavigationViewModel(Application application, MapboxNavigation navigation, - MapConnectivityController connectivityController) { + MapConnectivityController connectivityController, MapOfflineManager mapOfflineManager) { super(application); this.navigation = navigation; this.connectivityController = connectivityController; + this.mapOfflineManager = mapOfflineManager; } // Package private (no modifier) for testing purposes @@ -121,7 +123,7 @@ public void onDestroy(boolean isChangingConfigurations) { if (!isChangingConfigurations) { destroyRouter(); endNavigation(); - connectivityController.assign(null); + destroyMapOffline(); deactivateInstructionPlayer(); isRunning = false; } @@ -343,7 +345,7 @@ private void initializeMapOfflineManager(NavigationViewOptions options) { OfflineRegionDefinitionProvider definitionProvider = new OfflineRegionDefinitionProvider(mapStyleUrl, pixelRatio); OfflineMetadataProvider metadataProvider = new OfflineMetadataProvider(); RegionDownloadCallback regionDownloadCallback = new RegionDownloadCallback(connectivityController); - MapOfflineManager mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider, + mapOfflineManager = new MapOfflineManager(offlineManager, definitionProvider, metadataProvider, connectivityController, regionDownloadCallback); NavigationOfflineDatabaseCallback callback = new NavigationOfflineDatabaseCallback(navigation, mapOfflineManager); mapOfflineManager.loadDatabase(mapDatabasePath, callback); @@ -464,6 +466,13 @@ private void clearDynamicCameraMap() { } } + private void destroyMapOffline() { + if (mapOfflineManager != null) { + mapOfflineManager.onDestroy(); + } + connectivityController.assign(null); + } + private void deactivateInstructionPlayer() { if (speechPlayer != null) { speechPlayer.onDestroy(); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java index 3f253e0f26a..ff5170d8afa 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManagerTest.java @@ -129,6 +129,23 @@ public void checksMergeOfflineRegionsIsCalledWhenLoadDatabase() { verify(mockedOfflineManager).mergeOfflineRegions(eq(aDatabasePath), any(MergeOfflineRegionsCallback.class)); } + @Test + public void checksMergeOfflineRegionsCallbackOnDestroyIsCalledIfNotNullWhenOnDestroy() { + OfflineManager mockedOfflineManager = mock(OfflineManager.class); + OfflineRegionDefinitionProvider mockedOfflineRegionDefinitionProvider = mock(OfflineRegionDefinitionProvider.class); + OfflineMetadataProvider mockedOfflineMetadataProvider = mock(OfflineMetadataProvider.class); + MapConnectivityController mockedMapConnectivityController = mock(MapConnectivityController.class); + RegionDownloadCallback mockedRegionDownloadCallback = mock(RegionDownloadCallback.class); + MergeOfflineRegionsCallback mockedMergeOfflineRegionsCallback = mock(MergeOfflineRegionsCallback.class); + MapOfflineManager theMapOfflineManager = new MapOfflineManager(mockedOfflineManager, + mockedOfflineRegionDefinitionProvider, mockedOfflineMetadataProvider, mockedMapConnectivityController, + mockedRegionDownloadCallback, mockedMergeOfflineRegionsCallback); + + theMapOfflineManager.onDestroy(); + + verify(mockedMergeOfflineRegionsCallback).onDestroy(); + } + private MapOfflineManager buildMapOfflineManager(String routeSummary, MapConnectivityController mapConnectivityController) { OfflineManager mockedOfflineManager = mock(OfflineManager.class); diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java index ecf6f86c967..2ed08ce2f54 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/MergeOfflineRegionsCallbackTest.java @@ -4,6 +4,7 @@ import org.junit.Test; +import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -33,4 +34,15 @@ public void checksOfflineDatabaseLoadedOnErrorCallbackIsCalledWhenOnError() { verify(mockedOfflineDatabaseLoadedCallback).onError(eq(anyError)); } + + @Test + public void checksOfflineDatabaseLoadedOnDestroyReleasesCallback() { + OfflineDatabaseLoadedCallback mockedOfflineDatabaseLoadedCallback = mock(OfflineDatabaseLoadedCallback.class); + MergeOfflineRegionsCallback theMergeOfflineRegionsCallback = + new MergeOfflineRegionsCallback(mockedOfflineDatabaseLoadedCallback); + + OfflineDatabaseLoadedCallback destroyedCallback = theMergeOfflineRegionsCallback.onDestroy(); + + assertNull(destroyedCallback); + } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java index 7e0e60dd5be..b2a35a0c5e0 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallbackTest.java @@ -22,4 +22,15 @@ public void checksMapOfflineManagerProgressChangeListenerIsAddedWhenOnComplete() verify(mockedNavigation).addProgressChangeListener(eq(mockedMapOfflineManager)); } + @Test + public void checksMapOfflineManagerOnDestroyIsCalledWhenOnDestroy() { + MapboxNavigation mockedNavigation = mock(MapboxNavigation.class); + MapOfflineManager mockedMapOfflineManager = mock(MapOfflineManager.class); + NavigationOfflineDatabaseCallback theNavigationOfflineDatabaseCallback = + new NavigationOfflineDatabaseCallback(mockedNavigation, mockedMapOfflineManager); + + theNavigationOfflineDatabaseCallback.onDestroy(); + + verify(mockedMapOfflineManager).onDestroy(); + } } \ No newline at end of file diff --git a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java index 7b81d690459..9bee899994a 100644 --- a/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java +++ b/libandroid-navigation-ui/src/test/java/com/mapbox/services/android/navigation/ui/v5/NavigationViewModelTest.java @@ -26,7 +26,9 @@ public void stopNavigation_progressListenersAreRemoved() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); + MapOfflineManager mapOfflineManager = mock(MapOfflineManager.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController, + mapOfflineManager); viewModel.stopNavigation(); @@ -38,19 +40,37 @@ public void stopNavigation_milestoneListenersAreRemoved() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); + MapOfflineManager mapOfflineManager = mock(MapOfflineManager.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController, + mapOfflineManager); viewModel.stopNavigation(); verify(navigation).removeMilestoneEventListener(null); } + @Test + public void stopNavigation_mapOfflineManagerOnDestroyIsCalledIfNotNull() { + Application application = mock(Application.class); + MapboxNavigation navigation = mock(MapboxNavigation.class); + MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); + MapOfflineManager mapOfflineManager = mock(MapOfflineManager.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController, + mapOfflineManager); + + viewModel.onDestroy(false); + + verify(mapOfflineManager).onDestroy(); + } + @Test public void stopNavigation_mapConnectivityControllerStateIsReset() { Application application = mock(Application.class); MapboxNavigation navigation = mock(MapboxNavigation.class); MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); + MapOfflineManager mapOfflineManager = mock(MapOfflineManager.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController, + mapOfflineManager); Boolean defaultState = null; viewModel.onDestroy(false); @@ -64,7 +84,9 @@ public void updateRoute_navigationIsNotUpdatedWhenChangingConfigurations() { MapboxNavigation navigation = mock(MapboxNavigation.class); DirectionsRoute route = mock(DirectionsRoute.class); MapConnectivityController mockedConnectivityController = mock(MapConnectivityController.class); - NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController); + MapOfflineManager mapOfflineManager = mock(MapOfflineManager.class); + NavigationViewModel viewModel = new NavigationViewModel(application, navigation, mockedConnectivityController, + mapOfflineManager); viewModel.onDestroy(true); viewModel.updateRoute(route); From 17d75513bef83a625b3e7595e0e6edb53211b2c9 Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Thu, 16 May 2019 08:01:53 -0400 Subject: [PATCH 17/19] bump mapboxNavigator to 6.2.0 version and cleanup --- .../activity/OfflineRegionDownloadActivity.kt | 10 +++++----- .../navigationui/NavigationLauncherActivity.java | 14 +++++++------- build.gradle | 2 -- gradle/dependencies.gradle | 2 +- .../ui/v5/NavigationOfflineDatabaseCallback.java | 4 ---- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt index 09ba06d2701..7384908bfff 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/OfflineRegionDownloadActivity.kt @@ -219,11 +219,11 @@ class OfflineRegionDownloadActivity : AppCompatActivity(), RouteTileDownloadList //val minZoom: Double = mapboxMap.cameraPosition.zoom //val maxZoom: Double = mapboxMap.maxZoomLevel val pixelRatio: Float = this.resources.displayMetrics.density - //val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( - // styleUrl, bounds, minZoom, maxZoom, pixelRatio) - // TODO Testing downloading a Geometry and using OfflineGeometryRegionDefinition as definition - val definition: OfflineGeometryRegionDefinition = OfflineGeometryRegionDefinition( - styleUrl, geometry, minZoom, maxZoom, pixelRatio) + val definition: OfflineTilePyramidRegionDefinition = OfflineTilePyramidRegionDefinition( + styleUrl, bounds, minZoom, maxZoom, pixelRatio) + // TODO Testing downloading a Geometry using OfflineGeometryRegionDefinition as definition + //val definition: OfflineGeometryRegionDefinition = OfflineGeometryRegionDefinition( + // styleUrl, geometry, minZoom, maxZoom, pixelRatio) val metadata: ByteArray val jsonObject: JSONObject = JSONObject() diff --git a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java index 9e4ccd130d4..9abfe9beed9 100644 --- a/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java +++ b/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java @@ -4,7 +4,6 @@ import android.content.SharedPreferences; import android.location.Location; import android.os.Bundle; -import android.os.Environment; import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -44,7 +43,6 @@ import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.services.android.navigation.testapp.NavigationSettingsActivity; import com.mapbox.services.android.navigation.testapp.R; -import com.mapbox.services.android.navigation.ui.v5.MapOfflineOptions; import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher; import com.mapbox.services.android.navigation.ui.v5.NavigationLauncherOptions; import com.mapbox.services.android.navigation.ui.v5.camera.CameraUpdateMode; @@ -356,11 +354,13 @@ private void launchNavigationWithRoute() { if (!offlineVersion.isEmpty()) { optionsBuilder.offlineRoutingTilesVersion(offlineVersion); } - // TODO Testing merging previously downloaded region - File downloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); - String databaseFilePath = downloadDirectory + "/" + "kingfarm.db"; - String offlineStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; - optionsBuilder.offlineMapOptions(new MapOfflineOptions(databaseFilePath, offlineStyleUrl)); + // TODO Testing dynamic offline + /** + * File downloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + * String databaseFilePath = downloadDirectory + "/" + "kingfarm.db"; + * String offlineStyleUrl = "mapbox://styles/mapbox/navigation-guidance-day-v4"; + * optionsBuilder.offlineMapOptions(new MapOfflineOptions(databaseFilePath, offlineStyleUrl)); + */ NavigationLauncher.startNavigation(this, optionsBuilder.build()); } diff --git a/build.gradle b/build.gradle index bee52a4bd72..6a2cb71232e 100644 --- a/build.gradle +++ b/build.gradle @@ -31,8 +31,6 @@ task testReport(type: TestReport, group: 'Build') { allprojects { repositories { - // TODO Remove when Maps SDK is released - maven { url 'https://oss.jfrog.org/artifactory/oss-snapshot-local/' } google() mavenCentral() jcenter() diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index ad8fe41249d..9e035458a28 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -12,7 +12,7 @@ ext { mapboxSdkServices : '4.8.0', mapboxEvents : '4.4.1', mapboxCore : '1.2.0', - mapboxNavigator : 'route_buffer-SNAPSHOT-7', + mapboxNavigator : '6.2.0', mapboxCrashMonitor : '2.0.0', mapboxAnnotationPlugin : '0.6.0', mapboxSearchSdk : '0.1.0-SNAPSHOT', diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java index e89b6c56d3b..97a8a0da93f 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/NavigationOfflineDatabaseCallback.java @@ -16,15 +16,11 @@ class NavigationOfflineDatabaseCallback implements OfflineDatabaseLoadedCallback @Override public void onComplete() { - // TODO Remove debug log after testing - Timber.d("NavigationOfflineDatabaseCallback#onComplete"); navigation.addProgressChangeListener(mapOfflineManager); } @Override public void onError(String error) { - // TODO Remove debug log after testing - Timber.d("NavigationOfflineDatabaseCallback#onError %s", error); Timber.e(error); } From edf8306e7973fdda9f8fd0f95cd2dbe3c7223fcb Mon Sep 17 00:00:00 2001 From: Guardiola31337 Date: Thu, 16 May 2019 08:26:20 -0400 Subject: [PATCH 18/19] add pr changelog entry --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3863bbf56a..ed3df274bea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ Mapbox welcomes participation and contributions from everyone. -### v0.38.0 - May 15, 2019 +### v0.38.0 - May 16, 2019 +* Add option to load offline maps database for NavigationView [#1895](https://github.com/mapbox/mapbox-navigation-android/pull/1895) * Update Maps SDK to 7.4.0 [#1907](https://github.com/mapbox/mapbox-navigation-android/pull/1907) * Added walking options [#1934](https://github.com/mapbox/mapbox-navigation-android/pull/1934) * SoundButton clicklistener wasn't set properly [#1937](https://github.com/mapbox/mapbox-navigation-android/pull/1937) From 43700cbaabb89e1111f4a130b92327fbe7fcf0f6 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Thu, 16 May 2019 09:42:27 -0400 Subject: [PATCH 19/19] Cleanup remaining SDK TODOs and add javadoc --- .../navigation/ui/v5/MapOfflineManager.java | 1 - .../v5/navigation/MapboxNavigator.java | 2 +- .../v5/navigation/NavigationRouteProcessor.java | 10 ++++++---- .../v5/routeprogress/RouteProgress.java | 16 ++++++++++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java index be980d2a3bb..da313ee0941 100644 --- a/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java +++ b/libandroid-navigation-ui/src/main/java/com/mapbox/services/android/navigation/ui/v5/MapOfflineManager.java @@ -47,7 +47,6 @@ public void onProgressChange(Location location, RouteProgress routeProgress) { Geometry currentRouteGeometry = routeProgress.routeGeometryWithBuffer(); if (previousRouteGeometry == null || !previousRouteGeometry.equals(currentRouteGeometry)) { previousRouteGeometry = currentRouteGeometry; - // TODO unique identifier for download metadata? String routeSummary = routeProgress.directionsRoute().routeOptions().requestUuid(); download(routeSummary, previousRouteGeometry, regionDownloadCallback); } diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java index 0817710cfcc..0ec9c59ec8f 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/MapboxNavigator.java @@ -21,7 +21,7 @@ class MapboxNavigator { private static final int INDEX_FIRST_ROUTE = 0; - private static final float GRID_SIZE = 0.0025f; // TODO do these make sense? + private static final float GRID_SIZE = 0.0025f; private static final short BUFFER_DILATION = 1; private final Navigator navigator; private final RouteHandler routeHandler; diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java index 41e16af625c..70551da289a 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/navigation/NavigationRouteProcessor.java @@ -119,10 +119,7 @@ private RouteProgress buildRouteProgressFrom(NavigationStatus status, MapboxNavi .inTunnel(status.getInTunnel()) .currentState(currentRouteState); - // TODO extract to private? - progressBuilder.routeGeometry(routeGeometry); - progressBuilder.routeGeometryWithBuffer(routeGeometryWithBuffer); - + addRouteGeometries(progressBuilder); addVoiceInstructions(status, progressBuilder); addBannerInstructions(status, navigator, progressBuilder); addUpcomingStepPoints(progressBuilder); @@ -157,6 +154,11 @@ private void addUpcomingStepPoints(RouteProgress.Builder progressBuilder) { } } + private void addRouteGeometries(RouteProgress.Builder progressBuilder) { + progressBuilder.routeGeometry(routeGeometry); + progressBuilder.routeGeometryWithBuffer(routeGeometryWithBuffer); + } + private void addVoiceInstructions(NavigationStatus status, RouteProgress.Builder progressBuilder) { VoiceInstruction voiceInstruction = status.getVoiceInstruction(); progressBuilder.voiceInstruction(voiceInstruction); diff --git a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java index 01cbd61df8d..baff0c9dadd 100644 --- a/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java +++ b/libandroid-navigation/src/main/java/com/mapbox/services/android/navigation/v5/routeprogress/RouteProgress.java @@ -189,11 +189,23 @@ public int remainingWaypoints() { @Nullable public abstract RouteProgressState currentState(); - // TODO javadoc + /** + * Returns the current {@link DirectionsRoute} geometry. + * + * @return current route geometry + */ @Nullable public abstract Geometry routeGeometry(); - // TODO javadoc + /** + * Returns the current {@link DirectionsRoute} geometry with a buffer + * that encompasses visible tile surface are while navigating. + *

+ * This {@link Geometry} is ideal for offline downloads of map or routing tile + * data. + * + * @return current route geometry with buffer + */ @Nullable public abstract Geometry routeGeometryWithBuffer();