Как правильно использовать TextToSpeech в классе Activity? - PullRequest
0 голосов
/ 11 июля 2019

Мне нужна помощь с Android Studio. Я пытаюсь разработать простое Android-задание, которое должно говорить, слушать, а затем отвечать на вопрос пользователя. Перво-наперво, я пытаюсь заставить Activity просто произносить общую фразу. Моя проблема в том, что после инициализации TextToSpeech ничего не произносит, если инструкция написана вне слушателя Button. Некоторый код должен прояснить ситуацию:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView imgView = findViewById(R.id.emote);
        Button helloBtn = findViewById(R.id.sayBtn);

        EmoteController emoteController = EmoteController.getInstance(MainActivity.this, imgView);
        emoteController.setEmote(Emote.DOUBTFUL);

        tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int i) {
                if(i != TextToSpeech.ERROR){
                    tts.setLanguage(Locale.ENGLISH);
                    /*THIS SPEAK DOES WORK WHEN TEXTTOSPEECH VARIABLE IS INITIALIZED!*/
                    tts.speak("Initialized!", TextToSpeech.QUEUE_FLUSH, null, null);
                }
                else{
                    Toast.makeText(getApplicationContext(), "Failed to initialize TextToSpeech", Toast.LENGTH_SHORT).show();
                }
            }
        });

        helloBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                /*THIS SPEAK DOES IF WORK IF BUTTON IS CLICKED!*/
                tts.speak("Speech from Button!", TextToSpeech.QUEUE_ADD, null, null);
            }
        });

        /*-->THIS SPEAK DOES NOT WORK!<--*/
        tts.speak("Speech from on create!", TextToSpeech.QUEUE_ADD, null, null);
    }

Как видите, в предоставленном коде я использую метод speak 3 раза: один в tts инициализации, другой в слушателе Button и последний в onCreate(Bundle) методе. Первые два работают хорошо, последний не говорит вообще. Моя цель здесь - общаться с Activity без кнопок или чего-либо еще, так как Activity это просто ImageView. После запуска приложения оно должно задать вопрос, дождаться ответа и затем обработать ответ. Есть идеи, почему работают только первые два speak() метода, а не третий? Я не думаю, что это имеет значение, но для полноты я позволю вам, ребята, увидеть метод onResume:

@Override
    public void onResume() {
        super.onResume();
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
    }

Надеюсь, я был чист, Большое спасибо

1 Ответ

1 голос
/ 11 июля 2019

Ключевое слово здесь "асинхронный"

Инициализация нового экземпляра TextToSpeech не заканчивается сразу после этой строки, потому что это асинхронный процесс

tts = new TextToSpeech(..)

Всякий раз, когда вы видите метод, которыйв качестве параметра требуется xxxListener или xxxCallback, это должен быть асинхронный метод, подобный этому.Работа, которую выполняет этот метод, будет завершена в другой момент в будущем, а не «сейчас».

Это означает, что сразу после этой строки tts еще не был экземпляром TextToSpeech, поэтому этот вызов не будет работать

/*-->THIS SPEAK DOES NOT WORK!<--*/
tts.speak("Speech from on create!", TextToSpeech.QUEUE_ADD, null, null);

Два других вызова работали, потому что они будут вызваны в будущем.

Первый вызывается в методе обратного вызова onInit () объекта Listener, когда экземпляр фактически инициализируется.

Последний вызывается при нажатии кнопки, достаточно долго, чтобы быть уверенным, что все инициализировано.

...