2015-06-26 11 views
5

In Android 5 ho dovuto affrontare strani problemi. La prima chiamata allo standard startListening di SpeechRecognizer risulta nell'errore con il codice di errore 7 (ERROR_NO_MATCH).SpeechRecognizer genera onError al primo ascolto

ho fatto test di app con il seguente codice:

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

e hanno questa messaggi di log dopo la prima startListening chiamata:

onError 7 
onReadyForSpeech 
onBeginningOfSpeech 
onEndOfSpeech 
onResults 

E seguenti messaggi dopo l'altro startListening chiamate:

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

Quindi, qual è la ragione di questo errore e come Lo aggiusto?

+0

Potrebbe essere un bug nell'implementazione di SpeechRecognizer che si sta utilizzando. Quale implementazione è? Per esempio. Sto vedendo qualcosa di simile con Google App 4.7.13.19.arm. – Kaarel

+0

Sì, @Kaarel, il problema è nella versione 4.7.13.19.arm – xVir

risposta

2

Ho avuto lo stesso problema ma non sono riuscito a trovare una soluzione alternativa, quindi ho finito con il chiamare return in onError se il tempo tra startListening e onError è irragionevolmente breve.

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. 
} 
+0

Sembra, è l'unica opzione ... Grazie! :) – xVir

5

Non appena si configura la funzione "OK Google" su ogni schermata, viene visualizzato l'errore.

Quindi questa sembra essere la ragione!

disattivare la funzione e il problema deve essere risolto

+1

Confermato, questa sembra essere la causa anche sui miei dispositivi. https://code.google.com/p/android/issues/detail?id=179293 – ballzak

1

Ho avuto lo stesso problema su più dispositivi. Sembra onError (7) viene sempre chiamato prima onReadyForSpeech(), quindi se per evitare di utilizzare i tempi brutti, si può fare qualcosa di simile:

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

e nel 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

Fatto una soluzione .

Si tratta di un flusso regolare

onReadyForSpeech -> onBeginningOfSpeech -> onEndOfSpeech -> onResults

Ma weired fluire

onError (nessuna corrispondenza) -> onReadyForSpeech -> onBeginningOfSpeech -> onEndOfSpeech -> onResults

Quindi impostare un valore booleano alla fine del discorso su true. e controlla onError per assicurarti che abbia generato un errore dopo la fine della parola!

speech.startListening(recognizerIntent); 
isEndOfSpeech = false; 

@Override 
    public void onError(int error) { 
     if (!isEndOfSpeech) 
      return; 
} 


@Override 
    public void onEndOfSpeech() { 
     isEndOfSpeech = true; 
    } 
0

Si è rivelato molto semplice nel mio caso. Il suono di avvio del riconoscimento vocale era troppo alto e ha innescato il processo di ascolto proprio all'inizio. Abbassare il suono del sistema sarebbe d'aiuto. (Il tasto del volume)