Как переключаться между языками TTS нажатием кнопки в Android

Я делаю приложение-переводчик, которое переводит с английского на итальянский и с итальянского на английский. Когда вводится английское слово, оно переводится, и TTS произносит перевод с родным акцентом. Итак, я ввожу «Сыр», и это переводится на итальянский, поэтому «Формаджо» отображается и произносится с итальянским акцентом.

Моя проблема в том, что механизм TTS настроен с локалью при инициализации действия, и я изо всех сил пытаюсь переключиться между локальными языками во время выполнения. Если я ввожу английское слово, оно использовало итальянскую локаль по желанию, но если я затем ввожу итальянское слово, оно будет продолжать использовать первый использованный язык локали, итальянский, а не британский. Это работает и наоборот: при вводе итальянского слова сначала используется британский язык, но он не переключается.

Можно ли настроить язык объектов TTS, готовый к немедленному использованию, нажав кнопку?

Вот мой упрощенный код:

public class TranslateActivity extends Activity implements OnInitListener {

        Locale locLanguage, locLanguage2;
        private TextToSpeech tts;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            super.onCreate(savedInstanceState);
            setContentView(R.layout.translate);


            locLanguage = new Locale("gb_GB");
            locLanguage2 = new Locale("it_IT");

            engtoita = (LinearLayout) findViewById(R.id.engtoitaButton);
            itatoeng = (LinearLayout) findViewById(R.id.itatoengButton);



    engtoita.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    tts.setLanguage(locLanguage2);

                    class bgStuff extends AsyncTask<Void, Void, Void> {

                        @Override
                        protected Void doInBackground(Void... params) {

                            try {
                                phraseEntered = et.getText().toString();  
                                translatedText = translate(phraseEntered);

                                if(translatedText!="")
                                {
                                speakOut(translatedText);
                                }
                            } catch (Exception e) {

                                e.printStackTrace();
                                z = "Sorry, there was an error.";
                                translatedText = z; 
                            }
                            return null;
                        }
                    }

                }

            });


    itatoeng.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    tts.setLanguage(locLanguage1);

                    class bgStuff extends AsyncTask<Void, Void, Void> {

                        @Override
                        protected Void doInBackground(Void... params) {

                            try {
                                phraseEntered = et.getText().toString();  
                                translatedText = translate(phraseEntered);

                                if(translatedText!="")
                                {
                                speakOut(translatedText);
                                }
                                } catch (Exception e) {

                                    e.printStackTrace();
                                    z = "Sorry, there was an error.";
                                    translatedText = z; 
                                }


                                return null;
                            }
                        }
                    }

                });
            }

    @Override
        public void onInit(int status) {
            // TODO Auto-generated method stub
            if (status == TextToSpeech.SUCCESS) {


                int result = tts.setLanguage(locLanguage);

                if (result == TextToSpeech.LANG_MISSING_DATA
                        || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Log.e("TTS", "This Language is not supported");
                } else {

                }

            } else {
                Log.e("TTS", "Initilization Failed!");
            }
        }

        private void speakOut(String text) {

            tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
        }

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == MY_DATA_CHECK_CODE) {
                if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    tts = new TextToSpeech(this, this);
                } else {
                    Intent installTTSIntent = new Intent();
                    installTTSIntent
                            .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    ArrayList<String> languages = new ArrayList<String>();
                    languages.add("ita"); 
                    installTTSIntent.putStringArrayListExtra(
                            TextToSpeech.Engine.EXTRA_CHECK_VOICE_DATA_FOR,
                            languages);
                    startActivity(installTTSIntent);
                }
            }
        }

    }

Я надеюсь, что этого достаточно для кода, чтобы продемонстрировать, чего я пытаюсь достичь. Я посмотрел, как установить язык объекта TTS на лету, но не вижу примеров, где это требуется.


person deucalion0    schedule 21.07.2014    source источник


Ответы (1)


Лучше поздно, чем никогда...

Ваш onActivityResult слишком сложен.
Попробуйте использовать этот вариант:

@Override
protected final void onActivityResult
(
    final int requestCode, final int resultCode, final Intent data
)
{
    // If TTS Voice data doesn't exist, download it.
    if (requestCode == TTS_DATA_CHECK)
    {
        if (resultCode != Engine.CHECK_VOICE_DATA_PASS)
        {
            // Voice data doesn't exist
            final Intent tnt = new Intent(Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(tnt);
        }
    }
}

(Вам нужно будет определить эту константу)

private static final int TTS_DATA_CHECK = 1;

Чтобы установить другой язык:

// Change language
tts.setLanguage(new Locale("en")); // or "it"
// Say it
tts.speak("All you need is Love!", TextToSpeech.QUEUE_FLUSH, null);

Make sure your device isn't set to "Always use default settings", иначе изменение языка не будет применено.

Последнее замечание: как вы уже догадались, мой объект TTS называется tts.

person Phantômaxx    schedule 05.08.2014
comment
Большое спасибо! Поздно намного лучше, чем никогда! Ваш код сработал! Оценил! - person deucalion0; 06.08.2014
comment
эй, у меня была такая же проблема, и этот код отлично работает внутри активности, но не работает внутри фрагмента. - person B L Λ C K; 04.08.2020
comment
@BLΛCK Как это возможно?! Может быть, дело в видимости? - person Phantômaxx; 21.08.2020