Développer des applications Android* avec fonctionnalités de reconnaissance vocale

par Stanislav Pavlov

Android ne peut pas reconnaître la parole et un appareil Android typique ne peut pas le faire non plus. Ou serait-ce possible ?

Le meilleur moyen est de demander à une autre application de s’occuper de la reconnaissance pour nous. L’opération consistant à demander à une autre application de faire quelque chose dans Android est appelé utiliser des intentions.

Notre appareil cible doit avoir au moins une application pouvant traiter l’intention de reconnaissance vocale, qui est appelée par l’action RecognizerIntent.ACTION_RECOGNIZE_SPEECH.

Par exemple, l’application Google Voice Search. C’est un des meilleurs outils de reconnaissance pour Android et il prend en charge de nombreuses langues. Ce service nécessite une connexion Internet car la reconnaissance vocale est réalisée sur des serveurs Google. Cette application possède une Activité très simple qui informe les utilisateurs qu’ils peuvent parler. Dès que l’utilisateur arrête de parler, la boîte de dialogue se ferme et notre application (appeleur d’intention) reçoit une liste de chaînes correspondant à la parole reconnue.

Un exemple de reconnaissance vocale

Nous allons écrire un petit exemple d’application qui démontre l’utilisation de Voice Search dans les applications.

Notre application doit effectuer les choses suivantes :

  • Recevoir une demande de reconnaissance vocale
  • Vérifier la disponibilité d’une application de reconnaissance vocale
  • Si la reconnaissance vocale est disponible, appeler l’intention et recevoir les résultats
  • Si la reconnaissance vocale n’est pas disponible, afficher une boîte de dialogue invitant à installer Google Voice Search et rediriger l’utilisateur vers Google Play, s’il le souhaite

Tout d’abord, nous créons une classe qui implémente la logique de reconnaissance vocale. Nous appelons cette classe SpeechRecognitionHelper, où nous pouvons déclarer une fonction publique statique run() qui recevra une requête de lancement de la reconnaissance :

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

Comme vous pouvez le voir, en plus de la fonction run(), nous devons implémenter trois autres fonctions :

  • isSpeechRecognitionActivityPresented – Vérifie si l’application de reconnaissance vocale est présente sur le système
  • installGoogleVoiceSearch – Initialise le processus d’installation de Google Voice Search
  • startRecognition – Prépare l’intention appropriée et exécute la reconnaissance

Pour vérifier si l’appareil dispose d’une application de reconnaissance vocale, nous pouvons utiliser la méthode queryIntentActivities dans la classe PackageManager. Cette méthode présente une liste d’activités pouvant traiter l’intention spécifiée. Pour recevoir une instance du PackageManager, nous pouvons utiliser getPackageManager.

Notre code est montré ci-dessous :

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
    }

Implémentez maintenant la fonction startRecognition. Cette fonction forme l’intention appropriée permettant de lancer l’activité de reconnaissance vocale. Vous trouverez des informations détaillées décrivant comment le faire sur la page documentation.

Code source :

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

Et finalement, nous allons implémenter la fonction installGoogleVoiceSearch. Cette fonction permet d’afficher une boîte de dialogue demandant à l’utilisateur s’il souhaite installer Google Voice Search et qui le dirige vers Google Play, s’il le souhaite.

/**
     * 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
    }

C’est à peu près tout. Nous exécutons l’activité de reconnaissance vocale. Puis nous demandons à l’utilisateur l’autorisation d’installer Voice Search et l’envoyons sur Google Play s’il y consent. Il nous reste à collecter les résultats de la reconnaissance vocale.

Nous envoyons une demande en utilisant la fonction startActivityForResult pour collecter les résultats de l’activité lancée. Nous devons également redéfinir une méthode OnActivityResult dans notre activité d’appeleur d’intention. Cela peut être réalisé comme suit :

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

Maintenant, nous sommes prêts

La classe SpeechRecognitionHelper que nous avons crée nous permet de réaliser une demande de reconnaissance vocale en appelant une seule fonction run().

Tout ce qu’il faut pour ajouter une fonctionnalité de reconnaissance est d’ajouter cette classe à notre projet et d’appeler la fonction d’exécution à l’endroit voulu. Et puis implémenter le traitement des résultats textuels en redéfinissant la méthode onActivityResult pour l’activité qui a lancé l’appel de reconnaissance.

Pour davantage d’informations, vous pouvez consulter le site Web Android Developers. Vous y trouverez de bons exemples montrant comment réaliser la reconnaissance vocale et, ce qui est tout aussi important, comment obtenir la liste des langues disponibles. Vous aurez besoin de cette liste si vous voulez reconnaître une langue autre que la langue par défaut de l’utilisateur.

Pour accélérer l’intégration des entrées vocales dans votre application, vous pouvez télécharger et utiliser ce code pour la classe SpeechRecognitionHelper.

À propos des auteurs

Stanislav travaille dans le groupe Software & Services Group chez Intel Corporation. Il a plus de 10 ans d’expérience dans le développement de logiciels. Il s’intéresse plus particulièrement à l’optimisation des performances, de la consommation électrique et à la programmation parallèle. Dans son rôle actuel d’ingénieur en applications fournissant de l’assistance technique pour les appareils basés sur Intel, Stanislav travaille en étroite collaboration avec des développeurs de logiciels et des architectes SoC afin de les aider à obtenir les meilleures performances possibles sur les plates-formes Intel. Stanislav possède une maîtrise en économie mathématique, obtenue à la National Research University Higher School of Economics.

Mikhail est coauteur de ce blog et en stage d’été chez Intel, et il étudie l’informatique à Lobachevsky University. Il aime se plonger profondément dans les maths et faire des trucs de programmation Android.

 

Intel et le logo Intel sont des marques commerciales d'Intel Corporation aux États-Unis et/ou dans d'autres pays.
Copyright © 2013 Intel Corporation. Tous droits réservés.
* Les autres noms et désignations peuvent être revendiqués comme marques par des tiers.

Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

Commentaires

Bonjour, 

Bonjour, 

j'ai suivi le tuto mais j'ai un problème avec "SystemData.VOICE_RECOGNITION_REQUEST_CODE", SystemData n'étant pas reconnue ?

Dans le template que vous fournissez en lien, il manque une fonction qui n'est pas implémentée aussi, et tous les commentaires sont illisibles.

En tous cas super tuto et merci d'avance pour la réponse,

Théo.