Handling RecognitionListener Errors

2019-02-10 10:02发布

I am using the Android's speech API to continuously getting input from the user. However this doesn't work quite well when errors occur.

What I do is restarting the listener in the method that detects error. It works sometime but the recognizer hangs often for some time. Especially after detecting Server, network time out and recognizer busy errors. This is annoying!

I have found some attempt to solve this problem, but none of them worked for me.

Do you have a better idea?

Here i my code:

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条回答
Ridiculous、
2楼-- · 2019-02-10 10:36
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);
查看更多
我想做一个坏孩纸
3楼-- · 2019-02-10 10:41

Try to properly clean up after the error, e.g. call cancel or destroy on the SpeechRecognizer.

查看更多
聊天终结者
4楼-- · 2019-02-10 10:43
  • If you get recognizer busy error you have to call cancel and then call startListening
  • If you get server or network errors you have to check for network connection before calling startListening
查看更多
来,给爷笑一个
5楼-- · 2019-02-10 10:51

I m posting this late , but this might help some one. I was also facing same error , & also it was not listening after some random time , i tried the following & it helped me somewhat, Try doing this ,

case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: 
        recognizer.destroy();
        startSR(); // As it destroys the current objects & calling startSR() will instantiate
                   // objects again 
查看更多
登录 后发表回答