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();
}
}
Try to properly clean up after the error, e.g. call
cancel
ordestroy
on theSpeechRecognizer
.cancel
and then callstartListening
startListening
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 ,