メインコンテンツまでスキップ

Voice instructions

The Mapbox Navigation SDK allows you to provide prompt and detailed voice instructions to users of your application. You can use a voice instruction to notify the user of an upcoming turn or announce that a faster route has been detected.

The Navigation SDK uses the Mapbox Java SDK's VoiceInstructions class to hold information that should be announced out loud by the device (for example, the street that the user should stay on for a certain distance).

Use default voice instructions

There are two steps to play voice instructions in your application: generate an announcement and then play an announcement.

Create an instance of the speech API

Before you can generate an announcement, you need to instantiate the speech API in your Activity or Fragment:

val speechApi = MapboxSpeechApi(this, Locale.US.toLanguageTag())

Create an instance of the voice instructions player

And before you can play an announcement, you need to instantiate the text-to-speech engine in onCreate of your Activity or onActivityCreated of your Fragment. Do not use lazy initialization for this class since it takes some time to initialize the system services required for on-device speech synthesis. With lazy initialization there is a high risk that said services will not be available when the first instruction has to be played.

lateinit var voiceInstructionsPlayer: MapboxVoiceInstructionsPlayer

override fun onCreate() {
// do your initialization here
voiceInstructionsPlayer = MapboxVoiceInstructionsPlayer(
this,
Locale.US.toLanguageTag()
)
}

Generate and play an announcement

Start by generating the content of the announcement using MapboxSpeechApi. MapboxSpeechApi accepts a VoiceInstructions object and returns a state object that includes the content of the announcement when it is ready or an error and a fallback with the raw announcement.

Then, pass the content of the announcement to MapboxVoiceInstructionsPlayer, which will play the announcement aloud. If you provide a synthesized speech MP3 which was successfully generated with the MapboxSpeechApi, a media player will be used to play the instruction. If not, an onboard speech-to-text engine, obtained using built-in Android APIs, will be used to synthesize the raw announcement's text.

The result of invoking MapboxSpeechApi#generate is returned as a callback containing either a success in the form of SpeechValue or failure in the form of SpeechError.

val speechCallback =
MapboxNavigationConsumer<Expected<SpeechError, SpeechValue>> { expected ->
expected.fold(
{ error ->
// In case of error, a fallback announcement is returned that can be played
// using [MapboxVoiceInstructionsPlayer]
voiceInstructionsPlayer.play(
error.fallback,
voiceInstructionsPlayerCallback
)
},
{ value ->
// The announcement data obtained (synthesized speech mp3 file from Mapbox's API Voice) is played
// using [MapboxVoiceInstructionsPlayer]
voiceInstructionsPlayer.play(
value.announcement,
voiceInstructionsPlayerCallback
)
}
)
}

val voiceInstructionsObserver =
VoiceInstructionsObserver { voiceInstructions ->
// The data obtained must be used to generate the speech announcement
speechAPI.generate(
voiceInstructions,
speechCallback
)
}

The result of invoking MapboxVoiceInstructionsPlayer#play is returned as a callback containing SpeechAnnouncement. This can be used to cleanup any associated files generated before:

val voiceInstructionsPlayerCallback =
MapboxNavigationConsumer<SpeechAnnouncement> { value ->
// Remove already consumed file to free-up space
speechAPI.clean(value)
}
Using only the onboard TTS engine
To decrease latency and cost you can consider using only the MapboxVoiceInstructionsPlayer with manually created SpeechAnnouncements with only announcement text value which will rely only on the usage of the onboard TTS engine.

Start and stop receiving voice events

Register a VoiceInstructionsObserver with MapboxNavigation:

mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)

Don't forget to unregister the observer, cancel any potential in-flight MapboxSpeechApi requests and shutdown MapboxVoiceInstructionsPlayer in onStop or onDestroy:

override fun onDestroy() {
super.onDestroy()
mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
speechApi.cancel()
voiceInstructionsPlayer.shutdown()
}

Also, every time a new route is obtained make sure to cancel any potential in-flight MapboxSpeechApi requests and clear the MapboxVoiceInstructionsPlayer queue:

val routesObserver =
RoutesObserver { result ->
// Every time a new route is obtained make sure to cancel the [MapboxSpeechApi] and
// clear the [MapboxVoiceInstructionsPlayer]
speechApi.cancel()
voiceInstructionsPlayer.clear()
}

Adjust voice instructions volume

To set the volume level of MapboxVoiceInstructionsPlayer you need to provide a value between 0.0 (mute) and 1.0 (max) through SpeechVolume:

// This is used to set the speech volume to mute
voiceInstructionsPlayer.volume(SpeechVolume(0.0f))

Use MapboxAudioGuidance

MapboxAudioGuidance is a higher-level audio guidance service that builds on top of MapboxSpeechApi and MapboxVoiceInstructionsPlayer. It integrates directly with the MapboxNavigationApp lifecycle and handles observer registration, voice instruction prefetching, and mute state persistence automatically — so you don't need to manage these concerns yourself.

Use MapboxAudioGuidance when you want a self-contained audio guidance service. Use the lower-level MapboxSpeechApi and MapboxVoiceInstructionsPlayer directly when you need full manual control over each announcement.

Get or create an instance

The recommended way to use MapboxAudioGuidance is through the registered singleton, which ties into the MapboxNavigationApp lifecycle automatically:

val audioGuidance = MapboxAudioGuidance.getRegisteredInstance()

getRegisteredInstance() returns the existing registered instance if one is already registered, or creates a new one and registers it.

If you need a standalone instance that you manage yourself (for example to register it conditionally or with specific options), use create() instead.

val options = MapboxSpeechApiOptions.Builder()
.gender(VoiceGender.MALE)
.build()

val audioGuidance = MapboxAudioGuidance.create(options)
MapboxNavigationApp.registerObserver(audioGuidance)

Observe audio guidance state

MapboxAudioGuidance exposes a StateFlow of MapboxAudioGuidanceState. Collect this flow to react to guidance state changes without affecting playback.

audioGuidance.stateFlow().collect { state ->
// do something when audio state has changed
}

Control mute state

Call mute(), unmute(), or toggle() to control whether voice instructions are played aloud. When muted, voice instructions are still received and reflected in stateFlow() — only playback is suppressed.

// Mute voice guidance
audioGuidance.mute()

// Unmute voice guidance
audioGuidance.unmute()

// Toggle between muted and unmuted
audioGuidance.toggle()

MapboxAudioGuidance persists the muted state across app sessions using DataStore. When the app is relaunched and MapboxAudioGuidance attaches, it will restore saved mute state automatically.

Customize speech API options

You can configure the voice gender and API base URL via MapboxSpeechApiOptions. Pass options when creating the instance:

val options = MapboxSpeechApiOptions.Builder()
.gender(VoiceGender.FEMALE)
.build()

val audioGuidance = MapboxAudioGuidance.create(options)

You can also update options at runtime :

val updatedOptions = MapboxSpeechApiOptions.Builder()
.gender(VoiceGender.MALE)
.build()

audioGuidance.updateSpeechApiOptions(updatedOptions)

Access the player

Use getCurrentVoiceInstructionsPlayer() to access the underlying MapboxVoiceInstructionsPlayer

audioGuidance.getCurrentVoiceInstructionsPlayer()

Manage the lifecycle

Because MapboxAudioGuidance implements MapboxNavigationObserver, it handles its own cleanup when detached from MapboxNavigationApp. If you registered the instance yourself, unregister it when it is no longer needed:

override fun onDestroy() {
super.onDestroy()
MapboxNavigationApp.unregisterObserver(audioGuidance)
}
この{Type}は役に立ちましたか?