Skip to main content

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:


MapboxSpeechApi speechApi = new 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.


MapboxVoiceInstructionsPlayer voiceInstructionsPlayer;

@Override
public void onCreate() {
// do your initialization here
voiceInstructionsPlayer = new 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.


MapboxNavigationConsumer<Expected<SpeechValue, SpeechError>> speechCallback = new MapboxNavigationConsumer<Expected<SpeechValue, SpeechError>>() {
@Override
public void accept(Expected<SpeechValue, SpeechError> value) {
if (value instanceof Expected.Success) {
// The announcement data obtained (synthesized speech mp3 file from Mapbox's API Voice) is played
// using MapboxVoiceInstructionsPlayer
voiceInstructionsPlayer.play(
((SpeechValue) ((Expected.Success) value).getValue()).getAnnouncement(),
voiceInstructionsPlayerCallback
);
} else {
// In case of error, a fallback announcement is returned that can be played
// using MapboxVoiceInstructionsPlayer
voiceInstructionsPlayer.play(
((SpeechError) ((Expected.Failure) value).getError()).getFallback(),
voiceInstructionsPlayerCallback
);
}
}
};

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:


MapboxNavigationConsumer<SpeechAnnouncement> voiceInstructionsPlayerCallback = new MapboxNavigationConsumer<SpeechAnnouncement>() {
@Override
public void accept(SpeechAnnouncement value) {
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
protected void 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:


RoutesObserver routesObserver = result -> {
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(new SpeechVolume(0.0f));
Was this page helpful?