Buscar
Social
Ofertas laborales ES
« Nokia anuncia sus primeros terminales móviles basados en Android | Main | Workers Control, system pattern »
martes
feb252014

Desarrollo de aplicaciones para Android* con características de reconocimiento de voz

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.

Introducción

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.

Una muestra de reconocimiento de voz

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:

  • Recibir una solicitud de reconocimiento de voz
  • Consultar la disponibilidad de la aplicación para el reconocimiento del habla
  • Si el reconocimiento del habla está disponible, entonces debe llamar a la intención para éste y recibir los resultados
  • Si el reconocimiento del habla no está disponible, entonces debe mostrar el diálogo para instalar Google Voice Search y, si acepta, redirigir al usuario a Google Play

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:

  • isSpeechRecognitionActivityPresented: comprueba si la aplicación de reconocimiento del habla se encuentra en el sistema
  • installGoogleVoiceSearch: inicializa el proceso de instalación de Google Voice Search
  • startRecognition: prepara la Intención adecuada y ejecuta el reconocimiento

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);
    }

Ahora estamos listos

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.

Sobre los autores

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.

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>