Reputation: 459
I have an app that uses SpeechRecognizer (in onCreate function):
mIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mRecognizer.setRecognitionListener(this);
I have a single button that starts and stops the speech recognition (in 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;
}
The problem is when I rapidly tap the button as soon as the activity starts, a force close notification appears with this error log:
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)
It does not crash the application but I would like to prevent this from happening. From what I understand from the logs, my code called stoplistening before the speech recognizer is ready. Is there a way to check if its ok to stopListening/startListening?
Additionally, the bug only occurs if I rapidly tap it as soon as the activity starts. Otherwise, speechrecognizer just calls onError and I can update my button from there. I'm contemplating on adding a delay to give speechrecognizer sometime to process thing through but it feels clunky.
Upvotes: 1
Views: 2214
Reputation: 9572
You can't quite replace stop with cancel and say it solves the rapid stop problem because cancel isn't the same -
cancel
will stop the recognizer and not show any results.
stopListening
will stop the recording and trigger the onResults
listener callback with the transcription of the recording so far.
On my phone (OS 4.4.2) - I found calling stopListening
before the onReadyForSpeech
happened will cause the recognizer to become stuck! No onResults
or onError
is called and attempting to start it again causes a BUSY error.
The solution - set mIsRecording to true only on onReadyForSpeech
When you want to stop the recognizer call stopListening
only if the flag is true. If its false then call cancel
instead and trigger the end event manually.
Upvotes: 1
Reputation: 18151
Instead of mRecognizer.stopListening();
you should call mRecognizer.cancel();
If the OS is JB you have to implement a countdown timer see Android Speech Recognition as a service on Android 4.1 & 4.2
Upvotes: 1