Ir al contenido principal

Desarrollo en Android T14 - Utilizar TextoToSpeech TTS

Desarrollo en Android T14 - Utilizar TextoToSpeech TTS


El sistema operativo Android cuenta con una opción de accesibilidad llamada TTS por sus siglas en ingles TextToSpeech, que permite a los usuarios “leer” los textos de pantalla, ya sea para utilizarlos en los lectores de libros para convertirlos en audio-libros, o leer los mensajes que llegan al sistema, o ayudar a las personas con problemas de visión a poder acceder de manera más fácil a las opciones del smartphone.

Este sistema tiene características especiales, empezando por la entonación al momento de leer, es decir un texto en ingles se pronunciará de forma extraña si el teléfono esta configurado en español o en frances, así que una de las configuraciones esenciales es el idioma en que se quieren leer los textos.

Otra configuración importante es identificar si el sistema tiene instalado los paquetes de voz para trabajar “offline” es decir sin necesidad de conectarse a Internet, o en caso de no tenerlos descargados poder conectarse a Internet para reproducir el texto.


1. Para este tutorial se crea un nuevo proyecto utilizando la plantilla Blank.

2. La interfaz será similar a la mostrada en la siguiente imagen.

 

3.- En la interfaz se agrega una TextView y un EditText, que será donde se escribirá el texto que se desea leer, el código se verá como el siguiente.

xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="mx.blogspot.salvadorhm.leertexto.MainActivity"
    tools:showIn="@layout/activity_main">

    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Escribe un texto" />

    <EditText
        android:id="@+id/etText"
        android:inputType="textAutoCorrect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

4. Para hacer uso de TextToSpeech se importa la librería del mismo nombre, con lo que se puede acceder a la función de accesibilidad de Android.

import android.speech.tts.TextToSpeech;

5. Una vez importada la librería se crea un objeto que será el encargado de iniciar el TTS y reproducir el sonido.

private TextToSpeech tts;

6. Adicional se crea un objeto para el EditText, para el FloatingActionButton que se encargará de ejecutar la acción de convertir el texto a sonido, y un Toolbar para mostrar un ActionBar.

public class MainActivity extends AppCompatActivity{

    private TextToSpeech tts;
    private EditText etText;
    private FloatingActionButton fab;
    private Toolbar toolbar;

7. En el método onCreate del Activity se inician los objetos antes creados, teniendo atención especial en el objeto tts con el que se crea un TextToSpeech y se le asigna un listener llamado onInitListener que se creará en el siguiente punto.

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

    tts new TextToSpeech(this,onInitListener);
    etText = (EditText)findViewById(R.id.etText);

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(onClickListener);
}

8. Para crear el OnInitListener se usa la función de Android Studio para completar código Alt+Enter, con lo que se creará el listener onInitListener, que se pasa como parámetro al objeto tts creado anteriormente, este listener tiene como función iniciar el TTS configurar el idioma deseado, para esto se compara la variable status, para verificar que está función esta habilitada y funcional en el smartphone.

Una ves que se realizo la verificación se configura el idioma para la entonación utilizando el método setLanguage, en este caso se utiliza Local.getDefault, para usar como base el idioma en el que esta configurado el smartphone, aunque es posible especificar el idioma que se desea usar.

TextToSpeech.OnInitListener onInitListener new TextToSpeech.OnInitListener() {
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS){
            int result = tts.setLanguage(Locale.getDefault());

            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
                Log.d("TTS""Idimoa no soportado");
            }else{
                Log.d("TTS""TTS configurado correctamente");
            }
        }else{
            Log.d("TTS","Voz no inicializada");
        }
    }
};

9. De la misma forma que el punto anterior se sobrescribe el método onDestroy, este método se encarga se detener la reproducción de audio y “apagar” el sintetizador al cerrar la aplicación, o en caso de alguna falla.

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

10. A continuación se crea el método speak(), en el que se recibe el texto que el usuario escribió en el EditText de la interfaz gráfica, y utilizando el método speak se convierte el texto a audio, este método recibe 3 parámetros, el primero es el texto, el segundo es el método par reproducir el audio, en este caso la opción QUEQUE_FLUSH cancela cualquier reproducción en curso y reproduce el nuevo texto.

Este método es obsoleto a partir de la API 21, pero sigue siendo funcional con estos parámetros.

private void speak(){
    String text = etText.getText().toString();
    tts.speak(text,TextToSpeech.QUEUE_FLUSH,null);
}

11. En el método onClickListener se atrapa el evento click y cuando este evento lo produce el botón flotante llama al método speak creado en el paso anterior y reproduce el texto.

View.OnClickListener onClickListener new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(v == fab)
            speak();
    }
};

12. El código completo queda como se muestra a continuación:

package mx.blogspot.salvadorhm.leertexto;

import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

import java.util.Locale;

public class MainActivity extends AppCompatActivity{

    private TextToSpeech tts;
    private EditText etText;
    private FloatingActionButton fab;
    private Toolbar toolbar;

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

        tts new TextToSpeech(this,onInitListener);
        etText = (EditText)findViewById(R.id.etText);

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(onClickListener);
    }

    View.OnClickListener onClickListener new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(v == fab)
                speak();
        }
    };

    private void speak(){
        String text = etText.getText().toString();
        tts.speak(text,TextToSpeech.QUEUE_FLUSH,null);
    }

    TextToSpeech.OnInitListener onInitListener new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS){
                int result = tts.setLanguage(Locale.getDefault());

                if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
                    Log.d("TTS""Idimoa no soportado");
                }else{
                    Log.d("TTS""TTS configurado correctamente");
                }
            }else{
                Log.d("TTS","Voz no inicializada");
            }
        }
    };

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


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}




Comentarios

Entradas más populares de este blog

Creación de Librerías en Java

Creación de Librerías en Java   Las librerías son un conjunto de clases con funciones especificas que ayudan a desarrollar aplicaciones más complejas de una forma sencilla, por ejemplo si se requiere realizar cálculos matemáticos y emplear el funciones como el Seno o Coseno, simplemente se importa la librería Math y se utilizan estos métodos, en lugar de desarrollarlos. Java cuenta con una extensa lista de librerías disponibles dentro del JDK o desarrolladas por terceros, pero también existe la posibilidad de desarrollar librerías propias para reutilizar de forma más eficiente el código, por ejemplo si se trabaja de forma cotidiana con conexión a base de datos, se pueden desarrollar métodos genéricos que realicen la conexión, que validen las consultas, etc. de forma que su uso reduzca el tiempo de desarrollo e incremente la productividad. Para este tutorial se van a crear dos proyectos en NetBeans, uno sera la librería y el otro proyecto hará uso de esta.

Elegir la clase a ejecutar en NetBeans, MVC

Elegir la clase a ejecutar en NetBeans Para que java pueda ejecutar una aplicación esta debe tener un método conocido como punto de entrada, este método tiene la sintaxis: void static void main(String [] sax){ //código } En ocasiones en una aplicación tiene varios puntos de entrada, que pueden servir para probar diferentes partes de la aplicación sin tener que recorrer o pasar por varias clases, para esto se puede seleccionar directamente en las propiedades del proyecto que clase será la principal.

Librerías JOptionPane para generar ventanas de entrada y salida de datos

Para poder introducir datos leídos desde el teclado existen varias formas, una de ellas hace uso de la librería javax.swing.JOptionPane que entre otras opciones permite mostrar ventanas para introducir datos, y ventanas para mostrar valores. Con el uso de esta librería se crean pequeñas interfaces definidas por el sistema, pero ya se hace uso de las librerías graficas swing, que se verán más adelante.