El tutorial consta de dos partes, una de ellas de como utilizar la Api del reconocimiento de voz (Speech Recognition) para obtener un String (adena de texto) apartir de nuestro mensaje oral. y la segunda parte es como utilizar ese String para poder localizar el nombre en la SIM y llamar al contacto.
Para entender bien este tutorial recomiento antes la lectura de estos dos tutoriales:
-http://www.tutorialeshtml5.com/2012/02/tutorial-basico-android-agregar-boton.html
-http://www.tutorialeshtml5.com/2012/03/android-introduccion-tutorial-y-tipos.html
A continuación os presentaré el código totalmente comentado para su perfecto entendimiento. Entiendo que hay mil maneras de hacerlo y mucho mejor. He obtado por esta manera ya que es la más entendible para aficionados y obtener una idea más clara de la herramienta. No olvidemos que este blog es para aprender e intentar buscarnos un poco la vida para mejorar nuestra propia técnica.
Ante todo no olvidarnos que para que este tutorial funcione tenemos que poner estos permisos en el manifest de nuestra aplicación:
<uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/> <uses-permission android:name="android.permission.CALL_PHONE"/>Y este sería el código java:
public class Reconocimiento extends Activity { private static final int VOICE_RECOGNITION_REQUEST_CODE = 1; private Button bt_start; private Vector<String> nombres; private Vector<String> telefonos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_reconocimiento); //Relacionamos el boton con el XML bt_start = (Button)findViewById(R.id.button1); bt_start.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //Lanzamos el reconoimiento de voz startVoiceRecognitionActivity(); } }); //Recogemos todos los telefonos y nombre en los //vetores: nombres y telefonos getNameNumber(); } private void startVoiceRecognitionActivity() { // Definición del intent para realizar en análisis del mensaje Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); // Indicamos el modelo de lenguaje para el intent intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); // Definimos el mensaje que aparecerá intent.putExtra(RecognizerIntent.EXTRA_PROMPT,"Diga, Llamar a ..."); // Lanzamos la actividad esperando resultados startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); } @Override //Recogemos los resultados del reconocimiento de voz protected void onActivityResult(int requestCode, int resultCode, Intent data) { //Si el reconocimiento a sido bueno if(requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK){ //El intent nos envia un ArrayList aunque en este caso solo //utilizaremos la pos.0 ArrayList<String> matches = data.getStringArrayListExtra (RecognizerIntent.EXTRA_RESULTS); //Separo el texto en palabras. String [ ] palabras = matches.get(0).toString().split(" "); //Si la primera palabra es LLAMAR if(palabras[0].equals("llamar")){ for(int a=0;a<nombres.size();a++){ //Busco el nombre que es la tercera posicion (LLAMAR A LORENA) if(nombres.get(a).equals(palabras[2])){ //Si la encuentra recojo el numero telf en el otro //vector que coincidira con la posicion ya que //los hemos rellenado a la vez. Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:"+telefonos.get(a))); //Realizo la llamada startActivity(callIntent); break; } } } } } //Con el getNameNumber lo que hago es recoger los nombres //de la SIM en un vector //Y los numeros de telefonos en otro vector, eso sí tienen que coincidir //las posiciones de uno y de otro, por eso los relleno a la vez. private void getNameNumber(){ nombres = new Vector<String>(); telefonos = new Vector<String>(); Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; ContentResolver cr = getContentResolver(); Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER }; Cursor names = getContentResolver().query( uri, projection, null, null, null); int indexName = names.getColumnIndex( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); int indexNumber = names.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER); names.moveToFirst(); do { //Aquí relleno los dos String name = names.getString(indexName); nombres.add(name); String number = names.getString(indexNumber); telefonos.add(number); } while (names.moveToNext()); } }Espero vuestras dudas y opiniones.
Nuevo! Haz click en el siguiente Link para descargar el Proyecto
Muchas gracias! y no olviden escribir sus comentarios!
Hola Quisiera saber si hay alguna manera de obtener el resultado del onActivityResult(); ya que en mi programa tengo uso dos botones, en los cuales se activa el reconocimiento de voz, pero cada boton usa diferente Textview para mostrar el resultado. Gracias
ResponderEliminarBuenos días!
EliminarSí, de hecho si sigues el ejemplo donde dice:
ArrayList matches = data.getStringArrayListExtra
(RecognizerIntent.EXTRA_RESULTS);
debajo de este puedes hacer un textview.settext(matches.get(0).toString());
siendo matches.get(0).toString() la respuesta de texto a voz. Muchas gracias!
No olvidéis el +1 ^^
Q tal amigo, hice la aplicaion tal cual como estaba aqui,el ide no me mostraba nigun error , compilo todo muy bien, pero a la hora de ejecutar el programa en mi celular, al aplastar el boton en el programa, me sale q hay un error y se debe cerrar :S ... q puede ser?
ResponderEliminarMira a ver que te dice el Logcat y cópiamelo aquí y le hecho un ojo a ver. Muchas Gracias!
EliminarEste comentario ha sido eliminado por el autor.
EliminarA mi también me tira error pero cuando lo inicio me fije el problema y parece estar en el método getNameNumber(). Si comentarizo la llamada a ese método la aplicación se abre pero al hacer click en el boton tambien tira error, me fije de vuelta y este error parece que está en la llamada a startVoiceRecognitionActivity().
EliminarQue raro, ami me funcionó perfectamente en Samsung S3 android 4.1
EliminarLo estuve probando en un emulador de Android 4.2.2, no se si puede ser este el problema. Lo voy a probar emulando el Android 4.1.2
EliminarMmm... no tienes un terminal físico para probar? nose si el reconocimiento de voz funciona através del emulador. Te reconoce el microfono del PC?
EliminarNo estoy seguro si reconoce el micrófono, pero si consigo un smartphone seguro lo pruebo
EliminarHola. Conseguisteis probarlo en un emulador???
EliminarSauludos, muy bien explicado, lo que deseo hacer es una aplicacion, para mi mama que es recientemente ciega o invidente, para que pueda encontrar cosas en su casa, necesito que la persona invidente por comandos de voz, se consulte una pequeña base de datos, y regrese las coordenadas del lugar donde se encuentra el objeto, se programar PIC, y solo necesito que el movil me identifique las coordenadas del comando de voz, para k el pic con sonidos distribuidos en la casa de mi mama en cuentre lo que necesita sin perderse tanto, espero poder aportar un buen tutorial del proyecto terminado, y ayudar a tanta gente con este problema similar, si ud, puede ayudarme a avanzar mas rapido se lo agradeceremos infinitamente, buen dia...
ResponderEliminarMe parece muy interesante el proyecto, actualmente dispongo de poco tiempo... pero para cualquier cosa no dudes en preguntar!
Eliminarsaludos, podrias facilitarme tu proyecto?? (lpandof3.1284@yahoo.com), lo k pasa es k se me esta complicando un poco soy nuevo en java, gracias
EliminarDisculpa pero no suelo guardar los proyectos.. :S
EliminarPero al ser nuevo lo que te iría mejor para empezar es saber crearlo. Busca algún tutorial en google de: crear proyecto nuevo android en eclipse.
;)
Hola, soy completamente nuevo, debo hacer un proyecto en el cual, debo conectar una aplicacion android con un circuito para el control de algunas luces, el ventilador y el sistema de seguridad de una maqueta de una casa mediante la voz. Podrias hecharme una mano, o dandome una idea por favor porque estoy un poco confundido.
ResponderEliminarBuenos días, Yo buscaría algo como Arduino busca información sobre eso. Con arduino podrás encender las luces, ventilador, etc.. Después tendrás que mirar como conectar el arduino al Android ya sea por cable o bluetooth,etc...
EliminarEspero a verte encaminado un poco. gracias!
Buenas,
ResponderEliminarlo primero decir que muchas gracias por este tuto y por otros muchos que me han servido de ayuda. Lo segundo, me gustaría saber si hay una forma de acceder al audio dentro del Intent y poder reproducirlo antes o después de realizar la transcripción al String.
De nuevo muchas gracias y un saludo!
He estado buscando y no he encontrado nada al respecto...
EliminarSi encuentro algo te lo aré llegar ;)
usa un TextToSpeech para reproducir el resultado es como yo lo hago.
Eliminarse podrá hacer que funcione sin conexión a internet??
ResponderEliminarCon esta API de google no... desconozco ahora mismo si existen otras descargables que no utilicen internet.
Eliminarhola saben si funciona en modo offline con la nueva actualización Android 4.1 Jelly Bean que tiene esta opción ya actualizada.
ResponderEliminarHola Saludos y buen tutorial. Quiero saber si hay alguna manera de que el reconocimiento de voz sea en español ya que me genera muchos errores al hablar, reconoce pero palabras en inglés. Muchas gracias.
ResponderEliminarEn que idioma tienes el terminal? Yo lo tengo en Español-España y el reconocimiento en español es excelente. No se si a lo mejor el Español-Mexico (ejemplo) puede fallar..
Eliminarvicto yo cambio el idioma del telefono con Locale.setDefault(Locale.FRANCE); y me funciona bien pero el idioma del ACTION_RECOGNIZE_SPEECH no es el mismo del telefono segun la documentacion de android developer se puede hacer con intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en-US");
Eliminarintent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,"en-US");
intent.putExtra(RecognizerIntent.EXTRA_ONLY_RETURN_LANGUAGE_PREFERENCE,"en-US"); pero no me funciona sabes como lo puedo cambiar a nivel de código y que funcione.
Amigo muchas gracias por el tuto, esta muy bueno.
ResponderEliminarUna pregunta esq necesito es leer texto, también estoy haciendo una aplicación para invidentes y necesito leer un string para qué el invidentelo escuche, muchas gracias y que pena la molestia
Muchas gracias por tu comentario. Tengo algo que seguramente te ayude. Es un link de google en el cual tu le pasas un String por GET en el parametro 'q' y te devuelve un archivo .mp3 con la voz leyendo el texto. Pruebalo en el navegador primero y después lo tendrás que adaptar para que android descarge el archivo de audio, ejemplo:
Eliminarhttp://translate.google.com/translate_tts?tl=es&q=Link%20patrocinado%20por%20Tutoriales%20Html%205
Cuentame qeu te parece, el +1 siempre se agradece :D
yo lo hago con un TextToSpeech:
Eliminardeclaramos la variable
TextToSpeech hablar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hablar = new TextToSpeech(this, this);
}
public void say(String text2say){
hablar.speak(text2say, TextToSpeech.QUEUE_FLUSH, null);
}
@Override
public void onInit(int status) {
say("Hello World");
}
si quieres que diga lo que esta en el texview solo crea una variable y cambia el string en el say ejemplo say (variable) la variable debe ser de tipo string
Vitor el ejemplo no funciona se cierra cuando digo llamar a creo que es el en getNameNumber(); pude notar que en
ResponderEliminarCursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
cur nunca es utilizada
podrías verificar el código y corregirlo te lo agradecería.
el 'cur' lo que hace es lanzar la 'query'
EliminarHe verificado el código, a mí me funciona bien. He subido un link para que descarguéis el proyecto. Muchas gracias!
Hola excelente codigo ahora si entiendo como funciona pero tengo una duda yo no quiero que lo llame quiero que con voz busque el contacto y de inmediato me envie a otra ventana donde pueda enviar un mensaje de auido y ademas tengo problemas, quiero que cada paso donde este con una voz me diga donde esta y que puede hacer... gracias
ResponderEliminarEl proyecto que quieres hacer es bastante amplio, no se puede contestar en una simple pregunta ejejej
EliminarLo quee tienes que hacer es ir paso a pasa y para cada paso necesitaras buscar un tutorial para lo que estés realizando ese momento.
Espero que te vaya bien! seguramente algún tutorial de esta web te ayudará en tus pasos.
Hola, muy bueno el proyecto, solamente que tengo una pregunta, ya pude correr la aplicacion en mi dispositivo(android 4.1) no marca errores, el error que tengo es al momento de cuando acepta lo que digo, me cierra la aplicacion, y revise el logcat y me aparece FATAL EXCEPTION:main, java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1,data=Intent, entre otros, muchas gracias por tu tiempo, espero tu respuesta
ResponderEliminarRepasare el código y comentaré los resultados. Muchas gracias!
EliminarHola, gracias por subir tu proyecto, encontre que mi error eran unas librerias que me faltaban, y ya me funciona correctamente, gracias por darte el tiempo de subirlo. Saludos
Eliminarhola, tengo problemas a correr el programa en cuando corro tu programa al pasar por
ResponderEliminarstartActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
ya no me muestra nada!!!! no se si hay otra actividad que tengo q generar???
gracias
Me di cuenta de un error, si a la primera no te reconoce ya no funciona el reintento. Puede ser que sea eso lo que te pasa.
EliminarHe verificado el código, a mí me funciona bien. He subido un link para que descarguéis el proyecto. Muchas gracias!
Hola Victor:
ResponderEliminarExcelente tu tutorial!; una consulta, deseo implemente una app parecida al del tutorial, pero que me permita activar o llamar musica que tenga almacenado en mi ipod, por ejemplo, si digo; antistrees, a mi mobile, me suene musica relajante, si digo, romantica, se escuche musica del tipo que yo menciono. Es posible hacer esto?, agradeceré tus comentarios.
Gracias!!
Como digo muchas veces hay que hacerlo paso a paso, primero deberías grabar en un Vector los tipos de música y después en la línea de código:
Eliminarif(palabras[0].equals("llamar")){
A partir de hay la tendrías que sustituir el código para en vez de llamar al intent de llamara tendrías que hacer que llamara al reproductor indicándole la canción dependiendo del String recogido en la grabación de voz en el ejemplo és algo parecido a:
"tel:"+telefonos.get(a)
Muchas gracias por vuestros comentarios! :D
Gracias por la respuesta, otra consulta, como sabemos, los files de musica o audio, los guardamos en res/raw, pero en mi caso, los voy a guardar por tipo de musica, . mi idea seria: res/raw/relax, res/raw/rock, res/raw/pop. Mi pregunta seria, como resolveria esto en el código de mi reproductor de musica: reproductor = MediaPlayer.create(this,R.raw.audio)?
EliminarSaludos
He estado buscando y probando.. parece que no es posible crear subcarpetas dentro del resource raw. Lo siento igualmente si encuentro algo te lo aré saber.
EliminarMuchas gracias!
Un +1 nos ayuda a todos! :D
Hola de nuevo Victor al momento de correr tu programa tal cual, me sale
ResponderEliminar¡Lo sentimos!
La aplicacion Reconocimiento (com.---.reconocimeinto) se ha detenido inesperadamente. Intentelo de nuevo
y en el logcat sale esto...
mi correo es armando_27_01@hotmail.com para ver si te puedo mandar lo q dice mi logcat
Hola. Tengo el mismo problema que comentan en el mensaje anterior, cuando pulso el botón se detiene la aplicación. Parece que el problema esta en la llamada a startActivityForResult(..). Lo estoy probando con un Emulador de eclipse, no se si sera ese el problema.
ResponderEliminarAgradezco cualquier ayuda. david.rodriguezas@gmail.com
Sin duda creo que será por el emulador ya que no obtiene ningún sonido y no recibe nada en el ForResult.
EliminarMira a ver si puedes probarlo en un terminal. muchas gracias
Un +1 nos ayuda a todos :D
Ya lo he podido probar en un terminal y funciona bien! Es problema del emulador...
ResponderEliminarOtra pregunta, por lo que veo es necesario tener conexión a Internet no?
Muy bien! Gracias por aclarar lo del emulador.
EliminarSi... google por reconocimiento de voz necesita internet. Al menos de momento.
Un +1 nos ayuda a todos! :D
Gracias!
salu2.... una pregunta el reconocimento de voz solo puede funcionar con las apis de google con conexion a internet???? puede funcionar con una api de android i sin conexion..????
ResponderEliminarBuenas tardes, la verdad que no he buscado otras apis, ya que la de android que es la de google es la nativa del terminal y se suele usar esa. Miraré a ver que otras posibilidades hay. Gracias por tu comentario.
EliminarRecuerda un +1 nos ayuda a todos :D
Hola necesito mostrar en una caja de texto lo que se diga con la voz? como hago eso? porfavor
ResponderEliminarEso no viene integrado en Android. Tendrás que buscar alguna solución alternativa, yo por ejemplo adapte una api web que tiene google para enviarlo los parámetros y me respondía el .mp3
EliminarComo se puede hacer par que también reconozca con contacto con apellidos?
ResponderEliminaren la linea del if quedaria asi
Eliminarif (nombres.get(a).equals(palabras[2])&& nombres.get(a).equals(palabras[3]))
Buenas amigo, muy buen post, esta genial pero tengo una duda. Es posible guardar el contacto que has dicho en un archivo de texto??
ResponderEliminarhola amigo, excelente tuto, me podrias explicar como hacer para que en vez de llamar al contacto se le envie un sms con un texto ya definido? Muchas gracias
ResponderEliminarNo puedo descargar el proyecto, alguien seria tan amable de pasarmelo
ResponderEliminarBuen dia quisiera saber si habria alguien quien me pudiera asesorar si esta libreria de voz o alguna otra me sirviera para hacer la comparacion con sonidos por ejemplo la sirena de una ambulancia o una patrulla, si alguien tuviera alguna informacion que resultado me devuelve esta libreria me gustaria saberlo gracias
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarBuenas tengo un problema me compila sin errores y abre la app pero no me realiza la llama estoy probando en una terminal android 5.0.2 samsung A300H
ResponderEliminarHola un saludo...No se puede descargar el proyecto...agradecería que me mandes mi correo es hadesmaicol666@gmail.com
ResponderEliminarGracias de antemano
Hola. No se puede descargar el proyecto. Por favor actualiza el link. Dea antemano mil gracias
ResponderEliminarEl link para descargar el proyecto no funciona, por favor podrías actualizarlo. Gracias
ResponderEliminarHOLA EXCELENTE EXPLICACION, DISCULPA EL LINK YA NO FUNCIONA PODRIAS COMPARTIRLO NUEVAMENTE, O ALGUIEN QUE LO HAYA PODIDO DESCARGAR PODRIA COMPARTIRLO
ResponderEliminarGRACIAS POR EL APORTE.
SALUDOS.
hola amigo tengo un problema dentro de tu codigo hay un objeto cur que no esta siendo utilizado,podrias colgar un link con el proyecto si fueras muy amable.
ResponderEliminarhola como haria en vez de llamar al ejecutar el comando abra Gmail, Whatsapp alguna aplicación que quiera y este instalada
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarHola Victor, muy buen tutorial.
ResponderEliminarTe hago una consulta, hice un Service que es un Teclado (para remplazar el que viene por defecto en Android) y que una tecla funcione como el boton de Whatsapp, que te escuche lo que decis, pero que lo convierta a texto.. logré hacer el teclado, el servicio.. cuando quiero ejecutar la clase de tu tutorial, lo qu estuve leyendo es que no puedo instanciar una clase Activity desde un service.
Tenes idea como puedo ejecutarlo? (Encima, al ser un servicio y no una app comun, no puedo debugearlo y ver el tipo de error que sale)
Gracias !!
Hola Victor,quería consultarte como haría si yo quisiera dictar y al mismo tiempo quiero que se guarde el audio que dicte.¿se puede ?¿como lo haría ?.
ResponderEliminarTe agradecería un montón si se pudiera.
Hola Victor,quería consultarte como haría si yo quisiera dictar y al mismo tiempo quiero que se guarde el audio que dicte.¿se puede ?¿como lo haría ?.
ResponderEliminarTe agradecería un montón si se pudiera.