summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanesfeder <dan.nesfeder@mapbox.com>2017-10-11 11:15:10 -0400
committerdanesfeder <dan.nesfeder@mapbox.com>2017-10-11 11:15:10 -0400
commit68c78d5b5b886b2da9dfc45a211116e62bd17f55 (patch)
tree504c146e37b904a9cc5f380f9c4a103fd439516e
parent98a47884f06a8f165a2c15a54f82b356c8ef23d8 (diff)
downloadqtlocation-mapboxgl-68c78d5b5b886b2da9dfc45a211116e62bd17f55.tar.gz
Add navigation view example
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/NavigationViewActivity.java317
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_navigation_view.xml47
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml1
-rw-r--r--platform/android/dependencies.gradle8
7 files changed, 396 insertions, 4 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index 67939b5144..2e14478fb5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -60,6 +60,17 @@ dependencies {
compile rootProject.ext.dep.supportAppcompatV7
compile rootProject.ext.dep.supportRecyclerView
+ // Navigation SDK UI
+ compile ('com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.7.0-SNAPSHOT@aar') {
+ transitive = true
+ exclude group: 'com.mapbox.mapboxsdk', module: 'mapbox-android-sdk'
+ }
+
+ // Location Layer Plugin
+ compile ('com.mapbox.mapboxsdk:mapbox-android-plugin-locationlayer:0.1.0@aar') {
+ exclude group: 'com.mapbox.mapboxsdk', module: 'mapbox-android-sdk'
+ }
+
// Leak Canary
debugCompile rootProject.ext.dep.leakCanaryDebug
releaseCompile rootProject.ext.dep.leakCanaryRelease
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index bf97749b9e..ced18e012e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -24,6 +24,17 @@
</intent-filter>
</activity>
<activity
+ android:name=".activity.NavigationViewActivity"
+ android:description="@string/navigation_view"
+ android:label="@string/navigation_view">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_basic"/>
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity"/>
+ </activity>
+ <activity
android:name=".activity.infowindow.InfoWindowActivity"
android:description="@string/description_info_window"
android:label="@string/activity_info_window">
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/NavigationViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/NavigationViewActivity.java
new file mode 100644
index 0000000000..72ac7c894e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/NavigationViewActivity.java
@@ -0,0 +1,317 @@
+package com.mapbox.mapboxsdk.testapp.activity;
+
+import android.location.Location;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.BaseTransientBottomBar;
+import android.support.design.widget.Snackbar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.ProgressBar;
+import android.widget.Switch;
+import android.widget.Toast;
+
+import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.location.LocationSource;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.Constants;
+import com.mapbox.services.android.navigation.ui.v5.NavigationLauncher;
+import com.mapbox.services.android.navigation.ui.v5.route.NavigationMapRoute;
+import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
+import com.mapbox.services.android.telemetry.location.LocationEngine;
+import com.mapbox.services.android.telemetry.location.LocationEngineListener;
+import com.mapbox.services.api.directions.v5.models.DirectionsResponse;
+import com.mapbox.services.api.directions.v5.models.DirectionsRoute;
+import com.mapbox.services.commons.geojson.LineString;
+import com.mapbox.services.commons.models.Position;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import timber.log.Timber;
+
+import static com.mapbox.services.android.telemetry.location.LocationEnginePriority.HIGH_ACCURACY;
+
+public class NavigationViewActivity extends AppCompatActivity implements OnMapReadyCallback,
+ MapboxMap.OnMapLongClickListener, LocationEngineListener, Callback<DirectionsResponse> {
+
+ private static final int CAMERA_ANIMATION_DURATION = 1000;
+
+ private LocationLayerPlugin locationLayer;
+ private LocationEngine locationEngine;
+ private NavigationMapRoute mapRoute;
+ private MapboxMap mapboxMap;
+
+ private MapView mapView;
+ private Button launchRouteBtn;
+ private ProgressBar loading;
+ private Switch demoSwitch;
+
+ private Marker currentMarker;
+ private Position currentPosition;
+ private Position destination;
+ private DirectionsRoute route;
+
+ private boolean locationFound;
+ private boolean shouldSimulateRoute;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_navigation_view);
+ bind();
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ demoSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ shouldSimulateRoute = checked;
+ }
+ });
+ launchRouteBtn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ launchNavigationWithRoute();
+ }
+ });
+ }
+
+ private void bind() {
+ mapView = findViewById(R.id.mapView);
+ launchRouteBtn = findViewById(R.id.launchRouteBtn);
+ loading = findViewById(R.id.loading);
+ demoSwitch = findViewById(R.id.demoSwitch);
+ }
+
+ @SuppressWarnings({"MissingPermission"})
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ if (locationLayer != null) {
+ locationLayer.onStart();
+ }
+ }
+
+ @SuppressWarnings({"MissingPermission"})
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ if (locationEngine != null) {
+ locationEngine.addLocationEngineListener(this);
+ if (!locationEngine.isConnected()) {
+ locationEngine.activate();
+ }
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ if (locationEngine != null) {
+ locationEngine.removeLocationEngineListener(this);
+ }
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ if (locationLayer != null) {
+ locationLayer.onStop();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ if (locationEngine != null) {
+ locationEngine.removeLocationUpdates();
+ locationEngine.deactivate();
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ this.mapboxMap.setOnMapLongClickListener(this);
+ initLocationEngine();
+ initLocationLayer();
+ initMapRoute();
+ }
+
+ @Override
+ public void onMapLongClick(@NonNull LatLng point) {
+ destination = Position.fromCoordinates(point.getLongitude(), point.getLatitude());
+ launchRouteBtn.setEnabled(false);
+ loading.setVisibility(View.VISIBLE);
+ setCurrentMarkerPosition(point);
+ if (currentPosition != null) {
+ fetchRoute();
+ }
+ }
+
+ @SuppressWarnings({"MissingPermission"})
+ @Override
+ public void onConnected() {
+ locationEngine.requestLocationUpdates();
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ currentPosition = Position.fromCoordinates(location.getLongitude(), location.getLatitude());
+ onLocationFound(location);
+ }
+
+ @Override
+ public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
+ if (validRouteResponse(response)) {
+ route = response.body().getRoutes().get(0);
+ launchRouteBtn.setEnabled(true);
+ mapRoute.addRoute(route);
+ boundCameraToRoute();
+ hideLoading();
+ }
+ }
+
+ @Override
+ public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
+ Timber.e(throwable.getMessage());
+ }
+
+ @SuppressWarnings({"MissingPermission"})
+ private void initLocationEngine() {
+ locationEngine = new LocationSource(this);
+ locationEngine.setPriority(HIGH_ACCURACY);
+ locationEngine.setInterval(0);
+ locationEngine.setFastestInterval(1000);
+ locationEngine.addLocationEngineListener(this);
+ locationEngine.activate();
+
+ if (locationEngine.getLastLocation() != null) {
+ Location lastLocation = locationEngine.getLastLocation();
+ currentPosition = Position.fromCoordinates(lastLocation.getLongitude(), lastLocation.getLatitude());
+ }
+ }
+
+ @SuppressWarnings({"MissingPermission"})
+ private void initLocationLayer() {
+ locationLayer = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
+ locationLayer.setLocationLayerEnabled(LocationLayerMode.COMPASS);
+ }
+
+ private void initMapRoute() {
+ mapRoute = new NavigationMapRoute(mapView, mapboxMap);
+ }
+
+ private void fetchRoute() {
+ NavigationRoute.builder()
+ .accessToken(Mapbox.getAccessToken())
+ .origin(currentPosition)
+ .destination(destination)
+ .build()
+ .getRoute(this);
+ loading.setVisibility(View.VISIBLE);
+ }
+
+ private void launchNavigationWithRoute() {
+ if (route != null) {
+ NavigationLauncher.startNavigation(this, route,
+ null, shouldSimulateRoute);
+ }
+ }
+
+ private boolean validRouteResponse(Response<DirectionsResponse> response) {
+ return response.body() != null
+ && response.body().getRoutes() != null
+ && response.body().getRoutes().size() > 0;
+ }
+
+ private void hideLoading() {
+ if (loading.getVisibility() == View.VISIBLE) {
+ loading.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ private void onLocationFound(Location location) {
+ if (!locationFound) {
+ animateCamera(new LatLng(location.getLatitude(), location.getLongitude()));
+ Snackbar.make(mapView, "Long press map to place waypoint", BaseTransientBottomBar.LENGTH_LONG).show();
+ locationFound = true;
+ hideLoading();
+ }
+ }
+
+ public void boundCameraToRoute() {
+ if (route != null) {
+ List<Position> routeCoords = LineString.fromPolyline(route.getGeometry(),
+ Constants.PRECISION_6).getCoordinates();
+ List<LatLng> bboxPoints = new ArrayList<>();
+ for (Position position : routeCoords) {
+ bboxPoints.add(new LatLng(position.getLatitude(), position.getLongitude()));
+ }
+ if (bboxPoints.size() > 1) {
+ try {
+ LatLngBounds bounds = new LatLngBounds.Builder().includes(bboxPoints).build();
+ animateCameraBbox(bounds, CAMERA_ANIMATION_DURATION, new int[] {50, 500, 50, 335});
+ } catch (InvalidLatLngBoundsException exception) {
+ Toast.makeText(this, "Valid route not found.", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ }
+
+ private void animateCameraBbox(LatLngBounds bounds, int animationTime, int[] padding) {
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
+ padding[0], padding[1], padding[2], padding[3]), animationTime);
+ }
+
+ private void animateCamera(LatLng point) {
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(point, 16), CAMERA_ANIMATION_DURATION);
+ }
+
+ private void setCurrentMarkerPosition(LatLng position) {
+ if (position != null) {
+ if (currentMarker == null) {
+ MarkerViewOptions markerViewOptions = new MarkerViewOptions()
+ .position(position);
+ currentMarker = mapboxMap.addMarker(markerViewOptions);
+ } else {
+ currentMarker.setPosition(position);
+ }
+ }
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
index da3c78b07a..df52ccf727 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
@@ -87,6 +87,11 @@ public class MockLocationEngine extends LocationEngine {
}
}
+ @Override
+ public Type obtainType() {
+ return Type.MOCK;
+ }
+
private static class LocationAnimator extends AnimatorListenerAdapter {
private static final long DURATION_ANIMATION = 10000;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_navigation_view.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_navigation_view.xml
new file mode 100644
index 0000000000..52908d17c0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_navigation_view.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+ <ProgressBar
+ android:id="@+id/loading"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:indeterminate="true"
+ android:visibility="visible"/>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:padding="8dp"
+ android:background="@drawable/demo_switch_background"
+ android:orientation="horizontal"
+ android:elevation="2dp"
+ android:layout_gravity="center_horizontal|top">
+
+ <Switch
+ android:id="@+id/demoSwitch"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Simulate Route"/>
+
+ <Button
+ android:id="@+id/launchRouteBtn"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ android:enabled="false"
+ android:text="Launch Navigation"/>
+
+ </LinearLayout>
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
index 4d1f7eac38..d00d0120ba 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/descriptions.xml
@@ -15,6 +15,7 @@
<string name="description_camera_zoom">Different types of zoom methods</string>
<string name="description_minmax_zoom">Configure a max and min zoomlevel</string>
<string name="description_info_window">Learn how to handle the InfoWindow</string>
+ <string name="navigation_view">Navigation Drop-In UI</string>
<string name="description_add_bulk_markers">Add Markers In Bulk to a Map</string>
<string name="description_camera_animation_types">Showcase the different animation types</string>
<string name="description_visible_bounds">Center the camera around a bounds</string>
diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle
index 521084559f..252b9bae6d 100644
--- a/platform/android/dependencies.gradle
+++ b/platform/android/dependencies.gradle
@@ -1,14 +1,14 @@
ext {
minSdkVersion = 15
- targetSdkVersion = 25
- compileSdkVersion = 25
- buildToolsVersion = "25.0.2"
+ targetSdkVersion = 26
+ compileSdkVersion = 26
+ buildToolsVersion = "26.0.1"
versionCode = 11
versionName = "5.0.0"
mapboxServicesVersion = "2.2.3"
- supportLibVersion = "25.4.0"
+ supportLibVersion = "26.1.0"
espressoVersion = '3.0.1'
testRunnerVersion = '1.0.1'
leakCanaryVersion = '1.5.1'