Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpeechRecognizer on Android device without Google Apps

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.

like image 416
Raptor Avatar asked Jun 16 '16 10:06

Raptor


1 Answers

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.

like image 187
brandall Avatar answered Sep 28 '22 11:09

brandall