Skip to content

Commit 0f0eb10

Browse files
DzmitryFomchynŁukasz Paczos
and
Łukasz Paczos
authored
Migrate public examples to v3 (#201)
* Remove drop-in examples * Bump Nav SDK to 3.0 in app module * Comment out old activities * Building highlight activity * Camera transition activity * Fetch a route activity * Show location activity * Render route line activity * Speed limit activity * Status activity * Trip progress activity * Voice instructions activity * Turn by turn activity * Preview route activity * MultipleWaypointsActivity * Custom arrival activity * Migrate ShowManeuversActivity * Migrate ShowAlternativeRoutesActivity * ReplayHistoryActivity * Migrate ShowJunctionsActivity * Migrate ShowSignboardActivity * Correct styling * Remove Signboard and Junction views * Update app/src/main/java/com/mapbox/navigation/examples/standalone/turnbyturn/TurnByTurnExperienceActivity.kt Co-authored-by: Łukasz Paczos <[email protected]> * Address review comments * Fir route line layers ordering issue * Update app/src/main/java/com/mapbox/navigation/examples/standalone/location/ShowCurrentLocationActivity.kt Co-authored-by: Łukasz Paczos <[email protected]> * Update app/src/main/java/com/mapbox/navigation/examples/standalone/fetchroute/FetchARouteActivity.kt Co-authored-by: Łukasz Paczos <[email protected]> * Update README.md Co-authored-by: Łukasz Paczos <[email protected]> * Update README.md Co-authored-by: Łukasz Paczos <[email protected]> * Update README.md Co-authored-by: Łukasz Paczos <[email protected]> * Update app/build.gradle Co-authored-by: Łukasz Paczos <[email protected]> * Revert "Use app-preview for nav 3 examples (#198)" This reverts commit 1623155. * Migrate copilot to v3.0.2 * Update app/build.gradle Co-authored-by: Łukasz Paczos <[email protected]> * Fix styling --------- Co-authored-by: Łukasz Paczos <[email protected]>
1 parent 1623155 commit 0f0eb10

File tree

158 files changed

+1766
-4815
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+1766
-4815
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The repository is a collection of examples showing off the [Mapbox Navigation An
1212

1313
## Installation
1414

15-
Make sure you follow the steps under the [Installation](https://docs.mapbox.com/android/beta/navigation/guides/install/) guide. Once you have your **public and secret access tokens ready**, do the following:
15+
Make sure you follow the steps under the [Installation](https://docs.mapbox.com/android/navigation/guides/installation/) guide. Once you have your **public and secret access tokens ready**, do the following:
1616

1717
### [app](app)
1818

@@ -30,6 +30,11 @@ Make sure you follow the steps under the [Installation](https://docs.mapbox.com/
3030
6. Ensure that your secret token is added to [build.gradle](./build.gradle) or to global `gradle.properties` as described in the installation guide.
3131
7. Run the examples under `app`.
3232

33+
## Previous versions
34+
35+
If you're looking for code examples from previous versions of the Navigation SDK, you can access them through the following links:
36+
- [Navigation SDK v2](https://docs.mapbox.com/android/navigation/v2/guides/): https://github.com/mapbox/mapbox-navigation-android-examples/tree/main-v2
37+
- [Navigation SDK v1](https://docs.mapbox.com/android/legacy/navigation/guides/): https://github.com/mapbox/mapbox-navigation-android/tree/v1.6.0/examples/
3338

3439
## Getting Help
3540

app-preview/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ android {
6262

6363
dependencies {
6464
// Mapbox Navigation SDK
65-
implementation "com.mapbox.navigationcore:navigation:3.0.0-rc.5"
66-
implementation "com.mapbox.navigationcore:ui-maps:3.0.0-rc.5"
65+
implementation "com.mapbox.navigationcore:copilot:3.0.2"
66+
implementation "com.mapbox.navigationcore:android:3.0.2"
6767
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.21"
6868
implementation "androidx.core:core-ktx:1.9.0"
6969
implementation "com.google.android.material:material:1.7.0"

app-preview/src/main/AndroidManifest.xml

+3-9
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@
1919
</activity>
2020

2121
<activity
22-
android:name=".location.ShowCurrentLocationActivity"
23-
android:screenOrientation="portrait"
24-
android:exported="false" />
25-
26-
<activity android:name=".fetchroute.FetchARouteActivity"
27-
android:screenOrientation="portrait"
28-
android:exported="false"
29-
/>
22+
android:name=".copilot.CopilotActivity"
23+
android:exported="true" />
3024
</application>
31-
</manifest>
25+
</manifest>

app-preview/src/main/java/com/mapbox/navigation/examples/preview/ExamplesList.kt

+8-12
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,16 @@ package com.mapbox.navigation.examples.preview
22

33
import android.content.Context
44
import androidx.core.content.ContextCompat
5-
import com.mapbox.navigation.examples.preview.fetchroute.FetchARouteActivity
6-
import com.mapbox.navigation.examples.preview.location.ShowCurrentLocationActivity
5+
import com.mapbox.navigation.examples.preview.copilot.CopilotActivity
76

87
fun Context.examplesList() = listOf(
98
MapboxExample(
10-
ContextCompat.getDrawable(this, R.drawable.mapbox_ic_user_current_location),
11-
getString(R.string.title_current_location),
12-
getString(R.string.description_current_location),
13-
ShowCurrentLocationActivity::class.java
14-
),
15-
MapboxExample(
16-
ContextCompat.getDrawable(this, R.drawable.mapbox_screenshot_fetch_a_route),
17-
getString(R.string.title_fetch_route),
18-
getString(R.string.description_fetch_route),
19-
FetchARouteActivity::class.java
9+
ContextCompat.getDrawable(
10+
this,
11+
R.drawable.mapbox_screenshot_copilot
12+
),
13+
getString(R.string.title_copilot),
14+
getString(R.string.description_copilot),
15+
CopilotActivity::class.java
2016
),
2117
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
package com.mapbox.navigation.examples.preview.copilot
2+
3+
import android.annotation.SuppressLint
4+
import android.os.Bundle
5+
import android.util.Log
6+
import android.widget.Toast
7+
import androidx.appcompat.app.AppCompatActivity
8+
import androidx.core.view.isVisible
9+
import androidx.lifecycle.ViewModelProvider
10+
import com.mapbox.api.directions.v5.models.RouteOptions
11+
import com.mapbox.geojson.Point
12+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
13+
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
14+
import com.mapbox.navigation.base.extensions.applyLanguageAndVoiceUnitOptions
15+
import com.mapbox.navigation.base.options.CopilotOptions
16+
import com.mapbox.navigation.base.options.NavigationOptions
17+
import com.mapbox.navigation.base.route.NavigationRoute
18+
import com.mapbox.navigation.base.route.NavigationRouterCallback
19+
import com.mapbox.navigation.base.route.RouterFailure
20+
import com.mapbox.navigation.base.route.RouterOrigin
21+
import com.mapbox.navigation.copilot.HistoryPoint
22+
import com.mapbox.navigation.copilot.MapboxCopilot
23+
import com.mapbox.navigation.copilot.SearchResultUsed
24+
import com.mapbox.navigation.copilot.SearchResultUsedEvent
25+
import com.mapbox.navigation.copilot.SearchResults
26+
import com.mapbox.navigation.copilot.SearchResultsEvent
27+
import com.mapbox.navigation.core.DeveloperMetadata
28+
import com.mapbox.navigation.core.DeveloperMetadataObserver
29+
import com.mapbox.navigation.core.MapboxNavigation
30+
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
31+
import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
32+
import com.mapbox.navigation.core.lifecycle.requireMapboxNavigation
33+
import com.mapbox.navigation.core.telemetry.events.FeedbackEvent
34+
import com.mapbox.navigation.core.trip.session.NavigationSessionState
35+
import com.mapbox.navigation.core.trip.session.NavigationSessionStateObserver
36+
import com.mapbox.navigation.examples.preview.R
37+
import com.mapbox.navigation.examples.preview.databinding.MapboxActivityCopilotBinding
38+
39+
/**
40+
* This example shows how to integrate and work with [MapboxCopilot].
41+
* See [CopilotViewModel] to learn about [MapboxCopilot]'s lifecycle and
42+
* when to [MapboxCopilot.start] / [MapboxCopilot.stop].
43+
*
44+
* Copilot is a [MapboxNavigationObserver], so it's tied to the [MapboxNavigation] lifecycle automatically.
45+
* We recommended tracking the [DeveloperMetadata.copilotSessionId] (see [DeveloperMetadataObserver]) so that
46+
* Mapbox teams can better act on specific end-user feedback.
47+
* This ID helps Mapbox teams find the respective traces and troubleshoot issues faster.
48+
*
49+
* **As the application developer, you are responsible for communicating to drivers about the data that is being
50+
* collected from their drives, including what kind of data is being collected and when it is collected.**
51+
*
52+
* Nav SDK exposes configuration settings (see [NavigationOptions.copilotOptions]) to use Copilot in two ways:
53+
* 1) Automatic data collection:
54+
* - Enable Copilot for all trips performed by a specific driver (default option).
55+
* 2) Manual data collection:
56+
* - Copilot data is only sent when an end user submits negative feedback about a specific route to help
57+
* take action on the issue.
58+
* Data collection for Copilot is tightly coupled to the Navigation SDK Feedback, which means this is only effective
59+
* if the feedback events are pushed through [MapboxNavigation] Feedback APIs
60+
* (see [Feedback documentation](https://docs.mapbox.com/android/navigation/guides/feedback/) and
61+
* [MapboxNavigation.postUserFeedback] / [MapboxNavigation.provideFeedbackMetadataWrapper]).
62+
*
63+
* If you would like to provide search analytics into Copilot, you can send the Search events over to
64+
* Copilot (see [MapboxCopilot.push]).
65+
* This information would include whether a routable point for navigation was available.
66+
* Copilot helps understand the impact of search results to a navigation session (arrival experience, routable points).
67+
*
68+
* WARNING: Mapbox Copilot is currently in public-preview. Copilot-related entities and APIs are currently marked
69+
* as [ExperimentalPreviewMapboxNavigationAPI] and subject to change.
70+
* These markings will be removed when the feature is generally available.
71+
*
72+
* Copilot is a library included in the Navigation SDK that processes full-trip-trace longitude and
73+
* latitude data ("**Copilot**"). Copilot is turned off by default, and can be enabled by you at the
74+
* application-developer level to improve feedback resolution. If you enable Copilot, your organization is responsible
75+
* for obtaining and maintaining all necessary consents and permissions, including providing notice to and obtaining your end
76+
* users' affirmative, expressed consent before any access or use of Copilot.
77+
*
78+
* Before running the example, insert your Mapbox access token in the correct place
79+
* inside [app-preview/src/main/res/values/mapbox_access_token.xml]. If the XML file has not already been created,
80+
* add the file to the mentioned location, then add the following content to it:
81+
*
82+
* <?xml version="1.0" encoding="utf-8"?>
83+
* <resources xmlns:tools="http://schemas.android.com/tools">
84+
* <string name="mapbox_access_token"><PUT_YOUR_ACCESS_TOKEN_HERE></string>
85+
* </resources>
86+
*
87+
* The following steps explain how to use the example:
88+
* - Start the example
89+
* - Look at how Navigation session state is Idle
90+
* - Select the Play button to start a Free Drive trip session
91+
* - Look at how Navigation session state changes to Free Drive and the Copilot session ID is generated
92+
* - Select the Push Feedback button to push FeedbackEvent
93+
* - Select the Push Search button to push SearchResultsEvent and SearchResultUsedEvent
94+
* - Select the Set Route button to transition the session to Active Guidance
95+
* - Look at how Navigation session state changes to Active Guidance and the Copilot session ID is re-generated
96+
* - Select the Push Feedback button to push FeedbackEvent
97+
* - Select the Push Search button to push SearchResultsEvent and SearchResultUsedEvent
98+
* - Select the Stop button to transition the session to Free Drive
99+
* - Look at how Navigation session state changes to Active Guidance and the Copilot session ID is re-generated
100+
* - Select the Stop button to transition the session to Idle
101+
* - Look at how Navigation session state changes to Idle and the Copilot session ID is now empty
102+
*/
103+
104+
@SuppressLint("SetTextI18n")
105+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
106+
class CopilotActivity : AppCompatActivity() {
107+
108+
private val routeCoordinates = listOf(
109+
Point.fromLngLat(-122.4934801, 37.7721532),
110+
Point.fromLngLat(-122.4850055, 37.7801765),
111+
)
112+
113+
private lateinit var binding: MapboxActivityCopilotBinding
114+
private lateinit var copilotViewModel: CopilotViewModel
115+
private var navigationSessionState: NavigationSessionState = NavigationSessionState.Idle
116+
117+
private val navigationSessionStateObserver = NavigationSessionStateObserver {
118+
navigationSessionState = it
119+
val sessionStateText = "Navigation session state:"
120+
when (it) {
121+
is NavigationSessionState.Idle -> {
122+
binding.navigationSessionState.text =
123+
"$sessionStateText Idle"
124+
binding.startStopNavigation.setImageResource(R.drawable.ic_start)
125+
binding.fetchRoutes.isVisible = false
126+
binding.feedbackPush.isVisible = false
127+
binding.searchPush.isVisible = false
128+
}
129+
is NavigationSessionState.FreeDrive -> {
130+
binding.navigationSessionState.text =
131+
"$sessionStateText Free Drive"
132+
binding.startStopNavigation.setImageResource(R.drawable.ic_stop)
133+
binding.fetchRoutes.isVisible = true
134+
binding.feedbackPush.isVisible = true
135+
binding.searchPush.isVisible = true
136+
}
137+
is NavigationSessionState.ActiveGuidance -> {
138+
binding.navigationSessionState.text =
139+
"$sessionStateText Active Guidance"
140+
binding.startStopNavigation.setImageResource(R.drawable.ic_stop)
141+
binding.fetchRoutes.isVisible = false
142+
binding.feedbackPush.isVisible = true
143+
binding.searchPush.isVisible = true
144+
}
145+
}
146+
}
147+
private val developerMetadataObserver = DeveloperMetadataObserver {
148+
val copilotSessionIdText = "Copilot session ID:"
149+
binding.copilotSessionId.text = "$copilotSessionIdText ${it.copilotSessionId}"
150+
}
151+
private val mapboxNavigation by requireMapboxNavigation(
152+
onCreatedObserver = object : MapboxNavigationObserver {
153+
override fun onAttached(mapboxNavigation: MapboxNavigation) {
154+
mapboxNavigation.registerNavigationSessionStateObserver(
155+
navigationSessionStateObserver
156+
)
157+
mapboxNavigation.registerDeveloperMetadataObserver(developerMetadataObserver)
158+
}
159+
160+
override fun onDetached(mapboxNavigation: MapboxNavigation) {
161+
mapboxNavigation.unregisterNavigationSessionStateObserver(
162+
navigationSessionStateObserver
163+
)
164+
mapboxNavigation.unregisterDeveloperMetadataObserver(developerMetadataObserver)
165+
}
166+
}
167+
) {
168+
MapboxNavigationApp.setup(
169+
NavigationOptions.Builder(this)
170+
.copilotOptions(
171+
// Set shouldSendHistoryOnlyWithFeedback to true if you want to sent Copilot traces
172+
// only when an end user submits negative feedback
173+
CopilotOptions.Builder().shouldSendHistoryOnlyWithFeedback(false).build()
174+
)
175+
.build()
176+
)
177+
}
178+
179+
@SuppressLint("MissingPermission")
180+
override fun onCreate(savedInstanceState: Bundle?) {
181+
super.onCreate(savedInstanceState)
182+
binding = MapboxActivityCopilotBinding.inflate(layoutInflater)
183+
setContentView(binding.root)
184+
185+
copilotViewModel = ViewModelProvider(this)[CopilotViewModel::class.java]
186+
187+
binding.startStopNavigation.setOnClickListener {
188+
when (navigationSessionState) {
189+
is NavigationSessionState.Idle -> {
190+
mapboxNavigation.setNavigationRoutes(emptyList())
191+
mapboxNavigation.startTripSession()
192+
}
193+
is NavigationSessionState.FreeDrive -> {
194+
mapboxNavigation.stopTripSession()
195+
}
196+
is NavigationSessionState.ActiveGuidance -> {
197+
mapboxNavigation.setNavigationRoutes(emptyList())
198+
}
199+
}
200+
}
201+
202+
binding.fetchRoutes.setOnClickListener {
203+
fetchRoute()
204+
}
205+
206+
binding.feedbackPush.setOnClickListener {
207+
// Call postUserFeedback every time user submits feedback
208+
mapboxNavigation.postUserFeedback(
209+
FeedbackEvent.POSITIONING_ISSUE,
210+
"Test feedback",
211+
FeedbackEvent.UI,
212+
"encoded_screenshot",
213+
)
214+
Toast.makeText(this, "Feedback event pushed!", Toast.LENGTH_SHORT).show()
215+
}
216+
217+
binding.searchPush.setOnClickListener {
218+
// Push a SearchResultsEvent every time Search results response is retrieved
219+
MapboxCopilot.push(
220+
SearchResultsEvent(
221+
SearchResults("mapbox", "https://mapbox.com", null, null, "?query=test1", null)
222+
)
223+
)
224+
// Push a SearchResultUsedEvent every time a Search result is selected
225+
MapboxCopilot.push(
226+
SearchResultUsedEvent(
227+
SearchResultUsed(
228+
"mapbox",
229+
"test_id",
230+
"mapbox_poi",
231+
"mapbox_address",
232+
HistoryPoint(-77.03396910343713, 38.89992797324407),
233+
null,
234+
)
235+
)
236+
)
237+
Toast.makeText(this, "Search events pushed!", Toast.LENGTH_SHORT).show()
238+
}
239+
}
240+
241+
private fun fetchRoute() {
242+
mapboxNavigation.requestRoutes(
243+
RouteOptions.builder()
244+
.applyDefaultNavigationOptions()
245+
.applyLanguageAndVoiceUnitOptions(this)
246+
.alternatives(false)
247+
.coordinatesList(routeCoordinates)
248+
.layersList(listOf(mapboxNavigation.getZLevel(), null))
249+
.build(),
250+
251+
object : NavigationRouterCallback {
252+
override fun onRoutesReady(
253+
routes: List<NavigationRoute>,
254+
@RouterOrigin routerOrigin: String
255+
) {
256+
mapboxNavigation.setNavigationRoutes(routes)
257+
}
258+
259+
override fun onFailure(
260+
reasons: List<RouterFailure>,
261+
routeOptions: RouteOptions
262+
) {
263+
Log.d(LOG_TAG, "onFailure: $reasons")
264+
}
265+
266+
override fun onCanceled(
267+
routeOptions: RouteOptions,
268+
@RouterOrigin routerOrigin: String
269+
) {
270+
Log.d(LOG_TAG, "onCanceled")
271+
}
272+
}
273+
)
274+
}
275+
276+
private companion object {
277+
val LOG_TAG: String = CopilotActivity::class.java.simpleName
278+
}
279+
}

0 commit comments

Comments
 (0)