2015-06-26 38 views
5

在Android 5中我遇到了一個奇怪的問題。 SpeechRecognizer的startListening的第一個調用結果爲錯誤代碼7的onError(ERROR_NO_MATCH)。SpeechRecognizer在第一次聽時會拋出onError

我做了測試應用程序用下面的代碼:

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

而且具有第一startListening調用後此日誌消息:

onError 7 
onReadyForSpeech 
onBeginningOfSpeech 
onEndOfSpeech 
onResults 

又經過startListening調用以下消息:

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

那麼,這個錯誤的原因是什麼?我修復它?

+0

可能是您正在使用的SpeechRecognizer實施中的一個錯誤。它是什麼實現?例如。我看到類似於Google App 4.7.13.19.arm的內容。 – Kaarel

+0

是的,@Kaarel,問題是版本4.7.13.19.arm – xVir

回答

2

我有同樣的問題,但我無法找到一個解決辦法,所以我最終只是打電話內onError的回報,如果startListening和onError的之間的時間是不合理的短。

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

似乎,這是唯一的選擇......謝謝! :) – xVir

5

只要在每個屏幕上配置「Okay Google」功能,就會出現錯誤。

所以這似乎是原因!

取消激活功能並解決問題

+1

確認,這似乎也是我的設備上的原因。 https://code.google.com/p/android/issues/detail?id=179293 – ballzak

1

我在幾臺設備上遇到了同樣的問題。這似乎onerror的(7)onReadyForSpeech()之前一直叫,所以如果避免使用醜陋的時候,你可以這樣做:

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

,並在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

完成一個解決方法。

這是一個常規流

onReadyForSpeech - > onBeginningOfSpeech - > onEndOfSpeech - > onResults

但是weired流動

的onError(不匹配) - > onReadyForSpeech - > onBeginningOfSpeech - > onEndOfSpeech - > onResults

因此,將語音結尾的布爾值設置爲true。並檢查onError以確保它在語音結束後發出錯誤!

speech.startListening(recognizerIntent); 
isEndOfSpeech = false; 

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


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

原來我的情況很簡單。語音識別的發射聲音太大,並在開始時觸發了聽音過程。關掉系統聲音會有所幫助。 (音量鍵)

相關問題