How to poll available TTS engines for available languages without instantiating each one and wating for init

后端 未结 1 719
孤城傲影
孤城傲影 2020-12-19 06:20

I need to instantiate a TextToSpeech object and set a given language (which is set programmatically and may vary). I know I can use setLanguage() but that will only work if

1条回答
  •  隐瞒了意图╮
    2020-12-19 07:00

    Here is the setup I use for debugging - You could use elements of it in production:

    // Container Class
    
    public class ContainerVoiceEngine {
    
        private String label;
        private String packageName;
        private ArrayList voices;
        private Intent intent;
    
        public ContainerVoiceEngine() {
    
        }
    
        public ContainerVoiceEngine(final String label, final String packageName, final ArrayList voices, final Intent intent) {
    
            this.label = label;
            this.packageName = packageName;
            this.voices = voices;
            this.intent = intent;
        }
    
        public Intent getIntent() {
            return intent;
        }
    
        public void setIntent(final Intent intent) {
            this.intent = intent;
        }
    
        public String getLabel() {
            return label;
        }
    
        public void setLabel(final String label) {
            this.label = label;
        }
    
        public String getPackageName() {
            return packageName;
        }
    
        public void setPackageName(final String packageName) {
            this.packageName = packageName;
        }
    
        public ArrayList getVoices() {
            return voices;
        }
    
        public void setVoices(final ArrayList voices) {
            this.voices = voices;
        }
    }
    
    
    // Usage within an Activity - Debugging only!
    
      private ArrayList containerVEArray;
        private int requestCount;
    
        private void getEngines() {
    
            requestCount = 0;
    
            final Intent ttsIntent = new Intent();
            ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    
            final PackageManager pm = getPackageManager();
    
            final List list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);
    
            containerVEArray = new ArrayList(list.size());
    
            for (int i = 0; i < list.size(); i++) {
    
                final ContainerVoiceEngine cve = new ContainerVoiceEngine();
    
                cve.setLabel(list.get(i).loadLabel(pm).toString());
                cve.setPackageName(list.get(i).activityInfo.applicationInfo.packageName);
    
                final Intent getIntent = new Intent();
                getIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    
                getIntent.setPackage(cve.getPackageName());
                getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
                getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
    
                cve.setIntent(getIntent);
    
                containerVEArray.add(cve);
            }
    
            Log.d("TAG", "containerVEArray: " + containerVEArray.size());
    
            for (int i = 0; i < containerVEArray.size(); i++) {
                startActivityForResult(containerVEArray.get(i).getIntent(), i);
            }
    
        }
    
        @Override
        public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
            Log.i("TAG", "onActivityResult: requestCount: " + " - requestCode: " + requestCode);
    
            requestCount++;
    
            try {
    
                if (data != null) {
    
                    final Bundle bundle = data.getExtras();
    
                    if (bundle != null) {
    
                        Log.d("TAG", containerVEArray.get(requestCode).getLabel() + " - Bundle Data");
    
                        final Set keys = bundle.keySet();
                        final Iterator it = keys.iterator();
    
                        while (it.hasNext()) {
                            final String key = it.next();
                            Log.d("TAG", "Key: " + key + " = " + bundle.get(key));
                        }
    
                    }
    
                    if (data.hasExtra("availableVoices")) {
                        containerVEArray.get(requestCode).setVoices(data.getStringArrayListExtra("availableVoices"));
                    } else {
                        containerVEArray.get(requestCode).setVoices(new ArrayList());
                    }
                }
    
                if (requestCount == containerVEArray.size()) {
    
                    for (int i = 0; i < containerVEArray.size(); i++) {
    
                        Log.v("TAG", "cve: " + containerVEArray.get(i).getLabel() + " - "
                                + containerVEArray.get(i).getVoices().size() + " - " + containerVEArray.get(i).getVoices().toString());
                    }
                }
    
            } catch (final IndexOutOfBoundsException e) {
                Log.e("TAG", "IndexOutOfBoundsException");
                e.printStackTrace();
            } catch (final NullPointerException e) {
                Log.e("TAG", "NullPointerException");
                e.printStackTrace();
            } catch (final Exception e) {
                Log.e("TAG", "Exception");
                e.printStackTrace();
            }
        }
    

    Hope that helps.

    Edit

    Further to your comment, these 'voices' are in actual fact the languages, in the sense that they return a representative Locale in their structure. Be aware though, the Locale is in a different format to the System Locale, which is really annoying and needs to be sorted in a future Android update.

    Take a look at my answer here regarding the pitfalls with using tts.setLanguage(Locale). The question also deals with creating a Locale - Locale loc = new Locale(String).

    You can use a loop for the ArrayList of available languages to try and construct a Locale from each, for each Engine.

    Hope that helps.

    0 讨论(0)
提交回复
热议问题