3 votes

SpeechRecognizer n'entend pas après le premier résultat

J'utilise SpeechRecognizer et RecognizerIntent dans Android pour mettre en œuvre la reconnaissance vocale. Mon objectif est de redémarrer l'écoute de la parole après que le système de reconnaissance vocale ait affiché les résultats à l'écran. Pour cela, j'utilise le code suivant.

Le problème est que la première fois s'exécute bien et affiche les résultats, mais après avoir commencé à écouter pour la deuxième fois (appelé par la méthode onResults), il n'entend pas ce qui est dit pour une raison quelconque. Il affiche alors une erreur ERROR_SPEECH_TIMEOUT, ce qui signifie qu'il n'y a pas eu d'entrée de parole. Sur Logcat, je peux voir qu'il entre dans onReadyForSpeech() mais, pour une raison quelconque, il n'entend pas ce que je dis.

Quelqu'un sait-il pourquoi cela peut se produire ? Est-ce qu'il continue à écouter après avoir retourné un résultat ? Est-il correct d'appeler à nouveau startListening de manière explicite ?

public class VR extends Activity implements RecognitionListener {

    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
    private TextView vrtext;
    private SpeechRecognizer speech = null;
    private Intent intent;
    private String TAG = "VR";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.vr);

        vrtext = (TextView) findViewById(R.id.vrtext);  

    }

    @Override
    public void onResume()
    {
        listen();
        super.onResume();
    }

    private void listen()
    {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

        speech.startListening(intent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // TODO Auto-generated method stub

        if(speech != null)
        {
            speech.destroy();
            Log.i(TAG,"destroy");
        }

    }

    public void onBeginningOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onbeginningofspeech");
    }

    public void onBufferReceived(byte[] arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onbufferreceived");
    }

    public void onEndOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onendofspeech");
    }

    public void onError(int arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "error code: " + arg0);
    }

    public void onEvent(int arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onevent");
    }

    public void onPartialResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onpartialresults");
    }

    public void onReadyForSpeech(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onreadyforspeech");
    }

    public void onResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onresults");
        ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        String s = "";
        for (String result:matches)
            s += result + "\n";

        vrtext.setText(s);

        speech.startListening(intent);

    }

    public void onRmsChanged(float arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onrmschanged");
    }

}

2voto

gregm Points 5441

"Est-ce qu'il continue à écouter après avoir retourné un résultat ?" Non

"Est-il correct d'appeler startListening à nouveau explicitement ?" Oui.

De plus, si vous voulez que la reconnaissance se fasse de manière continue, vous devez appeler startListening à nouveau si des erreurs se produisent comme ceci :

@Override
public void onError(int errorCode)
{
    if ((errorCode == SpeechRecognizer.ERROR_NO_MATCH)
            || (errorCode == SpeechRecognizer.ERROR_SPEECH_TIMEOUT))
    {
        Log.d(TAG, "didn't recognize anything");
        // keep going
        recognizeSpeechDirectly();
    }
    else
    {
        Log.d(TAG,
                "FAILED "
                        + SpeechRecognitionUtil
                                .diagnoseErrorCode(errorCode));
    }
}

Consultez mon code pour utiliser SpeechRecognizer pour détecter un certain mot prononcé ici .

1voto

Ε Г И І И О Points 1582

Veillez à utiliser un seul SpeechRecognizer à l'intérieur de l'activité. Le moyen le plus rapide et le plus sale est de le rendre statique.

private static SpeechRecognizer speech = null;

Changez votre listen() pour vérifier la présence de nullité sur l'objet parole.

private void listen()
{
    if (speech == null) {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
    }
    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

    speech.startListening(intent);
}

Appelez la méthode d'écoute dans onResults() et en onError() .

public void onResults(Bundle arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "onresults");
    ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
    String s = "";
    for (String result:matches)
        s += result + "\n";

    vrtext.setText(s);

    //speech.startListening(intent);
    listen();

}

public void onError(int arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "error code: " + arg0);
    listen();
}

Et enfin, n'oubliez pas de faire le nettoyage nécessaire en onDestroy() .

@Override
public void onDestroy() {
    super.onDestroy();
    speech.destroy();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X