更新:根据我今天的测试,这个bug似乎已经得到解决,这不再是必需的步骤。如果以后再次出现问题,将其保留。从我的测试结果来看,语音超时功能正常工作。
好吧,我知道这很丑陋,但使用onPartialResults似乎能够解决问题(我了解onPartialResults的注意事项,但我已经尝试了几次,直到Google修复这个荒谬的错误之前,这个方法看起来行得通!)我还没有进行全面测试(一旦我在应用程序中使用它,我会返回测试结果),但我迫切需要一个解决方案。基本上,我使用onRmsChanged触发用户完成讲话,并假设当RmsDb下降到峰值以下且2秒内没有onPartialResults时,我们完成了讲话。
我不喜欢的一件事是销毁SR会发出双重uh-oh声。供参考和自己体验。请发布任何改进意见!
注意:如果您要重复使用此代码,请勿忘记重置bBegin和fPeak!同时,您需要重新创建SR(可以在onStartCommand中或停止并启动服务中实现。)
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.ArrayList;
public class SpeechToTextService extends Service {
private String TAG = "STT";
float fPeak;
boolean bBegin;
long lCheckTime;
long lTimeout = 2000;
@Override
public void onCreate() {
super.onCreate();
bBegin = false;
fPeak = -999;
final SpeechRecognizer sr = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
sr.setRecognitionListener(new RecognitionListener() {
@Override
public void onReadyForSpeech(Bundle bundle) {
Log.i(TAG, "onReadyForSpeech");
}
@Override
public void onBeginningOfSpeech() {
bBegin = true;
Log.i(TAG, "onBeginningOfSpeech");
}
@Override
public void onRmsChanged(float rmsDb) {
if(bBegin) {
if (rmsDb > fPeak) {
fPeak = rmsDb;
lCheckTime = System.currentTimeMillis();
}
if (System.currentTimeMillis() > lCheckTime + lTimeout) {
Log.i(TAG, "DONE");
sr.destroy();
}
}
}
@Override
public void onBufferReceived(byte[] buffer) {
Log.i(TAG, "onBufferReceived");
}
@Override
public void onEndOfSpeech() {
Log.i(TAG, "onEndOfSpeech");
}
@Override
public void onError(int error) {
Log.i(TAG, "onError:" + error);
}
@Override
public void onResults(Bundle results) {
ArrayList data = results.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION);
String sTextFromSpeech;
if (data != null) {
sTextFromSpeech = data.get(0).toString();
} else {
sTextFromSpeech = "";
}
Log.i(TAG, "onResults:" + sTextFromSpeech);
}
@Override
public void onPartialResults(Bundle bundle) {
lCheckTime = System.currentTimeMillis();
ArrayList data = bundle.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION);
String sTextFromSpeech;
if (data != null) {
sTextFromSpeech = data.get(0).toString();
} else {
sTextFromSpeech = "";
}
Log.i(TAG, "onPartialResults:" + sTextFromSpeech);
}
@Override
public void onEvent(int eventType, Bundle params) {
Log.i(TAG, "onEvent:" + eventType);
}
});
Intent iSRIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
iSRIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
iSRIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
iSRIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());
iSRIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en-US");
iSRIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en-US");
sr.startListening(iSRIntent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}