Skip to content Skip to sidebar Skip to footer

Text To Speech Returns A Different Non-existant Locale After Setting An Existing One

original question I have a standard texttospeech, android.speech.tts.TextToSpeech I initialize it and set a language by using tts.setLanguage(Locale.getDefault()) That default Loc

Solution 1:

You're right, it's frustrating how the locale codes the TTS object uses are different to those of the device locale. I don't understand why this decision was made.

To add further complication, the TTS Engine can supply all kinds of different locales, such as eng_US_sarah or en-US-female etc. It's down to the TTS Engine how these are stored and displayed.

I've had to write additional code to iterate through the returned locales and attempt to match them to the locale the system can use, or vica-versa.

To start with, take a look at how the engines you have installed are returning their locale information. You can then start to collate in your code a list to associate 'deu_DEU' to 'de_De'.

This is often simplistic by using split("_") & startsWith(String), but unfortunately not for all locales.

Here's some base code I've used to analyse the installed TTS Engines' locale structure.

privatevoidgetEngines() {

    finalIntentttsIntent=newIntent();
    ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

    finalPackageManagerpm= getActivity().getPackageManager();

    final List<ResolveInfo> list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);

    final ArrayList<Intent> intentArray = newArrayList<Intent>(list.size());

    for (inti=0; i < list.size(); i++) {

        finalIntentgetIntent=newIntent();
        getIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

        getIntent.setPackage(list.get(i).activityInfo.applicationInfo.packageName);
        getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);

        intentArray.add(getIntent);

    }

    for (inti=0; i < intentArray.size(); i++) {
        startActivityForResult(intentArray.get(i), i);
    }
}

@OverridepublicvoidonActivityResult(finalint requestCode, finalint resultCode, final Intent data) {

    try {

        if (data != null) {             
            System.out.print(data.getStringArrayListExtra("availableVoices").toString());
        }

    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

From the above ISO-3 codes and the device locale format, you should be able to come up with something for the locales you are concerned with.

I've been intending to submit an enhancement request to AOSP for a while, as all TTS Engines need to use constant values and extras such as gender etc need to be added to use the TTS Engines to their full capabilities.

EDIT: Further to your edit, note the wording regarding setLanguage(). The individual TTS Engine will try and match as close as possible to the requested locale, but that applied locale may be completely wrong, depending on how lenient the Engine provider is in their code and their response.

Solution 2:

After creating an object of TextToSpeech class, you should configure it (or check it's available state/values) into TextToSpeech.OnInitListener's onInit() callback. You will get reliable information there about your TextToSpeech object.

Check my answer here: https://stackoverflow.com/a/65620221/7835969

Post a Comment for "Text To Speech Returns A Different Non-existant Locale After Setting An Existing One"