Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto download offline speech recognition language on Android

Is there any way in Java to detect if an Android device has an offline speech recognition language installed, and if it does not prompt the user to download it?

I know you can ask to speech to text to prefer offline speech to text, but how do you know if the device has the language installed?

This question is not on how to use offline speech, this works. The question is "how to detect and download/install offline speech languages" from Java app code. i.e. have the app detect if they have offline German language installed, and if not prompt the user to download/install it.

like image 472
James Avatar asked Feb 03 '17 21:02

James


People also ask

How do I get offline speech recognition?

Android does have offline speech recognition capabilities. You can activate this by going to Settings - Language and Input - Voice Input and touch the cog icon next to Enhanced Google Services.

How do I stop my phone from downloading speech services?

Launch the Android phone Settings and open Apps or Application Manager. Now find Speech Services by Google and tap on it. Some users may have to enable viewing of System Apps or look under other apps. Then tap on Force Stop and afterward, confirm to Force Stop the app.


1 Answers

This is not the answer you are hoping for, as at the time of writing, I don't believe there is a straight forward solution to this. I very much hope to be proved wrong.

I requested an enhancement to provide this information programmatically a long time ago - here

The enhancement suggested an additional parameter RecognizerIntent.EXTRA_SUPPORTED_OFFLINE_LANGUAGES:

It would surely be trivial for this to be added and used in the following way:

final Intent vrIntent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
getContext().sendOrderedBroadcast(vrIntent, null, new BroadcastReceiver() {

    @Override
    public void onReceive(final Context context, final Intent intent) {

        final ArrayList<String> vrStringLocales = intent.getExtras().getStringArrayList(
                RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);

        // This would be nice
        final ArrayList<String> vrStringOfflineLocales = intent.getExtras().getStringArrayList(
                RecognizerIntent.EXTRA_SUPPORTED_OFFLINE_LANGUAGES);
    }

}, null, 1234, null, null);

Alas, it has never happened.

You do have two other options to attempt to handle this gracefully.

In the unlikely event you application runs with root permissions, you can check the location of /data/data/com.google.android.googlequicksearchbox/app_g3_models/ which contains the offline files, labelled quite handily by their locale.

The second involves knowing when the user needs a prompt to install the missing offline files.

From my experience, the recognition error of SpeechRecognizer.ERROR_SERVER most often denotes this, but it is not foolproof.

@Override
public void onError(final int error) {

    switch (error) {

        case SpeechRecognizer.ERROR_SERVER:
            // TODO - prompt to install offline files
            break;
    }
}

When detected, you can guide the user to the correct installation screen.

public static final String PACKAGE_NAME_GOOGLE_NOW = "com.google.android.googlequicksearchbox";
public static final String ACTIVITY_INSTALL_OFFLINE_FILES = "com.google.android.voicesearch.greco3.languagepack.InstallActivity";

public static boolean showInstallOfflineVoiceFiles(@NonNull final Context ctx) {

    final Intent intent = new Intent();
    intent.setComponent(new ComponentName(PACKAGE_NAME_GOOGLE_NOW, ACTIVITY_INSTALL_OFFLINE_FILES));

    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    try {
        ctx.startActivity(intent);
        return true;
    } catch (final ActivityNotFoundException e) {

    } catch (final Exception e) {

    }

    return false;
}

Using hard-coded values such as this, is of course not ideal, but neither is this situation!

Once you've messed around with all of the above and think you have a good interim solution - think again! Regardless of whether the user has correctly installed the missing offline files, it is highly likely it still won't work.....

My answer here describes the process I still have to guide my user's with. It's very frustrating.

Finally one more bug to throw into the mix - RecognitionListener.onError(int) can be thrown when there isn't an error. Check my gist from the answer here to use a BugRecognitionListener so you can check the callbacks are being sent in the correct order and ignore those that aren't. This remains a problem, despite my answer suggesting a fix in a previous release.

The above should keep you busy! Good luck....

like image 82
brandall Avatar answered Oct 17 '22 14:10

brandall