SpeechRecognizer throws onError on first listen

In Android 5, I ran into a strange problem. The first startListening call results in onError with error code 7 ( ERROR_NO_MATCH ).

I made a test application with the following code:

 if (speechRecognizer == null) { speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this); speechRecognizer.setRecognitionListener(new RecognitionListener() { @Override public void onReadyForSpeech(Bundle bundle) { Log.d(TAG, "onReadyForSpeech"); } @Override public void onBeginningOfSpeech() { Log.d(TAG, "onBeginningOfSpeech"); } @Override public void onRmsChanged(float v) { Log.d(TAG, "onRmsChanged"); } @Override public void onBufferReceived(byte[] bytes) { Log.d(TAG, "onBufferReceived"); } @Override public void onEndOfSpeech() { Log.d(TAG, "onEndOfSpeech"); } @Override public void onError(int i) { Log.d(TAG, "onError " + i); } @Override public void onResults(Bundle bundle) { Log.d(TAG, "onResults"); } @Override public void onPartialResults(Bundle bundle) { Log.d(TAG, "onPartialResults"); } @Override public void onEvent(int i, Bundle bundle) { Log.d(TAG, "onEvent"); } }); } final Intent sttIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en"); sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en"); speechRecognizer.startListening(sttIntent); 

And to have these log messages after the first startListening call:

 onError 7 onReadyForSpeech onBeginningOfSpeech onEndOfSpeech onResults 

And the following messages after another startListening call:

 onRmsChanged ... onRmsChanged onReadyForSpeech onRmsChanged ... onRmsChanged onBeginningOfSpeech onRmsChanged ... onRmsChanged onEndOfSpeech onRmsChanged onRmsChanged onRmsChanged onResults 

So what is the cause of this error and how to fix it?

+5
source share
5 answers

I had the same problem, but I could not find a workaround, so in the end I just called a return inside onError if the time between startListening and onError is unreasonably short.

 protected long mSpeechRecognizerStartListeningTime = 0; protected synchronized void speechRecognizerStartListening(Intent intent) { if (mSpeechRecognizer != null) { this.mSpeechRecognizerStartListeningTime = System.currentTimeMillis(); RLog.d(this, "speechRecognizerStartListening"); this.mSpeechRecognizer.startListening(intent); } } ... @Override public synchronized void onError(int error) { RLog.i(this, this.hashCode() + " - onError:" + error); // Sometime onError will get called after onResults so we keep a boolean to ignore error also if (mSuccess) { RLog.w(this, "Already success, ignoring error"); return; } long duration = System.currentTimeMillis() - mSpeechRecognizerStartListeningTime; if (duration < 500 && error == SpeechRecognizer.ERROR_NO_MATCH) { RLog.w(this, "Doesn't seem like the system tried to listen at all. duration = " + duration + "ms. This might be a bug with onError and startListening methods of SpeechRecognizer"); RLog.w(this, "Going to ignore the error"); return; } // -- actual error handing code goes here. } 
+2
source

Once you set the Good Google feature to each screen, an error will appear.

So it seems that this is the reason!

Deactivate the function and the problem should be resolved.

+5
source

I had the same problem on multiple devices. It seems that onError (7) is always called before onReadyForSpeech (), so to avoid using ugly times, you can do something like:

 public void start(){ performingSpeechSetup = true; speechRecognizer.startListening(intent); } 

and in RecognitionListener:

 public void onReadyForSpeech(Bundle bundle) { performingSpeechSetup = false; } @Override public void onError(int error) { if (performingSpeechSetup && error == SpeechRecognizer.ERROR_NO_MATCH) return; // else handle error } 
+1
source

One workaround completed.

This is a regular thread.

onReadyForSpeech → onBeginningOfSpeech → onEndOfSpeech → onResults

But portable stream

onError (no match) -> onReadyForSpeech -> onBeginningOfSpeech -> onEndOfSpeech -> onResults

So, set the boolean at the end of the speech to true. and check onError to make sure it throws an error after speaking!

 speech.startListening(recognizerIntent); isEndOfSpeech = false; @Override public void onError(int error) { if (!isEndOfSpeech) return; } @Override public void onEndOfSpeech() { isEndOfSpeech = true; } 
+1
source

In my case, it turned out to be very easy. The start of the voice recognition sound was too loud and caused a listening process at the very beginning. Muting the system sound will help. (Volume key)

0
source

All Articles