私は音声認識リスナーを繰り返し開始するサービスを持っているので、ユーザーが話す自由なセッションを持つことができます。このクラスは、5 秒間音声が聞こえない場合に ERROR_SPEECH_TIMEOUT がスローされる Jelly Bean の問題も処理します。したがって、基本的にこれは機能します。ただし、これを繰り返し呼び出すと、 onBeginningOfSpeech() が呼び出されないという事実からも明らかなように、暗黙のうちに失敗します。ここで、まったく話さなければ、Jelly Bean のタイムアウト ハンドラが毎回確実にリスナーを再起動します。音声が聞こえたため、 onResults() が呼び出された後にのみ失敗するようです。onResults() が呼び出された後は、recognirer.startListening(recognizerIntent) が確実に呼び出されますが、私が言ったように、何も起こりません。失敗した場合、それはランダムであり、問題が何であるかを示す Logcat には何もありません。他に何を試すべきかわかりません。うまくいけば、Android 音声認識の専門家の 1 人がこれを以前に見たことがあるでしょう...
最小: 2.2 ターゲット: JB でのテスト: Android 4.1.2
詳細情報 (11-01-13) 私の HTC One の 4.3 アップデートは、この問題に確実に対処しています。以下の私の音声認識サービスは、信頼性が高く正確になりました。エラーなしで少なくとも数分間実行しました。4.1.2 に関しては、4.3 にアップデートする前はうまく機能しているように見えました (Google は何か変更を加えましたか?)...わかりませんが、まだいくつかの単語が読み上げられず、場合によってはエラーが発生しませんでした。聞くのをやめるだけです (この場合、onBeginningOfSpeech() は呼び出されません)。コードでできる限りのことを行ったので、この問題に関して Android 4.1.2 についてユーザーに警告する必要があると思います。
詳細情報 (09-17-13) おそらく、9 月末に HTC の Android アップデート (4.3) が来る予定です ( http://www.ubergizmo.com/2013/09/htc-one-to-receive -android-4-3-jelly-bean-update-this-september/ )。そのデバイスでこの問題が解決されることを願っています。Android 4.1.2 を実行していて、そのバージョンをしばらく使用しているアプリ ユーザーにとっては、問題は残っています。そのような場合にどうすればよいかはまだわかりません。うまくいけば、それがこの問題のある唯一の Android バージョンです。4.1.2 を実行しているデバイスの数を確認する方法はありますか??
詳細情報 (09-15-13) この投稿では、Google 音声認識エンジンが Android 4.x で起動しません。著者は、彼の HTC one でこの問題が発生していると述べています。(Android 4.1.2) でこの問題が発生している HTC も持っています。これはHTCのものに特有のものでしょうか?(または Android 4.1.2 を実行しているデバイス) - JB を実行しているすべての最新のデバイスでテストするのは難しいため、確認できません。著者はさらに、彼の Nexxus 4.2.2 は問題なく動作すると述べています。この問題が発生するデバイスを教えてください。
詳細情報 (9-08-13) 私のコードに問題がないことを確認するために、Android 2.3.3 でもこれをテストし、onResult() > startListening() を 25 回続けて呼び出すことができました。Android 4.1.2 をターゲットにしている場合、3 つまたは 4 つの呼び出しを超えることはありません。誰もこの問題に遭遇していないなんて信じられない?
public class VoiceRecogService extends Service
{
protected AudioManager mAudioManager;
protected SpeechRecognizer mSpeechRecognizer;
protected Intent mSpeechRecognizerIntent;
protected RecognitionListener mSpeechRecognizerListner;
//protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));
protected volatile boolean mIsListening;
protected volatile boolean mIsCountDownOn;
static final int MSG_RECOGNIZER_START_LISTENING = 1;
static final int MSG_RECOGNIZER_CANCEL = 2;
private int mBindFlag;
private Messenger mServiceMessenger;
private Context m_ctx;
private Handler mHandler = new Handler();
//private boolean m_bReadyForSpeechReceived = false;
@Override
public void onCreate()
{
super.onCreate();
m_ctx = this;
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//do not mute beep when speech listening first kicks off
Log.d("TESTING: SPEECH SERVICE: CALL START", "onCreate()");
startListening(false);
}
private void startListening(boolean bMuteSound){
Log.d("TESTING: SPEECH SERVICE: startListening()", mIsListening? "true":"false");
if (bMuteSound==true && Build.VERSION.SDK_INT >= 16)//Build.VERSION_CODES.JELLY_BEAN)
{
// turn off beep sound
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
if (!mIsListening)
{
//mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
recognizeSpeechDirectly ();
mIsListening = true;
}
}
/////////////////////////////////////////////////////////////////////////
/**
* lazy initialize the speech recognizer
*/
private SpeechRecognizer getSpeechRecognizer()
{
if (mSpeechRecognizer == null)
{
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(m_ctx);
}
return mSpeechRecognizer;
}
private RecognitionListener getSpeechRecognizerListner()
{
if (mSpeechRecognizerListner == null)
{
mSpeechRecognizerListner = new SpeechRecognitionListener();
}
return mSpeechRecognizerListner;
}
private void recognizeSpeechDirectly()
{
Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// accept partial results if they come
recognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
recognizeSpeechDirectly(m_ctx,recognizerIntent, getSpeechRecognizerListner(), getSpeechRecognizer());
}
public static void recognizeSpeechDirectly(Context context,
Intent recognizerIntent,
RecognitionListener listener,
SpeechRecognizer recognizer)
{
//need to have a calling package for it to work
if (!recognizerIntent.hasExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE))
{
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.dummy");
}
recognizer.setRecognitionListener(listener);
recognizer.startListening(recognizerIntent);
}
////////////////////////////////////////////////////////////////////////////
public void stop()
{
if (getSpeechRecognizer() != null)
{
getSpeechRecognizer().stopListening();
getSpeechRecognizer().cancel();
getSpeechRecognizer().destroy();
mIsListening = false;
if (Build.VERSION.SDK_INT >= 16);//Build.VERSION_CODES.JELLY_BEAN)
mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
}
}
// Count down timer for Jelly Bean work around
protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
{
@Override
public void onTick(long millisUntilFinished)
{
// TODO Auto-generated method stub
}
@Override
public void onFinish()
{
mIsCountDownOn = false;
Log.d("TESTING: SPEECH SERVICE: CALL START", "onFinish()");
startListening(true);
}
};
@Override
public void onDestroy()
{
super.onDestroy();
if (mIsCountDownOn)
{
mNoSpeechCountDown.cancel();
}
if (mSpeechRecognizer != null)
{
mSpeechRecognizer.destroy();
}
}
protected class SpeechRecognitionListener implements RecognitionListener
{
@Override
public void onReadyForSpeech(Bundle params)
{
if (Build.VERSION.SDK_INT >= 16)//Build.VERSION_CODES.JELLY_BEAN)
{
mIsCountDownOn = true;
mNoSpeechCountDown.start();
}
Log.d("TESTING: SPEECH SERVICE", "onReadyForSpeech");
}
@Override
public void onBeginningOfSpeech()
{
// speech input will be processed, so there is no need for count down anymore
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
}
@Override
public void onEndOfSpeech()
{
Log.d("TESTING: SPEECH SERVICE", "onEndOfSpeech");
}
@Override
public void onBufferReceived(byte[] buffer)
{
//Log.d("TESTING: SPEECH SERVICE", buffer + new String(new byte[] {0x63}));
}
@Override
public void onError(int error)
{
if ((error == SpeechRecognizer.ERROR_NO_MATCH)
|| (error == SpeechRecognizer.ERROR_SPEECH_TIMEOUT)){
if (mIsCountDownOn)
{
mIsCountDownOn = false;
mNoSpeechCountDown.cancel();
}
mIsListening = false;
Log.d("TESTING: SPEECH SERVICE: CALL START", "onError()");
startListening(true);
}
}
@Override
public void onEvent(int eventType, Bundle params)
{
}
@Override
public void onPartialResults(Bundle partialResults)
{
}
@Override
public void onResults(Bundle results)
{
//String str = new String();
//Log.d(TAG, "onResults " + results);
ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
//if(data.size() >=1){
// //check for save it:
//}
for (int i = 0; i < data.size(); i++)
{
Log.d("TESTING: SPEECH SERVICE", (String)data.get(i));
}
//if no "save it" somewhere in there, then continue:
if (mIsCountDownOn)
{
mIsCountDownOn = false;
}
mIsListening = false;
Log.d("TESTING: SPEECH SERVICE: CALL START", "onResults()");
startListening(true);
}
@Override
public void onRmsChanged(float rmsdB)
{
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}