5

我正在使用 Android 的语音 API 来不断地从用户那里获取输入。但是,当发生错误时,这并不能很好地工作。

我所做的是在检测错误的方法中重新启动侦听器。它有时会起作用,但识别器经常挂起一段时间。特别是在检测到服务器、网络超时和识别器繁忙错误之后。这很烦人!

我找到了一些解决这个问题的尝试,但没有一个对我有用。

你有更好的主意吗?

这是我的代码:

private void startSR(){

    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    //intent.putExtra(RecognizerIntent., value)
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, mContext.getPackageName());

    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);

    Log.d(TAG,"Speech recognition started!");
    if (recognizer != null) {
        recognizer = null;
        mListener = null;
    }

    Log.d(TAG,"setRecognitionListener");
    recognizer = SpeechRecognizer.createSpeechRecognizer(mContext);
    mListener = new Listener();

    recognizer.setRecognitionListener(mListener);

    recognizer.startListening(intent);

}
class Listener implements RecognitionListener{

    @Override
    public void onBeginningOfSpeech() {
        Log.i(TAG, "onBeginningOfSpeech");
        mStatus = "Beginning speech";
    }

    @Override
    public void onBufferReceived(byte[] buffer) {
        Log.i(TAG, "onBufferReceived");

    }

    @Override
    public void onEndOfSpeech() {
        Log.i(TAG, "onEndOfSpeech");
        mStatus = "Speech ended";
    }


    @Override
    public void onEvent(int eventType, Bundle params) {
        Log.i(TAG, "onEvent " + eventType);

    }

    @Override
    public void onPartialResults(Bundle partialResults) {
        Log.i(TAG, "onPartialResults");
        mStatus = "Partial results";
    }

    @Override
    public void onReadyForSpeech(Bundle params) {
        Log.i(TAG, "onReadyForSpeech");
        mReady = true;
        mStatus = "Speech engine ready";
    }
    @Override
    public void onRmsChanged(float rmsdB) {
        // TODO Auto-generated method stub

    }
    @Override
    public void onError(int error) {
        // TODO Auto-generated method stub
        mError = "";
        mStatus = "Error detected";
        switch (error) {
        case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:                
            mError = " network timeout"; 
            startListening();
            break;
        case SpeechRecognizer.ERROR_NETWORK: 
            mError = " network" ;
            //toast("Please check data bundle or network settings");
            return;
        case SpeechRecognizer.ERROR_AUDIO: 
            mError = " audio"; 
            break;
        case SpeechRecognizer.ERROR_SERVER: 
            mError = " server"; 
            startListening();
            break;
        case SpeechRecognizer.ERROR_CLIENT: 
            mError = " client"; 
            break;
        case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: 
            mError = " speech time out" ; 
            break;
        case SpeechRecognizer.ERROR_NO_MATCH: 
            mError = " no match" ; 
            startListening();

            break;
        case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: 
            mError = " recogniser busy" ; 
            break;
        case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: 
            mError = " insufficient permissions" ; 
            break;

        }
        Log.i(TAG,  "Error: " +  error + " - " + mError);

        //startSR();
    }


    @Override
    public void onResults(Bundle results) {
        mStatus = "Got some results";
        mResultAvailable = true;
        String str = new String();
        Log.d(TAG, "onResults " + results);

        mResults = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

        //mConfidences = results.getDoubleArray(SpeechRecognizer.CONFIDENCE_SCORES);

        Log.i(TAG, toString());

        startListening();


    }



}// class Listener

public ArrayList<String> getResults(){
    return mResults;
}
public void startListening(){
    if (SpeechRecognizer.isRecognitionAvailable(mContext)) {
        if (recognizer!=null){
            recognizer.startListening(intent);
            mResultAvailable = false;
            mResults = new ArrayList<String>();
        }
        else
            startSR();
    }
}
4

4 回答 4

2
  • 如果您收到识别器忙错误,您必须先打电话cancel,然后再打电话startListening
  • 如果您遇到服务器或网络错误,您必须在调用之前检查网络连接startListening
于 2013-05-23T00:26:59.093 回答
2
Intent RC = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        if (!RC.hasExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE))
        { 
            RC.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.dummy");
        } 

        sr.startListening(RC);
于 2014-02-22T13:48:55.177 回答
0

尝试在错误后正确清理,例如调用canceldestroySpeechRecognizer.

于 2013-04-03T09:42:38.653 回答
0

我发布这个很晚,但这可能会帮助一些人。我也面临同样的错误,而且在一段时间后它也没有听,我尝试了以下,它对我有所帮助,试试这样做,

case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: 
        recognizer.destroy();
        startSR(); // As it destroys the current objects & calling startSR() will instantiate
                   // objects again 
于 2014-03-08T12:22:03.673 回答