Skip to main content

Overview

The TextToSpeechController class provides a simplified interface for converting text to speech using Android’s TextToSpeech engine. It is configured for Spanish (Chile) locale and handles initialization automatically. Location: com.demodogo.ev_sum_2.services.TextToSpeechController

Constructor

class TextToSpeechController(context: Context)
context
Context
required
The Android application context required for initializing the TextToSpeech engine

Initialization

The controller automatically initializes the TextToSpeech engine on creation:
  • Language: Set to Spanish (Chile) - "es-CL"
  • Readiness: Tracked internally to ensure the engine is ready before speaking
  • Queue Mode: Uses QUEUE_FLUSH to replace any ongoing speech
val ttsController = TextToSpeechController(context)
// Engine initializes automatically in the background

Methods

speak

Converts the provided text to speech.
fun speak(text: String)
text
String
required
The text to speak. Will be trimmed before processing.
The method performs automatic validation:
  • Returns silently if the TTS engine is not ready
  • Returns silently if the text is blank after trimming
  • Uses QUEUE_FLUSH mode, which stops any ongoing speech before starting new speech

Usage Example

val ttsController = TextToSpeechController(context)

// Speak a phrase
ttsController.speak("Hola, ¿cómo estás?")

// Blank text is ignored
ttsController.speak("   ") // Does nothing

// New speech interrupts ongoing speech
ttsController.speak("Primera frase")
ttsController.speak("Segunda frase") // Interrupts and replaces first phrase

stop

Stops any ongoing speech immediately.
fun stop()
This method interrupts and clears any speech currently being spoken.

Usage Example

val ttsController = TextToSpeechController(context)

ttsController.speak("Esta es una frase muy larga que tardará en completarse")

// Stop speaking immediately
ttsController.stop()

destroy

Releases all resources used by the TextToSpeech engine.
fun destroy()
Always call destroy() when you’re done with the controller to free up system resources. This should typically be done in your Activity’s or Fragment’s onDestroy() method.
This method:
  1. Stops any ongoing speech
  2. Shuts down the TTS engine
  3. Nullifies the engine reference

Usage Example

override fun onDestroy() {
    super.onDestroy()
    ttsController.destroy()
}

Properties

The controller maintains internal state:
  • tts: TextToSpeech? - The underlying TTS engine instance
  • ready: Boolean - Indicates whether the engine is initialized and ready
These properties are private and managed automatically. The ready flag ensures that speak() only works when the engine is properly initialized.

Speech Configuration

The controller uses these settings:
SettingValueDescription
Languagees-CLSpanish (Chile)
Queue ModeQUEUE_FLUSHReplaces ongoing speech
Utterance ID"phrase_tts"Identifier for the speech utterance

Complete Usage Example

class PhraseDetailActivity : AppCompatActivity() {
    private lateinit var ttsController: TextToSpeechController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_phrase_detail)
        
        // Initialize TTS controller
        ttsController = TextToSpeechController(this)
        
        // Speak button
        findViewById<Button>(R.id.speakButton).setOnClickListener {
            val phraseText = findViewById<TextView>(R.id.phraseText).text.toString()
            ttsController.speak(phraseText)
        }
        
        // Stop button
        findViewById<Button>(R.id.stopButton).setOnClickListener {
            ttsController.stop()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // Clean up TTS resources
        ttsController.destroy()
    }
}

ViewModel Integration

class PhraseViewModel(application: Application) : AndroidViewModel(application) {
    private val ttsController = TextToSpeechController(application)

    fun speakPhrase(text: String) {
        ttsController.speak(text)
    }

    fun stopSpeaking() {
        ttsController.stop()
    }

    override fun onCleared() {
        super.onCleared()
        ttsController.destroy()
    }
}

Lifecycle Management

Follow these best practices for managing the TTS controller lifecycle:
  1. Create the controller early (e.g., in onCreate()) to allow initialization time
  2. Use speak() and stop() as needed during the component’s lifecycle
  3. Destroy in onDestroy() or onCleared() to release resources
// Activity lifecycle
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ttsController = TextToSpeechController(this)
}

override fun onDestroy() {
    super.onDestroy()
    ttsController.destroy()
}

// ViewModel lifecycle
class MyViewModel(app: Application) : AndroidViewModel(app) {
    private val ttsController = TextToSpeechController(app)
    
    override fun onCleared() {
        super.onCleared()
        ttsController.destroy()
    }
}

Error Handling

The controller handles initialization failures gracefully:
  • If TTS initialization fails, the ready flag remains false
  • All speak() calls will return silently when not ready
  • No exceptions are thrown to the caller
// Safe to call even if TTS initialization failed
ttsController.speak("Some text") // Returns silently if not ready

Language Support

The controller is configured for Spanish (Chile):
tts?.language = Locale.forLanguageTag("es-CL")
If you need to support different languages, you can modify the controller or create language-specific variants.

Queue Behavior

The controller uses QUEUE_FLUSH mode, which means:
  • New speech interrupts and replaces any ongoing speech
  • Previous speech in the queue is discarded
ttsController.speak("Primera frase")
ttsController.speak("Segunda frase") // Immediately stops "Primera frase"
If you need to queue multiple phrases sequentially, you would need to modify the controller to use TextToSpeech.QUEUE_ADD instead.

See Also

Build docs developers (and LLMs) love