Nota: Este tutorial ha sido donado a la comunidad de javaHispano por Intel. Intel espera que en el futuro sus procesadores incrementen considerablemente su presencia en los terminales móviles Android, por ello ha creído que este artículo sería interesante para nuestra comunidad. El artículo puede encontrarse en la web de Intel aquí. Podéis encontrar el primer artículo de la serie aquí, el segundo aquí, y el tercero aquí, el cuarto aquí y el quinto aquí. En la web de Intel tenéis más tutoriales en español sobre Android.
Android no puede reconocer el habla, de manera que un dispositivo Android típico tampoco puede reconocer el habla. O, ¿existe una manera de que lo haga?
La manera más fácil es pedir a otra aplicación que realice el reconocimiento. Pedir a otra aplicación que haga algo en Android se llama uso de intenciones.
Nuestro dispositivo de destino debe tener al menos una aplicación que pueda procesar la Intención para el reconocimiento del habla, la cual es llamada por la acción RecognizerIntent.ACTION_RECOGNIZE_SPEECH.
Una de esas aplicaciones es Google Voice Search. Es uno de los mejores reconocedores disponibles para Android y es compatible con varios idiomas. Este servicio requiere una conexión con Internet debido a que el reconocimiento de voz se lleva a cabo en los servidores de Google. Esta aplicación tiene una Actividad muy simple que informa a los usuarios que pueden hablar. El momento en que el usuario deja de hablar, se cierra el diálogo y nuestra aplicación (intent caller) recibe una gama de cadenas con el reconocimiento del habla.
Escribamos una pequeña aplicación de muestra que demuestre el uso de búsqueda de voz en aplicaciones.
Nuestra aplicación necesita hacer lo siguiente:
Primero, crearemos una clase que implementa la lógica para el reconocimiento del habla. Asigne a esta clase el nombre deSpeechRecognitionHelper donde declaramos una función run() pública y estática que recibirá una solicitud para iniciar un reconocimiento:
/** * A helper class for speech recognition */ public class SpeechRecognitionHelper { /** * Running the recognition process. Checks availability of recognition Activity, * If Activity is absent, send user to Google Play to install Google Voice Search. * If Activity is available, send Intent for running. * * @param callingActivity = Activity, that initializing recognition process */ public static void run(Activity callingActivity) { // check if there is recognition Activity if (isSpeechRecognitionActivityPresented(callingActivity) == true) { // if yes – running recognition startRecognition(callingActivity); } else { // if no, then showing notification to install Voice Search Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show(); // start installing process installGoogleVoiceSearch(callingActivity); } } }
Como puede ver, además de la función run() necesitamos implementar otras tres funciones:
Para comprobar si el dispositivo tiene una aplicación para el reconocimiento del habla, podemos usar el método queryIntentActivities en la clasePackageManager. Este método ofrece una lista de actividades que pueden procesar la Intención especificada. Para recibir una instancia de PackageManager, podemos utilizar getPackageManager.
Nuestro código aparece a continuación:
isSpeechRecognitionActivityPresented
/** * Checks availability of speech recognizing Activity * * @param callerActivity – Activity that called the checking * @return true – if Activity there available, false – if Activity is absent */ private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) { try { // getting an instance of package manager PackageManager pm = callerActivity.getPackageManager(); // a list of activities, which can process speech recognition Intent List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); if (activities.size() != 0) { // if list not empty return true; // then we can recognize the speech } } catch (Exception e) { } return false; // we have no activities to recognize the speech }
Ahora implemente la función startRecognition. Esta función formará la Intención apropiada para iniciar la Actividad del reconocimiento del habla. Puede encontrar la información detallada sobre cómo hacerlo en la página de documentación.
Código fuente:
/** * Send an Intent with request on speech * @param callerActivity - Activity, that initiated a request */ private static void startRecognitionActivity(Activity callerActivity) { // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); // giving additional parameters: intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application"); // user hint intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); // setting recognition model, optimized for short phrases – search queries intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1); // quantity of results we want to receive //choosing only 1st - the most relevant // start Activity ant waiting the result ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE); }
Y, por último, implementaremos installGoogleVoiceSearch. Esta función mostrará el diálogo que pregunta al usuario si desea instalar Google Voice Search y, si responde afirmativamente, abre Google Play.
/** * Asking the permission for installing Google Voice Search. * If permission granted – sent user to Google Play * @param callerActivity – Activity, that initialized installing */ private static void installGoogleVoiceSearch(final Activity ownerActivity) { // creating a dialog asking user if he want // to install the Voice Search Dialog dialog = new AlertDialog.Builder(ownerActivity) .setMessage("For recognition it’s necessary to install \"Google Voice Search\"") // dialog message .setTitle("Install Voice Search from Google Play?") // dialog header .setPositiveButton("Install", new DialogInterface.OnClickListener() { // confirm button // Install Button click handler @Override public void onClick(DialogInterface dialog, int which) { try { // creating an Intent for opening applications page in Google Play // Voice Search package name: com.google.android.voicesearch Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch")); // setting flags to avoid going in application history (Activity call stack) intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); // sending an Intent ownerActivity.startActivity(intent); } catch (Exception ex) { // if something going wrong // doing nothing } }}) .setNegativeButton("Cancel", null) // cancel button .create(); dialog.show(); // showing dialog }
Eso es todo. Ejecutamos la Actividad de reconocimiento del habla. Luego, solicitamos permiso del usuario para instalar Voice Search y, si nos da permiso, abrimos Google Play. Algo que todavía debemos hacer es recopilar los resultados del reconocimiento de voz.
Enviamos una solicitud con la función startActivityForResult para recopilar resultados de la Actividad iniciada. También necesitamos redefinir un métodoOnActivityResult en nuestro llamador de intenciones Actividad. Puede hacerlo de esta manera:
// Activity Results handler @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { // if it’s speech recognition results // and process finished ok if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) { // receiving a result in string array // there can be some strings because sometimes speech recognizing inaccurate // more relevant results in the beginning of the list ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); // in “matches” array we holding a results... let’s show the most relevant if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show(); } super.onActivityResult(requestCode, resultCode, data); }
La clase SpeechRecognitionHelper creada nos permite realizar una solicitud de reconocimiento del habla llamando a una sola función run().
Todo lo que se necesita para agregar una función de reconocimiento es agregar esta clase a nuestro proyecto y llamar a la función de ejecución en el lugar necesario. Y, después, implementar los resultados del procesamiento de texto al volver a definir el método onActivityResult para la Actividad que inició la llamada de reconocimiento.
Para obtener información adicional puede visitar el sitio web Desarrolladores para Android. Aquí encontrará buenos ejemplos que muestran la manera de implementar el reconocimiento de voz y, lo que es más importante, la manera de obtener la lista de idiomas disponibles. Necesitará esta lista si desea reconocer un idioma que no sea el de la región geográfica predeterminada del usuario.
Para obtener la rápida integración del reconocimiento de voz en su aplicación, puede descargar y utilizar este código para la claseSpeechRecognitionHelper.
Stanislav trabaja en el Grupo de software y servicios en Intel Corporation. Tiene más de 10 años de experiencia en desarrollo de software. Sus intereses principales son la optimización de rendimiento, el consumo de energía y la programación en paralelo. En su cargo actual como Ingeniero de aplicaciones que proporcionan asistencia técnica para dispositivos en Intel, Stanislav trabaja muy de cerca con desarrolladores de software y arquitectos de SoC para ayudarles a lograr el mejor rendimiento posible en las plataformas Intel. Stanislav recibió su diploma de Maestría en Economía matemática de la facultad 'Higher School of Economics' de la universidad 'National Research University'.
Mikhail es coautor de este blog y un interno temporal de Intel, está estudiando ciencias de computación en la universidad 'Lobachevsky University'. Le encanta estudiar matemáticas a fondo y crear trucos de programación para Android.