web-dev-qa-db-fra.com

Est-il possible d’utiliser l’API SpeechRecognizer directement pour la saisie vocale?

Le site Web Android Dev fournit un exemple de saisie vocale à l'aide de l'activité intégrée de saisie vocale de Google. L'activité affiche une fenêtre contextuelle préconfigurée avec le micro et transmet ses résultats à l'aide de onActivityResult().

Ma question: Existe-t-il un moyen d’utiliser la classe SpeechRecognizer directement pour la saisie de la parole sans afficher l’activité prédéfinie? Cela me permettrait de créer ma propre activité pour la saisie vocale.

18
vladimir.vivien

Voici le code utilisant la classe SpeechRecognizer (provenant de ici et ici ):

import Android.app.Activity;
import Android.content.Intent;
import Android.os.Bundle;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.speech.RecognitionListener;
import Android.speech.RecognizerIntent;
import Android.speech.SpeechRecognizer;
import Android.widget.Button;
import Android.widget.TextView;
import Java.util.ArrayList;
import Android.util.Log;



public class VoiceRecognitionTest extends Activity implements OnClickListener 
{

   private TextView mText;
   private SpeechRecognizer sr;
   private static final String TAG = "MyStt3Activity";
   @Override
   public void onCreate(Bundle savedInstanceState) 
   {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Button speakButton = (Button) findViewById(R.id.btn_speak);     
            mText = (TextView) findViewById(R.id.textView1);     
            speakButton.setOnClickListener(this);
            sr = SpeechRecognizer.createSpeechRecognizer(this);       
            sr.setRecognitionListener(new listener());        
   }

   class listener implements RecognitionListener          
   {
            public void onReadyForSpeech(Bundle params)
            {
                     Log.d(TAG, "onReadyForSpeech");
            }
            public void onBeginningOfSpeech()
            {
                     Log.d(TAG, "onBeginningOfSpeech");
            }
            public void onRmsChanged(float rmsdB)
            {
                     Log.d(TAG, "onRmsChanged");
            }
            public void onBufferReceived(byte[] buffer)
            {
                     Log.d(TAG, "onBufferReceived");
            }
            public void onEndOfSpeech()
            {
                     Log.d(TAG, "onEndofSpeech");
            }
            public void onError(int error)
            {
                     Log.d(TAG,  "error " +  error);
                     mText.setText("error " + error);
            }
            public void onResults(Bundle results)                   
            {
                     String str = new String();
                     Log.d(TAG, "onResults " + results);
                     ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                     for (int i = 0; i < data.size(); i++)
                     {
                               Log.d(TAG, "result " + data.get(i));
                               str += data.get(i);
                     }
                     mText.setText("results: "+String.valueOf(data.size()));        
            }
            public void onPartialResults(Bundle partialResults)
            {
                     Log.d(TAG, "onPartialResults");
            }
            public void onEvent(int eventType, Bundle params)
            {
                     Log.d(TAG, "onEvent " + eventType);
            }
   }
   public void onClick(View v) {
            if (v.getId() == R.id.btn_speak) 
            {
                Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);        
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,"voice.recognition.test");

                intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,5); 
                     sr.startListening(intent);
                     Log.i("111111","11111111");
            }
   }
}

Définissez main.xml avec un bouton et donnez l'autorisation RECORD_AUDIO dans manifest

50
png

Vous pouvez utiliser SpeechRecognizer, bien que je ne connaisse aucun exemple de code le concernant au-delà de cette précédente SO question . Cependant, il s’agit d’une nouveauté dans l’API de niveau 8 (Android 2.2) et n’est donc pas largement utilisable au moment de la rédaction de cet article.

1
CommonsWare

Assurez-vous également de demander les autorisations appropriées à l'utilisateur. Je me suis retrouvé coincé avec une erreur 9 renvoyant valeur: INSUFFICIENT_PERMISSIONS, même si j'avais les autorisations RECORD_AUDIO appropriées énumérées dans le manifeste.

En suivant le code exemple ici , j’ai pu obtenir les autorisations de l’utilisateur, puis la reconnaissance vocale a donné de bonnes réponses.

Par exemple. Ce bloc que j'ai mis dans mon onCreate () pour l'activité, bien qu'il puisse aller ailleurs dans le flux de l'interface utilisateur, avant d'appeler les méthodes SpeechRecognizer:

    protected void onCreate(Bundle savedInstanceState) {
        ...
        if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.RECORD_AUDIO)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.RECORD_AUDIO},
                    527);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request. (In this example I just punched in
            // the value 527)
        }
        ...
    }

Indiquez ensuite une méthode de rappel dans l'activité pour la demande d'autorisations:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 527: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

Une autre chose que je dois changer dans l'exemple de code de preetha ci-dessus, où le texte résultant est récupéré dans la méthode onResults (). Pour obtenir le texte réel du discours traduit (plutôt que la taille, à l'impression du code d'origine), imprimez la valeur de la chaîne construite str ou obtenez l'une des valeurs de retour dans ArrayList (data). Par exemple:

.setText(data.get(0));
1
FlannelTuba