Sviluppo di applicazioni Android* con funzionalità di riconoscimento vocale

Android non è in grado di riconoscere il parlato, quindi anche un dispositivo Android tipico non può riconoscere il parlato. Oppure, esiste un modo in cui possa farlo?

Il modo più semplice è quello di chiedere a un'altra applicazione di eseguire il riconoscimento vocale. Quando in Android si chiede a un'altra applicazione di fare qualcosa si dice che si utilizzano intent.

Il nostro dispositivo di destinazione deve avere almeno un'applicazione in grado di elaborare l'Intent per il riconoscimento vocale, che viene chiamato dall'azione RecognizerIntent.ACTION_RECOGNIZE_SPEECH.

Una di queste applicazioni è Google Voice Search. Si tratta di uno dei migliori riconoscitori disponibili per Android e supporta numerose lingue. Questo servizio richiede una connessione a Internet, perché il riconoscimento vocale avviene sui server di Google. Questa applicazione è una Activity molto semplice che informa gli utenti che possono parlare. Nel momento in cui l'utente smette di parlare, la finestra viene chiusa e la nostra applicazione (chiamante dell'intent) riceve una matrice di stringhe del parlato riconosciuto.

Esempio di riconoscimento vocale

Scriviamo una piccola applicazione di esempio che dimostra la ricerca vocale nelle applicazioni.

L'applicazione deve eseguire quanto segue:

  • Ricevere una richiesta di riconoscimento vocale
  • Verificare la disponibilità dell'applicazione di riconoscimento vocale
  • Se il riconoscimento vocale è disponibile, deve chiamarne l'intent e ricevere i risultati
  • Se il riconoscimento vocale non è disponibile, deve mostrare la finestra di dialogo per l'installazione di Google Voice Search e reindirizzare l'utente a Google Play, se lo desidera

In primo luogo, creiamo una classe che implementa la logica per il riconoscimento vocale. Chiamare questa classe SpeechRecognitionHelper dove dichiariamo una funzione pubblica statica run() che riceverà la richiesta di avvio di un riconoscimento:

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

Come potete vedere, oltre alla funzione run() dobbiamo implementare altre tre funzioni:

  • isSpeechRecognitionActivityPresented – verifica se l'applicazione di riconoscimento vocale è presente nel sistema
  • installGoogleVoiceSearch – inizializza il processo di installazione di Google Voice Search
  • startRecognition – prepara l'intent appropriato ed esegue il riconoscimento

Per controllare se il dispositivo dispone di un'applicazione per il riconoscimento vocale, possiamo usare il metodo queryIntentActivities nella classe PackageManager. Questo metodo fornisce un elenco di attività che possono elaborare l'intent specificato. Per ricevere un'istanza di PackageManager, possiamo usare getPackageManager.

Il nostro codice è riportato di seguito:

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
    }

Ora implementare la funzione startRecognition. Questa funzione formerà l'intent appropriato per l'attività di avvio del riconoscimento vocale. Nella pagina della documentazione è possibile trovare informazioni dettagliate su come farlo.

Codice sorgente:

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

E per ultimo implementeremo la funzione installGoogleVoiceSearch. Questa funzione mostrerà la finestra di dialogo che chiede all'utente se vuole installare Google Voice Search e, in caso affermativo, lo indirizza a 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
    }

Questo è tutto. Eseguiamo l'attività di riconoscimento vocale. Quindi richiediamo all'utente l'autorizzazione per installare Voice Search e, se l'utente acconsente, lo indirizziamo a Google Play. Una cosa che ci rimane da fare è raccogliere i risultati del riconoscimento vocale.

Inviamo una richiesta utilizzando la funzione startActivityForResult per raccogliere i risultati dell'attività avviata. Abbiamo anche bisogno di ridefinire un metodo OnActivityResult nell'attività del chiamante dell'intent. Lo si può realizzare nel modo seguente:

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

Ora siamo pronti

La classe creata SpeechRecognitionHelper ci permette di effettuare una richiesta di riconoscimento vocale chiamando una sola funzione run().

Tutto ciò che occorre fare per aggiungere una funzione di riconoscimento è aggiungere questa classe nel nostro progetto e richiamare la funzione run nel punto necessario. Implementare quindi l'elaborazione del testo dei risultati ridefinendo il metodo onActivityResult per l'attività che ha avviato la chiamata di riconoscimento.

Per ulteriori informazioni è possibile consultare il sito Web degli sviluppatori Android. Si possono trovare esempi interessanti che mostrano come fare il riconoscimento vocale, e soprattutto, come ottenere l'elenco delle lingue disponibili. Questo elenco è utile per il riconoscimento di lingue diverse da quella dell'impostazione locale predefinita dell'utente.

Per integrare rapidamente l'input vocale nell'applicazione, è possibile scaricare e utilizzare questo codice per la classe SpeechRecognitionHelper.

Informazioni sugli autori

Stanislav lavora nel gruppo software e servizi presso Intel Corporation. Ha oltre 10 anni di esperienza nello sviluppo di software. Il suo interesse principale è l'ottimizzazione delle prestazioni, del consumo di energia e della programmazione parallela. Nel suo attuale ruolo di ingegnere di applicazioni, in cui fornisce supporto tecnico per i dispositivi basati su Intel, Stanislav lavora in stretto contatto con gli sviluppatori di software e i progettisti SoC per aiutarli a raggiungere le prestazioni migliori possibili sulle piattaforme Intel. Stanislav ha conseguito un Master in Economia matematica presso la Scuola Superiore delle Scienze economiche dell'Università Nazionale di Ricerche.

Mikhail è co-autore di questo blog ed è uno stagista estivo presso Intel che sta studiando informatica all'Università Lobachevskij. Gli piace immergersi nella matematica ed escogitare trucchi di programmazione Android.

 

Intel e il logo Intel sono marchi di Intel Corporation registrati negli Stati Uniti e/o in altri paesi.
Copyright © 2013 Intel Corporation. Tutti i diritti riservati.
*Altri marchi e denominazioni potrebbero essere proprietà di terzi.

Per informazioni più dettagliate sulle ottimizzazioni basate su compilatore, vedere il nostro Avviso sull'ottimizzazione.