10

SpeechRecognizer works well on Android that with Google Apps (GApps). However in China, most of the Android devices will remove these Google Apps. What will happen when SpeechRecognizer is used? How could I test it without an actual device?

speechRecognizer = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
speechRecognizer.setRecognitionListener(new CustomListener());
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh_HK");
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, false);
intent.putExtra("android.speech.extra.EXTRA_ADDITIONAL_LANGUAGES", new String[]{"zh_HK", "en-US"});
speechRecognizer.startListening(intent);

where CustomListener() implements RecognitionListener.

Raptor
  • 53,206
  • 45
  • 230
  • 366
  • 2
    a possibility is to check via PackageManager if `Gapps` is installed by for example check `com.android.vending`. If not, then an alternative way for Speech recognizing could be sphinx: http://cmusphinx.sourceforge.net/ – Opiatefuchs Jun 16 '16 at 10:57
  • Good idea. However, Sphinx's language file takes up a lot of spaces. Will the above code crashes if no checking is added ? – Raptor Jun 16 '16 at 11:01
  • well, that´s a very good question and if I could I would give more upvotes to this. But really.....I don´t know. If I start from the normal case, an Intent to handle some action will crash if there is no package to do this. I think it´s the same with missing gapps, why should it be treated on another way. Avoid this can be done by intent.resolveActivity(pckManager) != null`, I guess. – Opiatefuchs Jun 16 '16 at 11:33
  • Maybe you can test it if you have some unused device and install cyanogenmod without the gapps. – Opiatefuchs Jun 16 '16 at 11:35
  • 2
    another idea is to set a `` to the manifest with `com.android.vending` , but I never tried to give a uses feature for a software. But it´s described in API, `for hardware or software`...... – Opiatefuchs Jun 16 '16 at 11:36

1 Answers1

6

I'm sure you are aware of most of the following, but for the sake of a comprehensive answer:

Any application can register as a Speech Recognition Provider, so long as it registers a RecognitionService correctly. In the case of Samsung devices, the Android Voice Search Settings will show two providers, Google and Vlingo.

Google's RecognitionService is packaged within their Google 'Now' application, which as you are aware, is reliant on Google Play Services.

Vlingo's RecognitionService is within their S-Voice application, which is only available publicly preinstalled on Samsung devices - so not really applicable to your question, but I mention due to my comment further down.

Before you use the SpeechRecognizer, you should always use the static helper method:

if (SpeechRecognizer.isRecognitionAvailable(getApplicationContext())) {
    // initialise
   } else {
   // nope
   }

As quoted by the method documentation:

Checks whether a speech recognition service is available on the system. If this method returns false, createSpeechRecognizer(Context) will fail.

Returns true if recognition is available, false otherwise

If you use this method in your particular use case, it should return false, so you don't have to worry about initialisation crashes.

As a note, Vlingo will return true here, but will never actually return speech responses, it will just throw ERROR_NETWORK for some reason. It's annoying.

Aside from the above check, you can also query which, if any, applications are registered as a Voice Recognition Provider by doing the following:

final List<ResolveInfo> services = context.getPackageManager().queryIntentServices(
                    new Intent(RecognitionService.SERVICE_INTERFACE), 0);

Any empty list, would mean no providers are available.

Finally, as mentioned in the comments, you could always treble check and make sure the Google application is installed:

Assuming you're targetting Jelly Bean+ I use the following convenience method:

/**
 * Check if the user has a package installed
 *
 * @param ctx         the application context
 * @param packageName the application package name
 * @return true if the package is installed
 */
public static boolean isPackageInstalled(@NonNull final Context ctx, @NonNull final String packageName) {
    try {
        ctx.getApplicationContext().getPackageManager().getApplicationInfo(packageName, 0);
        return true;
    } catch (final PackageManager.NameNotFoundException e) {
        return false;
    }
}

Where Google's package name is com.google.android.googlequicksearchbox

Very finally, rather than the headache of getting users to side load gapps, I'm sure you know there are many other voice recognition providers out there, who provider RESTful services you could use. Not all are free through.

brandall
  • 6,094
  • 4
  • 49
  • 103