EDIT: I should have mentioned this already, but I'm running this code in a service. The entire app is turned on/off by a widget button and has no activity.
Update: I tried attaching the SDK sources to the project so I could get a more precise idea of where the failure was occurring, but from the looks of it, only public APIs are included, which seems to make them a lot less useful... can anyone suggest at least a debugging approach for solving this issue? I'm kind of stuck.
I'm trying to use Android's speech recognition package to record user speech and translate it to text. Unfortunately, when I attempt initiate listening, I get an ANR error that doesn't point to anything specific.
As the SpeechRecognizer API indicates, a RuntimeException is thrown if you attempt to call it from the main thread. This would make me wonder if the processing was just too demanding... but I know that other applications use the Android API for this purpose and it is typically pretty snappy.
java.lang.RuntimeException: SpeechRecognizer should be used only from the application's main thread
Here is a (trimmed) sample of the code I'm trying to call from my service. Is this the proper approach?
Thanks for taking the time to help. This has been a hurdle I haven't been able to get over yet.
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
"com.domain.app");
SpeechRecognizer recognizer = SpeechRecognizer
.createSpeechRecognizer(this.getApplicationContext());
RecognitionListener listener = new RecognitionListener() {
@Override
public void onResults(Bundle results) {
ArrayList<String> voiceResults = results
.getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
if (voiceResults == null) {
Log.e(getString(R.string.log_label), "No voice results");
} else {
Log.d(getString(R.string.log_label), "Printing matches: ");
for (String match : voiceResults) {
Log.d(getString(R.string.log_label), match);
}
}
}
@Override
public void onReadyForSpeech(Bundle params) {
Log.d(getString(R.string.log_label), "Ready for speech");
}
@Override
public void onError(int error) {
Log.d(getString(R.string.log_label),
"Error listening for speech: " + error);
}
@Override
public void onBeginningOfSpeech() {
Log.d(getString(R.string.log_label), "Speech starting");
}
};
recognizer.setRecognitionListener(listener);
recognizer.startListening(intent);
The Android Speech API provides recognition control, background services, intents, and support for multiple languages. Again, it can look like a simple addition to the user input for your apps, but it's a very powerful feature that makes them stand out.
Depending on the app you are using, speech recognition sometimes requires an internet connection to work. Please note that some apps require to send your speech to a server in order to convert it to text.
The speech recognition part of the Web Speech API allows authorized Web applications to access the device's microphone and produces a transcript of the voice being recorded. This allows Web applications to use voice as one of the input & control method, similar to touch or keyboard.
From a service, you have to create the recognizer from looper running on the main thread. Also RecognizerIntent.EXTRA_RESULTS should be SpeechRecognizer.RESULTS_RECOGNITION.
psuedo code:
public class VoiceRecognition implements RecognitionListener, Runnable
{
@Override
public void run()
{
recognizer = SpeechRecognizer.createSpeechRecognizer(yourContext);
recognizer.setRecognitionListener((RecognitionListener) this);
intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
//... all the intent stuff ...
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
recognizer.startListening(intent);
}
@Override
public void onResults(Bundle results)
{
ArrayList<String> matches;
matches=results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
}
}
....
VoiceRecognition voiceRecognizer = new VoiceRecognition();
Handler loopHandler = new Handler(Looper.getMainLooper());
loopHandler.post(voiceRecognizer);
Make Sure to use the RECORD_AUDIO permission.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With