如何在Activity类中正确使用TextToSpeech?

时间:2019-07-11 14:11:15

标签: android android-activity text-to-speech

我需要有关Android Studio的帮助。 我正在尝试开发一个简单的Android活动,该活动应该说,听然后回答用户的问题。 首先,我正在尝试使Activity简单地讲一个通用短语。 我的问题是,一旦初始化,如果指令是在Button侦听器外部编写的,则TextToSpeech不会发出任何声音。 一些代码可以清除问题:

@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。 App启动后,它应该问一个问题,等待答案,然后再处理答案。 是否知道为什么只有前两个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 个答案:

答案 0 :(得分:1)

此处的关键字是“异步”

新的TextToSpeech实例的初始化在此行之后没有完成,因为它是异步过程

tts = new TextToSpeech(..)

每当您看到需要xxxListener或xxxCallback作为参数的方法时,它都必须是这样的异步方法。此方法正在做的工作将在将来的其他时间而不是“现在”完成。

这意味着在此行之后,tts尚未成为TextToSpeech的实例,因此此调用将无法工作

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

另外两个呼叫之所以起作用,是因为将来会被呼叫。

实际上是在实例初始化时,在Listener对象的onInit()回调方法中调用前者。

单击按钮时会调用后者,它足够长,可以确保所有内容都已初始化。