SpeechSynthesizer

public final class SpeechSynthesizer implements Closeable


Performs on-device text-to-speech audio synthesis.

One client serves every language. SpeechSynthesizerOptions only supplies a default locale; pass a locale to getSupportedVoices to list another language's voices, and the rest of the API follows the VoiceInfo you hand it. There is no reason to close and rebuild the client, or to keep one instance per language — both pay for a Binder reconnect and buy nothing.

Typical usage:

// 1. Create a SpeechSynthesizer with desired options.
val options: SpeechSynthesizerOptions =
speechSynthesizerOptions(Locale.US) {
// Optionally configure a background executor
// setExecutor(myExecutor)
// Optionally fail instead of substituting a voice that is not installed
// setVoiceFallbackEnabled(false)
}
val speechSynthesizer: SpeechSynthesizer = SpeechSynthesis.getClient(options)

// 2. Find a supported voice and check its status.
lifecycleScope.launch {
try {
// Defaults to the options locale. Pass one to switch language:
// speechSynthesizer.getSupportedVoices(Locale.FRANCE)
val supportedVoices: List<VoiceInfo> = speechSynthesizer.getSupportedVoices()
val voiceToUse: VoiceInfo? =
supportedVoices.firstOrNull { it.gender == VoiceInfo.Gender.FEMALE }

if (voiceToUse != null) {
val status: Int = speechSynthesizer.checkStatus(voiceToUse)
if (status == FeatureStatus.DOWNLOADABLE) {
// 3. If needed, download the voice model.
speechSynthesizer.download(voiceToUse).collect { downloadStatus ->
when (downloadStatus) {
is DownloadStatus.DownloadCompleted -> {
// Model is ready, start synthesis.
startMySynthesis(speechSynthesizer, voiceToUse)
}
is DownloadStatus.DownloadFailed -> {
// Handle download failure.
}
is DownloadStatus.DownloadProgress -> {
// Handle download progress.
}
else -> {}
}
}
} else if (status == FeatureStatus.AVAILABLE) {
// Model is ready, start synthesis.
startMySynthesis(speechSynthesizer, voiceToUse)
} else {
// Handle other statuses like DOWNLOADING or UNAVAILABLE.
}
}
} finally {
// 5. Release resources. Closing outside the coroutine would tear down the client
// while the work above is still in flight.
speechSynthesizer.close()
}
}

// 4. Define your synthesis logic.
suspend fun startMySynthesis(synthesizer: SpeechSynthesizer, voice: VoiceInfo) {
// Create a request and collect the responses.
val request = SpeechSynthesizerRequest(
input = SpeechSynthesizerRequest.Input.Text("Hello, world!", voice),
audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
synthesizer.synthesize(request).collect { response ->
// Process the responses.
when (response) {
is SpeechSynthesizerResponse.StatusUpdate -> {
when (response.status) {
SpeechSynthesizerResponse.Status.START -> { /* Started playing */}
SpeechSynthesizerResponse.Status.DONE -> { /* Playback finished */}
else -> {}
}
}
is SpeechSynthesizerResponse.AudioAvailable -> {
// Handle a chunk of synthesized audio
}
is SpeechSynthesizerResponse.Error -> {
// Handle synthesis error. With setVoiceFallbackEnabled(false), a voice that
// is not installed arrives here as ERROR_NOT_INSTALLED_YET.
}
}
}
}

Summary

Public methods

final @FeatureStatus int

Checks the availability status of a specific VoiceInfo.

void

Releases resources used by this SpeechSynthesizer.

final @NonNull Flow<@NonNull DownloadStatus>

Downloads the model assets required for speech synthesis with the specified VoiceInfo.

final @NonNull List<@NonNull VoiceInfo>

Returns the voices supported for locale, defaulting to the locale configured in SpeechSynthesizerOptions.

final void

Stops any active or pending speech synthesis.

final @NonNull Flow<@NonNull SpeechSynthesizerResponse>

Synthesizes the input text from SpeechSynthesizerRequest into spoken audio.

Public methods

checkStatus

public final @FeatureStatus int checkStatus(@NonNull VoiceInfo voiceInfo)

Checks the availability status of a specific VoiceInfo.

Returns
@FeatureStatus int

A FeatureStatus indicator representing the status of the voice.

close

public void close()

Releases resources used by this SpeechSynthesizer.

Subsequent calls are no-ops.

download

public final @NonNull Flow<@NonNull DownloadStatus> download(@NonNull VoiceInfo voiceInfo)

Downloads the model assets required for speech synthesis with the specified VoiceInfo.

Returns
@NonNull Flow<@NonNull DownloadStatus>

A Flow of DownloadStatus emitting progress updates and the download outcome.

getSupportedVoices

public final @NonNull List<@NonNull VoiceInfo> getSupportedVoices(@NonNull Locale locale)

Returns the voices supported for locale, defaulting to the locale configured in SpeechSynthesizerOptions.

Passing a locale here is cheaper than building a second SpeechSynthesizer: the platform engine and the service connection are locale-independent, so a single instance can serve every language an app needs. Results are cached per locale for the lifetime of the instance.

Parameters
@NonNull Locale locale

the locale to list voices for. A locale without a country (for example Locale.FRENCH) matches every region of that language.

stop

public final void stop()

Stops any active or pending speech synthesis.

synthesize

public final @NonNull Flow<@NonNull SpeechSynthesizerResponse> synthesize(@NonNull SpeechSynthesizerRequest request)

Synthesizes the input text from SpeechSynthesizerRequest into spoken audio.

Parameters
@NonNull SpeechSynthesizerRequest request

The SpeechSynthesizerRequest containing the text input and synthesis configurations.

Returns
@NonNull Flow<@NonNull SpeechSynthesizerResponse>

A Flow of SpeechSynthesizerResponse emitting audio data chunks and playback lifecycle updates.