语音搜索/ SpeechRecognizer在快速启动/停止收听时崩溃

时间:2013-05-28 03:03:15

标签: android speech-recognition

我有一个使用SpeechRecognizer的应用程序(在onCreate函数中):

mIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mRecognizer.setRecognitionListener(this);

我有一个启动和停止语音识别的按钮(在onClick中):

if (view.getId() == R.id.btnSpeak) {
    if (mIsRecording) {
        mRecognizer.stopListening();
        mBtnSpeak.setBackgroundResource(R.drawable.mic);
        mIsCanceled = true;

    } else {
        mRecognizer.startListening(mIntent);
        mBtnSpeak.setBackgroundResource(R.drawable.mic_green);
    }

    mIsRecording = !mIsRecording;
}

问题是,当活动开始后我立即快速点击按钮时,会出现强制关闭通知,并显示此错误日志:

05-28 11:35:19.460: E/AndroidRuntime(9288): FATAL EXCEPTION: main
05-28 11:35:19.460: E/AndroidRuntime(9288): java.lang.NullPointerException
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.speechservice.MicrophoneManagerImpl.stopListening(MicrophoneManagerImpl.java:195)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.speechservice.RecognitionControllerImpl.onStopListening(RecognitionControllerImpl.java:280)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.GoogleRecognitionService.onStopListening(GoogleRecognitionService.java:58)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService.dispatchStopListening(RecognitionService.java:118)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService.access$100(RecognitionService.java:36)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService$1.handleMessage(RecognitionService.java:82)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.os.Looper.loop(Looper.java:130)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.app.ActivityThread.main(ActivityThread.java:3746)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at java.lang.reflect.Method.invokeNative(Native Method)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at java.lang.reflect.Method.invoke(Method.java:507)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at dalvik.system.NativeStart.main(Native Method)
05-28 11:35:19.460: E/AndroidRuntime(9288): [Blue Error Handler] Make Debugging Report file for main
05-28 11:35:19.460: E/AndroidRuntime(9288): java.lang.NullPointerException
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.speechservice.MicrophoneManagerImpl.stopListening(MicrophoneManagerImpl.java:195)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.speechservice.RecognitionControllerImpl.onStopListening(RecognitionControllerImpl.java:280)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.google.android.voicesearch.GoogleRecognitionService.onStopListening(GoogleRecognitionService.java:58)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService.dispatchStopListening(RecognitionService.java:118)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService.access$100(RecognitionService.java:36)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.speech.RecognitionService$1.handleMessage(RecognitionService.java:82)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.os.Looper.loop(Looper.java:130)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at android.app.ActivityThread.main(ActivityThread.java:3746)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at java.lang.reflect.Method.invokeNative(Native Method)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at java.lang.reflect.Method.invoke(Method.java:507)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
05-28 11:35:19.460: E/AndroidRuntime(9288):     at dalvik.system.NativeStart.main(Native Method)

它不会使应用程序崩溃,但我想防止这种情况发生。根据我对日志的理解,我的代码在语音识别器就绪之前称为stoplistening。有没有办法检查它是否可以stopListening / startListening?

此外,只有在活动开始后我立即点击它,才会出现该错误。否则,speechrecognizer只调用onError,我可以从那里更新我的按钮。我正在考虑添加一个延迟,以便在某个时候处理语音识别器,但它感觉很笨拙。

2 个答案:

答案 0 :(得分:1)

您应该致电mRecognizer.stopListening();而不是mRecognizer.cancel(); 如果操作系统是JB,则必须实现倒数计时器,请参阅Android Speech Recognition as a service on Android 4.1 & 4.2

答案 1 :(得分:1)

你不能用取代取代stop并说它解决了快速停止问题因为取消不一样 -

cancel将停止识别器并且不会显示任何结果 stopListening将停止录制并触发onResults侦听器回调,并记录到目前为止的录制内容。

在我的手机上(操作系统4.4.2) - 我发现在stopListening发生之前调用onReadyForSpeech会导致识别器卡住!调用onResultsonError并尝试再次启动它会导致BUSY错误。

解决方案 - 仅在onReadyForSpeech

上设置mIsRecording为true

当您想要仅在标志为真时停止识别器调用stopListening。如果为false,则改为调用cancel并手动触发结束事件。