【问题标题】:SpeechRecognizer not Hearing After First ResultSpeechRecognizer 在第一个结果后没有听到
【发布时间】:2012-06-25 19:29:47
【问题描述】:

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

}

【问题讨论】:

  • 您在调用listen 时没有清理早期的语音对象。在调用listen方法之前最好在语音对象上调用destroy()

标签: android speech-recognition voice-recognition speech


【解决方案1】:

“它返回结果后是否继续监听?” 没有

“再次显式调用 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

【讨论】:

  • 您是否遇到过在调用 startListening() 后永远不会调用 onReadyForSpeech() 的问题?我在几次调用 startListening() 后看到这种情况发生。并且它发生时是随机的。
  • 是的,我看到了这个错误,我不知道是我的错还是安卓的错误
  • 查看我的回答 (stackoverflow.com/a/57326936/9192635) 了解我是如何解决这个问题的
【解决方案2】:

确保在 Activity 中使用单个 SpeechRecognizer 对象。快速而肮脏的方法是使其成为静态。

private static SpeechRecognizer speech = null;

更改您的 listen() 方法以在语音对象上检查 null。

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

【讨论】:

  • 在调用其onDestroy() 方法之前,请确保speech 不是null
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
  • 2018-12-18
相关资源
最近更新 更多