tts_android_simple (codi)

configuration


🛠️ Guia pas a pas: Primera app Android amb TTS en català

1. Obrir Android Studio

2. Crear un nou projecte

  • Tria “Empty Activity”.
  • Dona-li un nom, per exemple: urqtejmi_TTSCatalà.
  • Assegura’t que el llenguatge sigui Java (o Kotlin si ho prefereixes).
  • Target SDK: tria API 21 o superior (TextToSpeech funciona des d’API 21).
  • Fes clic a Finish.

3. Editar la interfície (activity_main.xml)

Obre res/layout/activity_main.xml i enganxa aquest codi:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="24dp"
    android:gravity="center">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Escriu el text que vols escoltar"
        android:minLines="4"
        android:gravity="top"
        android:inputType="textMultiLine" />

    <Button
        android:id="@+id/btnSpeak"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Escolta"
        android:layout_marginTop="16dp"/>
</LinearLayout>

4. Afegir la lògica TTS (MainActivity.java)

Obre MainActivity.java i enganxa aquest codi:

package com.exemple.ttscatala;

import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    private TextToSpeech tts;
    private EditText editText;
    private Button btnSpeak;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.editText);
        btnSpeak = findViewById(R.id.btnSpeak);

        tts = new TextToSpeech(this, status -> {
            if (status == TextToSpeech.SUCCESS) {
                int result = tts.setLanguage(new Locale("ca", "ES"));
                if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Toast.makeText(this, "⚠️ Veu catalana no disponible", Toast.LENGTH_LONG).show();
                }
            }
        });

        btnSpeak.setOnClickListener(v -> {
            String text = editText.getText().toString();
            if (!text.isEmpty()) {
                tts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
            }
        });
    }

    @Override
    protected void onDestroy() {
        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
        super.onDestroy();
    }
}

5. Executar l’app

  • Connecta el teu dispositiu Android amb cable USB i activa el mode Desenvolupador.
  • Fes clic a Run ▶️ a Android Studio.
  • Tria el teu dispositiu i espera que s’instal·li.

🎯 Resultat

Ara podràs escriure qualsevol text en català i escoltar-lo amb la veu TTS del sistema (la mateixa que fa servir ReadEra).

Vols que et guiï per afegir funcions com selector de veu, velocitat, o guardar l’últim text llegit? També podem modularitzar-ho per reutilitzar-ho en altres apps.

aqui s’afegeix l’html

<!DOCTYPE html>
<html lang="ca">
<head>
  <meta charset="UTF-8">
  <title>Prova TTS Català</title>
  <style>
    body { font-family: sans-serif; padding: 2em; background: #f0f0f0; }
    textarea { width: 100%; max-width: 600px; height: 150px; font-size: 1.2em; }
    button { font-size: 1.2em; margin-top: 1em; }
  </style>
</head>
<body>
  <h2>Conversor de text a veu (Català)</h2>
  <textarea id="text" placeholder="Escriu el text que vols escoltar...">Bon dia! Com estàs?</textarea><br>
  <button onclick="speak()">Escolta</button>

  <script>
    function speak() {
      const text = document.getElementById('text').value;
      const utterance = new SpeechSynthesisUtterance(text);
      const voices = speechSynthesis.getVoices();
      const catala = voices.find(v => v.lang === 'ca-ES');

      if (catala) {
        utterance.voice = catala;
        utterance.lang = 'ca-ES';
      } else {
        alert("⚠️ No s'ha trobat cap veu catalana disponible.");
      }

      speechSynthesis.speak(utterance);
    }

    // Carrega les veus (pot trigar una mica)
    window.speechSynthesis.onvoiceschanged = () => {};
  </script>
</body>
</html>

MainActivity.kt amb veu english US

package com.example.helloworld

import android.os.Bundle
import android.speech.tts.TextToSpeech
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.helloworld.ui.theme.HelloWorldTheme
import java.util.Locale

class MainActivity : ComponentActivity(), TextToSpeech.OnInitListener {

    private var tts: TextToSpeech? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Inicialitza TextToSpeech
        tts = TextToSpeech(this, this)

        enableEdgeToEdge()
        setContent {
            HelloWorldTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }

    override fun onInit(status: Int) {
        if (status == TextToSpeech.SUCCESS) {
            // Configura l'idioma (anglès, per exemple)
            val result = tts?.setLanguage(Locale.US)

            if (result != TextToSpeech.LANG_MISSING_DATA && result != TextToSpeech.LANG_NOT_SUPPORTED) {
                // Digues el missatge
                tts?.speak("Hello Android!", TextToSpeech.QUEUE_FLUSH, null, null)
            }
        }
    }

    override fun onDestroy() {
        // Allibera els recursos del TTS
        tts?.stop()
        tts?.shutdown()
        super.onDestroy()
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    HelloWorldTheme {
        Greeting("Android")
    }
}

MainActivity.kt amb veu catalana ATENCIÓ AMB EL THEME!!!

package com.example.helloworld

import android.os.Bundle
import android.speech.tts.TextToSpeech
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.helloworld.ui.theme.HelloWorldTheme
import java.util.Locale

class MainActivity : ComponentActivity(), TextToSpeech.OnInitListener {

    private var tts: TextToSpeech? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Inicialitza TextToSpeech
        tts = TextToSpeech(this, this)

        enableEdgeToEdge()
        setContent {
            HelloWorldTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }

    override fun onInit(status: Int) {
        if (status == TextToSpeech.SUCCESS) {
            // Prova d'establir català (pot dependre del motor de TTS del dispositiu)
            val localeCa = Locale("ca", "ES")
            val result = tts?.setLanguage(localeCa)

            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                // Si no hi ha català, fem servir l’idioma per defecte
                tts?.setLanguage(Locale.getDefault())
                tts?.speak("El català no està disponible al teu dispositiu.", TextToSpeech.QUEUE_FLUSH, null, null)
            } else {
                // Parla en català
                tts?.speak("Hola Android! Benvingut a l’aplicació.", TextToSpeech.QUEUE_FLUSH, null, null)
            }
        }
    }

    override fun onDestroy() {
        tts?.stop()
        tts?.shutdown()
        super.onDestroy()
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hola $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    HelloWorldTheme {
        Greeting("Android")
    }
}

MainActivity.kt amb veu espanyola

package com.example.helloworld

import android.os.Bundle
import android.speech.tts.TextToSpeech
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.helloworld.ui.theme.HelloWorldTheme
import java.util.Locale

class MainActivity : ComponentActivity(), TextToSpeech.OnInitListener {

    private var tts: TextToSpeech? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Inicializa TextToSpeech
        tts = TextToSpeech(this, this)

        enableEdgeToEdge()
        setContent {
            HelloWorldTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }

    override fun onInit(status: Int) {
        if (status == TextToSpeech.SUCCESS) {
            // Establece el idioma español (España)
            val localeEs = Locale("es", "ES")
            val result = tts?.setLanguage(localeEs)

            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                // Si no está disponible, usa el idioma por defecto
                tts?.setLanguage(Locale.getDefault())
                tts?.speak("El idioma español no está disponible en tu dispositivo.", TextToSpeech.QUEUE_FLUSH, null, null)
            } else {
                // Habla en español
                tts?.speak("¡Hola Android! Bienvenido a la aplicación.", TextToSpeech.QUEUE_FLUSH, null, null)
            }
        }
    }

    override fun onDestroy() {
        tts?.stop()
        tts?.shutdown()
        super.onDestroy()
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "¡Hola $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    HelloWorldTheme {
        Greeting("Android")
    }
}