SpeechRecognizer 在第一次收听时抛出 onError
SpeechRecognizer throws onError on the first listening
在Android5 我遇到了奇怪的问题。第一次调用 SpeechRecognizer 的 startListening
会导致错误代码为 7 (ERROR_NO_MATCH) 的 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
那么,这个错误的原因是什么,我该如何解决?
我遇到了同样的问题,但我找不到解决方法,所以如果 startListening 和 onError 之间的时间过短,我最终只是在 onError 中调用 return。
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.
}
一旦您为每个屏幕配置 "Okay Google" 功能,就会出现错误。
原来是这个原因!
关闭该功能,问题应该就解决了
我在多台设备上都遇到了同样的问题。似乎 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
}
完成了一种解决方法。
这是常规流程
onReadyForSpeech -->onBeginningOfSpeech-->onEndOfSpeech -->onResults
但是流量很奇怪
onError(不匹配)-->onReadyForSpeech-->onBeginningOfSpeech-->onEndOfSpeech-->onResults
因此将语音结束时的布尔值设置为真。并检查 onError 以确保它在演讲结束后抛出错误!
speech.startListening(recognizerIntent);
isEndOfSpeech = false;
@Override
public void onError(int error) {
if (!isEndOfSpeech)
return;
}
@Override
public void onEndOfSpeech() {
isEndOfSpeech = true;
}
结果证明对我来说非常简单。语音识别的启动声音太大,一开始就触发了收听过程。调低系统声音会有帮助。 (音量键)
在Android5 我遇到了奇怪的问题。第一次调用 SpeechRecognizer 的 startListening
会导致错误代码为 7 (ERROR_NO_MATCH) 的 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
那么,这个错误的原因是什么,我该如何解决?
我遇到了同样的问题,但我找不到解决方法,所以如果 startListening 和 onError 之间的时间过短,我最终只是在 onError 中调用 return。
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.
}
一旦您为每个屏幕配置 "Okay Google" 功能,就会出现错误。
原来是这个原因!
关闭该功能,问题应该就解决了
我在多台设备上都遇到了同样的问题。似乎 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
}
完成了一种解决方法。
这是常规流程
onReadyForSpeech -->onBeginningOfSpeech-->onEndOfSpeech -->onResults
但是流量很奇怪
onError(不匹配)-->onReadyForSpeech-->onBeginningOfSpeech-->onEndOfSpeech-->onResults
因此将语音结束时的布尔值设置为真。并检查 onError 以确保它在演讲结束后抛出错误!
speech.startListening(recognizerIntent);
isEndOfSpeech = false;
@Override
public void onError(int error) {
if (!isEndOfSpeech)
return;
}
@Override
public void onEndOfSpeech() {
isEndOfSpeech = true;
}
结果证明对我来说非常简单。语音识别的启动声音太大,一开始就触发了收听过程。调低系统声音会有帮助。 (音量键)