I'm having problems using the RecognizerIntent API on Android 2.2. When I call the API using this code:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
startActivityForResult(intent, REQUEST_CODE_VOICE_SEARCH);
which looks like it should work, the search popup says "Unknown problem" on the device and in the logs it states:
01-17 14:25:30.433: ERROR/RecognitionActivity(9118): ACTION_RECOGNIZE_SPEECH intent called incorrectly. Maybe you called startActivity, but you should have called startActivityForResult (or otherwise included a pending intent).
01-17 14:25:30.433: INFO/RecognitionControllerImpl(9118): startRecognition(#Intent;action=android.speech.action.RECOGNIZE_SPEECH;launchFlags=0x800000;component=com.google.android.voicesearch/.IntentApiActivity;B.fullRecognitionResultsRequest=true;S.android.speech.extra.LANGUAGE_MODEL=free_form;end)
01-17 14:25:30.433: INFO/RecognitionControllerImpl(9118): State change: STARTING -> STARTING
01-17 14:25:30.443: ERROR/RecognitionControllerImpl(9118): required extra 'calling_package' missing in voice search intent
01-17 14:25:30.443: ERROR/RecognitionControllerImpl(9118): ERROR_CLIENT
01-17 14:25:30.443: ERROR/RecognitionControllerImpl(9118): ERROR_CLIENT
It looks like the problem is the missing "calling_package" extra; on the RecognizerIntent page it states that this extra is:
The extra key used in an intent to the speech recognizer for voice
search. Not generally to be used by
developers. The system search dialog
uses this, for example, to set a
calling package for identification by
a voice search API. If this extra is
set by anyone but the system process,
it should be overridden by the voice
search implementation.
As far as I can tell, I don't need to override this extra, so why am I getting this error? How can I fix my code?
I had the exact same problem. I was working on existing code that had android:launchMode="singleInstance" in the activity I was working on. This will not work for speechrecognizer intent. I changed it to android:launchMode="standard". Now let's see how it breaks the rest of my program :)
Your original code:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
startActivityForResult(intent, REQUEST_CODE_VOICE_SEARCH);
Works correctly. I tested it on my device (HTC Desire), and also compared it to other open-source uses, by executing the following query in Google, and browsing the source code.
RecognizerIntent.ACTION_RECOGNIZE_SPEECH
site:code.google.com
One of the output lines in my logcat looks like this:
01-26 13:28:53.268: INFO/RecognitionController(1459): startRecognition(#Intent;action=android.speech.action.RECOGNIZE_SPEECH;component=com.google.android.voicesearch/.IntentApiActivity;B.fullRecognitionResultsRequest=true;S.android.speech.extra.LANGUAGE_MODEL=web_search;S.calling_package=com.test;end)
Run a similar search with one of the built in apps (or downloaded ones), see that it works (and is not a device issue, etc.).
If that works correctly, take the code to a new test project, simply put those lines in the onCreate (Change the result constant to 0), and see if it works.
Have you tried setting the extra yourself?
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
intent.putExtra("calling_package","com.yourpackagename.YourActivityClassName");
startActivityForResult(intent, REQUEST_CODE_VOICE_SEARCH);
This is the approach used by this code and is the suggested solution to a similar issue.
Related
Ok, I know this has been an issue tracked since the release of Jelly Bean. I would like to extend the time before the speech.recognizer shuts off. I'm aware that the documentation states "Additionally, depending on the recognizer implementation, these values may have no effect."
So, If I want this to work is there a solution to "implementing" the recognizer or is this simply a limit prescribed by Google and we have no way to implement the recognizer so these values do mean something?
Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
i.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, Long.valueOf(10000));
i.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(10000));
i.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, Long.valueOf(10000));
i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
If Google has set the parameters, does anyone have a workaround?
first of all i will introduce myself. I am a young student from austria who is new to Android programming. My Project is to write a Barcode scanner and if you scan a product you get more information about it.
So lets get started with the real problem now:
I have done everything what the tutorials say and it works. The ZXING-Source Code is now a libary for my own Project and ofcourse it is included.
When i export the Android project as a FILENAME.APK and copy it to my SGS3 everything works.
Then i install the apk on my phone and start running the app. When i press the scan barcode button which calls the "onClick"-Method it does nothing. Android says to me the application has ben stopped.
I dont know which function i have to use. Should i use the IntentIntegrator methods or the intent methods to be able to scan a code. ( I know i cant use both in my Method, pasted it here to show your my problem )
public void onClick(final View view)
{
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.initiateScan();
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
startActivityForResult(intent, 0);
}
this integration is provided by intents,so you had to have installed app which runs with specific intent (action=com.google.zxing.client.android.SCAN) like Barcode Scanner
i'm pretty sure that you don't have such app on your other phone and thats why you're getting "activity not found" Exception now
Edit: about diffs between IntentIntegrator and plain Intent ... well, there is no diffs beside that with IntentIntegrator you have it all nicely wrapped
I need to support Android 2.1 and up. I know that CalendarContract isn't available in Android 2.1, so I've done the following workaround.
Intent intent = new Intent(Intent.ACTION_EDIT)
.setType("vnd.android.cursor.item/event")
.putExtra("beginTime", beginTime.getTimeInMillis())
.putExtra("title", title)
.putExtra("description", description)
.putExtra("eventLocation", location)
.putExtra("allDay", allDay)
.putExtra(Intent.EXTRA_EMAIL, email );
if(!allDay) {
intent.putExtra("endTime", endTime.getTimeInMillis());
}
startActivity(intent);
This works very well so far. I've tested on 2.1 through 4.1.
I'd like to add reminders, too, but I can't find any documentation on how to do it using Intents. Does anyone have an example? I want to avoid adding more permissions to my manifest for writing to the calendar, so if you have a suggestion that requires that, I won't be able to use it.
If you check the stock android Calendar source code, reminders cannot be added using intent.
Instead of this calendar has a setting to set the default reminder. But some OEMs could have implemented this. So even if you find it, it will not work on all phones.
In my voice recognition based app, I sometimes receive ERROR_RECOGNIZER_BUSY. Intuitively, this calls for... retries, right?
The problem is that this error is very undocumented, so obviously I have questions that perhaps someone more experienced in the field is able to answer:
What triggers such an error? Is it
really only busy server (at Google)?
or this could also hint at a bug in my app?
Do I have to explicitly close/reopen
a session before a retry?
How often to retry? once every
1-second? every 5-seconds? Other?
Your experienced insights are most welcome. Thanks.
I'm not 100% sure of this, however since it's been so long since you posted, I may as well give it a shot.
It seems that you are doing something wrong in the code. As the commenter said, it would be helpful if you actually posted the code that is returning this error.
However, in the source code for the Android speech recognition service found here:
http://source-android.frandroid.com/frameworks/base/core/java/android/speech/RecognitionService.java
we have a function called dispatchStopListening which seems to end the listening process. However, before it actually ends it, there are a few checks for illegal states, including this:
else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
listener.onError(SpeechRecognizer.ERROR_RECOGNIZER_BUSY);
Log.w(TAG, "stopListening called by other caller than startListening - ignoring");
}
This seems to imply that you are trying to end the listening process by some other guy than you started it with, which raises this error.
I hope this helps, but it would be extremely beneficial if you posted the code.
ERROR_RECOGNIZER_BUSY is often thrown when you are already in use of the SpeechRecognizer object. (Or you didn't close one proprely).
Simply add the package to your recognizer intent and it should work. That is what I have done.
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
...
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.package.name");
The most likely cause for ERROR_RECOGNIZER_BUSY is that you have not stopped the recognition service from the main thread and the error thrown was ignored.
This actually is a very simple error. It means the previous listening is not finished. Basically, you need to stop listening. In my App i have 2 button for different languages. calling stopListening() fixed the issue. The error does appear from time to time but the user experience is smooth now. It doesn't cause problems.
speech.stopListening();
USER_ID = 2;
Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, TARGET_CODE);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, TARGET_CODE);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, Conversation.this.getPackageName());
speech.startListening(recognizerIntent);
I wrote a small app to allow the user to choose which language he uses the Voice Search via a button, rather than relying on the user's language preference (sometimes you want to voice search in Japanese without switching your whole UI to Japanese).
I am testing the app on my HTC Desire /Android 2.1 (Softbank-x06ht). However, when I call the voice api, I get a "Connection Failed" dialog box [retry/cancel], and LogCat shows this warning:
09-12 11:26:13.583: INFO/RecognitionService(545): ssfe url=http://www.google.com/m/voice-search
09-12 10:49:45.683: WARN/RecognitionService(545): required parameter 'calling_package' is missing in IntentAPI request
Note that I can use the Google Voice Search app and it works with no problems.
According to the API Docs http://developer.android.com/reference/android/speech/RecognizerIntent.html#EXTRA_CALLING_PACKAGE the calling_package parameter is not to be used by developers. Well, if that is the case, why does the log say it is missing?
I tried to provide the parameter myself but it didnt change the outcome at all.
private static final String TRIVOICE_CALLING_PACKAGE = "calling_package";
private void callSpeechWebSearch (String language) {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,
language);
intent.putExtra(TRIVOICE_CALLING_PACKAGE,
"org.filsa.trivoice");
//intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
try {
startActivity(intent);
} catch (ActivityNotFoundException anfe) {
makeToast("ANFE:" +anfe.getMessage());
}
}
Use this code to get your package name
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
context.getPackageName());
I was having the same problem and set the calling package to the actual calling package (not class) and things then worked correctly. Android 2.2 on a Tmobile G2.