Una de las cosas que menos me gusta hacer es leer artículos de administración y es que son muy aburridos para mi que llevo ingeniería (hasta ética y filosofía es mucho mejor e importante, porque la administración es la forma de entretener a un montón de simios semi-calificados para que hagan el trabajo de unas horas en varias semanas), de eso ya tuve lo suficiente en el bachillerato (con opción en contaduría), por eso me decidí a crear una app para Android que me lea lo que yo no quiero leer, y que mejor momento que cuando voy en el autobus camino a la UTEC©
Bueno pero eso es lo de menos, vamos a trabajar un poco con la clase Text To Speech, es muy simple de usar y aplicar, en esta caso vamos a leer un archivo localizado en la carpeta raw para luego leerla con dicha clase.
Un vídeo dice mas que mil palabras (lo siento si lo ven antes de agregarle audio)
Antes de iniciar todo esto, necesitamos configurar el emulador o dispositivo, para que este en el idioma español, de lo contrario comenzara la lectura en ingles (por defecto). Para ello vamos a settings/keyboard and languages y hacemos la eleccion del idioma en español
Para comenzar agregamos un archivo en la carpeta raw, el cual debe de contener el archivo que deseamos que lea, recordemos que la carpeta raw no viene por defecto en el proyecto, asi que debemos de crearla y debe de quedar dentro de res/raw
Luego de eso trabajamos algo en el layout y lo dejamos de la siguiente manera
Como se logra observar, se trata de 2 botones y un TextView, el cual esta dentro de otro layout y a la vez dentro de un ScrollView (se vera mejor cuando ponga el codigo).
Trabajando el codigo
Luego de tener el layout que usaremos, comenzamos a tocar el codigo java, en el cual se comienza de la siguiente manera
El codigo anterio funciona así, al iniciar la clase y extender de Activity se usan dos interfaces TextToSpeech.OnInitListener y OnClickListene, las cuales generan dos metodos que son:
onClick(View arg0)
Que sera usado para manejar los eventos de los botones y
onInit(int status)
Que se usara para manejar el evento del lector
Ahora necesitamos llamar a los componentes de layout, y como a mi me gusta usar siempre un metodo inicializar lo dejo a continuacion
Como siempre este metodo se agrega al metodo onCreate(Bundle savedInstanceState), y si se preguntan que hace el método inicializar, a continuacion la explacion
primero inicializa las instancias o variables que se usan en todo el proyecto, ademas crea un objeto llamada miLector que hace uso de la clase Text To Speech y en el cual su constructor lleva 2 parámetros que son el contexto en donde estamos y el evento que genera, recordemos que estamos implementando TextToSpeech.OnInitListener, por esa razón queda de la siguiente manera
Ahora que conocemos la naturaleza de miLector, seria bueno saber que hace el metodo isLanguageAvailable(), lo que hace es preguntar si el lenguaje español esta disponible en el dispositivo.
Luego en los botones iniciar y parar, lo unico que se genera son los eventos de los botones
Ahora dentro del metodo onInit(int status) haremos lo siguiente
Lo que sucede dentro de onInit(int status) es lo siguiente
con un if preguntamos si el estado de la clase TextToSpeech esta generándose (sinceramente no se que valor devuelve, solo nos conformamos saber que devuelve un entero), luego le asignamos el valor de TextToSpeech.LANG_COUNTRY_AVAILABLE a una variable entera que la hemos nombrado result, esta variable contiene el valor que esperábamos de isLanguageAvailable(), luego en otro if preguntamos si ese lenguaje esta disponible en el dispositivo o si no es soportado, para el caso de no ser soportado o no contener el lenguaje, se desactiva el botón, de lo contrario es visible.
Ahora veamos que hace el método onClick(View arg0)
Lo que hace el método onClick(View arg0) es muy simple, hace uso de un switch para saber que se a presionado, si se presiona bParar, solamente se detiene la lectura y manda un mensaje al usuario (ojo que esto lo detiene completamente) luego de saber si se presiono bIniciar se ejecuta el método iniciarlectura(), el cual muestro a continuación.
¿muy simple verdad?, pero así es esto, lo complicado lo hace uno. Y para mostrar el texto del archivo en la carpeta raw se usa el siguiente metodo
Luego de eso hacemos lo mismo que con inicializar(), lo agregamos al método onCreate(Bundle savedInstanceState) y ya tendríamos una app casi completa, hay cosillas que podríamos mejorar, como por ejemplo indicarle a la app que en caso de no existir los archivos necesarios para usar Text To Speech, que los instale desde Google Play, para eso podriamos usar AlertDialog o Dialog, sea como sea son muy buenas sugerencias, en este ejemplo se oviaron por motivos de ser demostrativo.
Si quieren el codigo completo hagan clic aqui.
Un ejemplo de como agregar los paquetes necesarios esta en la pagina de Android Developers, al que lo solicite le puedo enviar el código completo de como usar los paquetes faltantes en esta app.
Como se logra observar, se trata de 2 botones y un TextView, el cual esta dentro de otro layout y a la vez dentro de un ScrollView (se vera mejor cuando ponga el codigo).
Trabajando el codigo
Luego de tener el layout que usaremos, comenzamos a tocar el codigo java, en el cual se comienza de la siguiente manera
public class TextoavozActivity extends Activity implements TextToSpeech.OnInitListener, OnClickListener{ /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public void onClick(View arg0) { // TODO Auto-generated method stub @Override public void onInit(int status) { // TODO Auto-generated method stub } }
El codigo anterio funciona así, al iniciar la clase y extender de Activity se usan dos interfaces TextToSpeech.OnInitListener y OnClickListene, las cuales generan dos metodos que son:
onClick(View arg0)
Que sera usado para manejar los eventos de los botones y
onInit(int status)
Que se usara para manejar el evento del lector
Ahora necesitamos llamar a los componentes de layout, y como a mi me gusta usar siempre un metodo inicializar lo dejo a continuacion
private TextView mostrar; private Button iniciar, parar; private TextToSpeech miLector; private void inicializar() { mostrar = (TextView) findViewById(R.id.mostrar); iniciar = (Button) findViewById(R.id.bIniciar); parar = (Button) findViewById(R.id.bParar); miLector = new TextToSpeech(this, this); miLector.isLanguageAvailable(new Locale("spa")); iniciar.setOnClickListener(this); parar.setOnClickListener(this); }
Como siempre este metodo se agrega al metodo onCreate(Bundle savedInstanceState), y si se preguntan que hace el método inicializar, a continuacion la explacion
primero inicializa las instancias o variables que se usan en todo el proyecto, ademas crea un objeto llamada miLector que hace uso de la clase Text To Speech y en el cual su constructor lleva 2 parámetros que son el contexto en donde estamos y el evento que genera, recordemos que estamos implementando TextToSpeech.OnInitListener, por esa razón queda de la siguiente manera
miLector = new TextToSpeech(this, this);
Ahora que conocemos la naturaleza de miLector, seria bueno saber que hace el metodo isLanguageAvailable(), lo que hace es preguntar si el lenguaje español esta disponible en el dispositivo.
Luego en los botones iniciar y parar, lo unico que se genera son los eventos de los botones
Ahora dentro del metodo onInit(int status) haremos lo siguiente
@Override public void onInit(int status) { // TODO Auto-generated method stub if(status == TextToSpeech.SUCCESS) { int result = TextToSpeech.LANG_COUNTRY_AVAILABLE; if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Toast.makeText(getApplication(), "Lenguaje no soportado", Toast.LENGTH_LONG).show(); iniciar.setEnabled(false); } else { iniciar.setEnabled(true); } } }
Lo que sucede dentro de onInit(int status) es lo siguiente
con un if preguntamos si el estado de la clase TextToSpeech esta generándose (sinceramente no se que valor devuelve, solo nos conformamos saber que devuelve un entero), luego le asignamos el valor de TextToSpeech.LANG_COUNTRY_AVAILABLE a una variable entera que la hemos nombrado result, esta variable contiene el valor que esperábamos de isLanguageAvailable(), luego en otro if preguntamos si ese lenguaje esta disponible en el dispositivo o si no es soportado, para el caso de no ser soportado o no contener el lenguaje, se desactiva el botón, de lo contrario es visible.
Ahora veamos que hace el método onClick(View arg0)
@Override public void onClick(View arg0) { // TODO Auto-generated method stub switch(arg0.getId()) { case R.id.bIniciar: iniciarLectura(); Toast.makeText(getApplication(), "Leyendo archivo", Toast.LENGTH_SHORT).show(); break; case R.id.bParar: miLector.stop(); Toast.makeText(getApplication(), "Deteniendo lectura", Toast.LENGTH_SHORT).show(); break; }
Lo que hace el método onClick(View arg0) es muy simple, hace uso de un switch para saber que se a presionado, si se presiona bParar, solamente se detiene la lectura y manda un mensaje al usuario (ojo que esto lo detiene completamente) luego de saber si se presiono bIniciar se ejecuta el método iniciarlectura(), el cual muestro a continuación.
private void iniciarLectura() { // TODO Auto-generated method stub miLector.speak(mostrar.getText().toString(), TextToSpeech.QUEUE_ADD, null); }
¿muy simple verdad?, pero así es esto, lo complicado lo hace uno. Y para mostrar el texto del archivo en la carpeta raw se usa el siguiente metodo
private void mostrarTexto() { // TODO Auto-generated method stub try { int id = R.raw.linux; InputStreamReader insr = new InputStreamReader(this.getResources().openRawResource(id )); BufferedReader bf = new BufferedReader(insr); String linea; StringBuilder texto = new StringBuilder(); while((linea = bf.readLine()) != null) { texto.append(linea); //la siguiente linea es por si son varias lineas de texto //texto.append("\n"); } insr.close(); bf.close(); mostrar.setText(texto.toString()); } catch(IOException e) { Toast.makeText(getApplication(), "No se pudo leer el archivo deseado", Toast.LENGTH_LONG).show(); } }
Luego de eso hacemos lo mismo que con inicializar(), lo agregamos al método onCreate(Bundle savedInstanceState) y ya tendríamos una app casi completa, hay cosillas que podríamos mejorar, como por ejemplo indicarle a la app que en caso de no existir los archivos necesarios para usar Text To Speech, que los instale desde Google Play, para eso podriamos usar AlertDialog o Dialog, sea como sea son muy buenas sugerencias, en este ejemplo se oviaron por motivos de ser demostrativo.
Si quieren el codigo completo hagan clic aqui.
Un ejemplo de como agregar los paquetes necesarios esta en la pagina de Android Developers, al que lo solicite le puedo enviar el código completo de como usar los paquetes faltantes en esta app.