Detect installed languages for offline recognition

2019-06-15 13:54发布

It is possible to determine via code which language packages are currently installed on a device? Tried this:

    Intent detailsIntent =  new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
    sendOrderedBroadcast(detailsIntent, null, new LanguageDetailsChecker(), null, Activity.RESULT_OK, null, null);

 

    public class LanguageDetailsChecker extends BroadcastReceiver  {

    private List<String> supportedLanguages;

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Bundle results = getResultExtras(true);
        if (results.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES))
        {
            supportedLanguages =results.getStringArrayList(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
            Log.d("TAG","languages: " + supportedLanguages);
        }
    }
}

However, the output shows me tons of languages, while I only have en_UK, en_US and es_ES installed. Any idea?

3条回答
\"骚年 ilove
2楼-- · 2019-06-15 14:13

If you have root(sorry), you can do it this way:

public static boolean isOfflineDictionaryPresent(String language) {
    if (locale == null) locale = Locale.US;
    String dir = "/system/usr/srec/config/" +
            language.replace('_', '.').toLowerCase();
    if ((new File(dir)).isDirectory()) return true;
    return false;
}

This was ripped from the Android 4.2.2 Recognizer.java source and modified:

  • returns a simple boolean instead of the dictionary directory
  • takes a String input(ex. "en_US") instead of a Locale

I'd get the full list just as you are, and loop through them to check which ones are available offline. I've checked the /system/usr/srec/config/ folder on two devices, and they both match the dictionaries I have installed.

Of course, the down side is that it only works for root, so I'm not sure how helpful this will be to you in the end. I'm really not sure what to say for non-root, I can't find anything.


Edit: Out of curiosity, though, what does EXTRA_SUPPORTED_LANGUAGES contain if you are offline? If it returns correctly, you might just have to fake out the network manager.

查看更多
淡お忘
3楼-- · 2019-06-15 14:16

check this sample:

public class SpeakingAndroid extends Activity implements  OnInitListener {

        //TTS object
    private TextToSpeech myTTS;
        //status check code
    private int TS_CHECK_CODE = 0;

        //create the Activity
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

            //check for TTS data
            Intent checkTTSIntent = new Intent();
            checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
            startActivityForResult(checkTTSIntent, TS_CHECK_CODE);
    }

        //act on result of TTS data check
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == MY_DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                //the user has the necessary data - create the TTS
            myTTS = new TextToSpeech(this, this);
            }
            else {
                    //no data - install it now
                Intent installTTSIntent = new Intent();
                installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installTTSIntent);
            }
        }
    }

        //setup TTS
    public void onInit(int initStatus) {

            //check for successful instantiation
        if (initStatus == TextToSpeech.SUCCESS) {
            if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE)
                myTTS.setLanguage(Locale.US);
        }
        else if (initStatus == TextToSpeech.ERROR) {
            Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
        }
    }
}

you can get all languages and check each lang is supported by tts or not? myTTS.isLanguageAvailable(Locale.US)

查看更多
Animai°情兽
4楼-- · 2019-06-15 14:38

You Should Simply try this:

 for (Locale locale : Locale.getAvailableLocales()) {
                try {
                    if (tts != null) {
                        if (locale != null && locale.getISO3Country() != null && locale.getISO3Language() != null && tts.isLanguageAvailable(locale) == 1) {
                            available_locs.add(locale);
                            tts.setLanguage((Locale) locale);

                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                if (tts.getVoice().getFeatures().contains(TextToSpeech.Engine.KEY_FEATURE_NOT_INSTALLED)) {
                                    Log.i(TAG, "[onInit]contains:IF " + locale.getDisplayName());
                                } else {
                                    Log.i(TAG, "***********[onInit]contains:ELSE " + locale.getDisplayName());
                                }

                            } else {
                                    /*not supported  21 below sdk so hide progressbar and hide spinner and only TTs in default
                                    language */
                                Log.i(TAG,"Not supported");
                            }

                        }
                    }
                } catch (Exception e) {
                    Log.i(TAG, "[onViewCreated] " + e.getLocalizedMessage());
                }
            }

In else condition you should known install language in your device .

查看更多
登录 后发表回答