第一个结果后,SpeechRecognizer没有听到

时间:2012-06-25 19:29:48

标签: android speech-recognition voice-recognition speech

我在Android中使用SpeechRecognizer和RecognizerIntent来实现语音识别。我的目标是在语音识别器在屏幕上显示结果后重新开始听讲话。为此,我使用以下代码。

问题是,第一次运行正常并显示结果但是在第二次开始监听之后(从onResults方法调用),它没有听到由于某种原因说出的内容。然后它给出ERROR_SPEECH_TIMEOUT错误,这意味着没有语音输入。在Logcat上,我可以看到它进入onReadyForSpeech(),但不知何故,它不会听到我在说什么。

有谁知道为什么会这样?它返回结果后会继续听吗?再次显式调用startListening是否正确?

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

}

2 个答案:

答案 0 :(得分:2)

“它会在返回结果后继续听吗?” 没有

“显式再次调用startListening是否正确?” 是。

此外,如果您想继续进行识别,如果出现以下错误,则应再次致电startListening

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

查看我的代码,使用SpeechRecognizer检测某个语音here

答案 1 :(得分:1)

确保在活动中使用单个SpeechRecognizer对象。快速而肮脏的方法是使其静止。

private static SpeechRecognizer speech = null;

更改listen()方法,检查语音对象为空。

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

onResults()onError()中调用listen方法。

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

最后不要忘记在onDestroy()进行必要的清洁。

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