首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在创建View后立即使用TTS (发言失败:未绑定TTS引擎)?

如何在创建View后立即使用TTS (发言失败:未绑定TTS引擎)?
EN

Stack Overflow用户
提问于 2020-07-15 19:36:59
回答 1查看 96关注 0票数 0

在我的应用程序中,我需要在激活Activity或Fragment后立即播放TTS。意外遇到问题: TTS.speak初始化后不能立即工作。没有错误或异常,只有“运行”窗口中的"I/TextToSpeech: Sucessfully to com.google.android.tts W/TextToSpeech: speak : not bound to TTS engine“。

同样的代码,如果将TTS.speak放在Button下面,也能成功工作。

下面是代码:

代码语言:javascript
复制
package com.example.symplettsproject;

import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;

import java.util.Locale;

public class FirstFragment extends Fragment {

    TextToSpeech TTS;
    TextReadingUtil util;

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
/
         util = new TextReadingUtil(getContext());
        util.speak("Hello World!!!");   // - not works

        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

             NavHostFragment.findNavController(FirstFragment.this)
                   .navigate(R.id.action_FirstFragment_to_SecondFragment);
            }
        });

        view.findViewById(R.id.button_speak).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

               util.speak("Hello World!!!");  // - it works!!!


                }
        });




    }
}

下面是TextReadingUtil:

代码语言:javascript
复制
public class TextReadingUtil {

    private TextToSpeech TTS;



    public TextReadingUtil(Context context) {

        if (TTS != null) {

            TTS.stop();
            TTS.shutdown();
        }

        TTS = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int initStatus) {
                if (initStatus == TextToSpeech.SUCCESS) {
                    if (TTS.isLanguageAvailable(new Locale(Locale.getDefault().getLanguage()))
                            == TextToSpeech.LANG_AVAILABLE) {
                        TTS.setLanguage(new Locale(Locale.getDefault().getLanguage()));
                    } else {
                        TTS.setLanguage(Locale.US);
                    }
                    TTS.setPitch(1.3f);
                    TTS.setSpeechRate(0.7f);

                } else if (initStatus == TextToSpeech.ERROR) {

                }
            }
        });



    }

    public void speak (String string){

        TTS.speak(string, TextToSpeech.QUEUE_FLUSH, null,null);


    }



}

我尝试在使用Thread.sleep和AsyncTask类启动后进行时间延迟,以运行TTS.speak,但没有成功。如果可能的话,请帮忙。

EN

回答 1

Stack Overflow用户

发布于 2020-07-16 07:51:32

问题是你在tts还没有初始化的时候就调用了speak。

这就是为什么它在onCreateView()中不起作用,但在按钮按下时起作用(因为它是在您按下按钮时初始化的)。

tts init是在后台完成的,并且需要时间,所以您不能期望它在init调用之后的下一行工作。您必须等待OnInitListener被调用才能知道它什么时候准备好了。

有不止一种方法可以处理这个问题,但如果您想要快速修改,可以尝试以下方法:

代码语言:javascript
复制
public class TextReadingUtil {

private TextToSpeech TTS;

// add this:
private String textToSpeakOnInit; 



public TextReadingUtil(Context context) {

    if (TTS != null) {

        TTS.stop();
        TTS.shutdown();
    }

    TTS = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int initStatus) {
            if (initStatus == TextToSpeech.SUCCESS) {
                if (TTS.isLanguageAvailable(new Locale(Locale.getDefault().getLanguage()))
                        == TextToSpeech.LANG_AVAILABLE) {
                    TTS.setLanguage(new Locale(Locale.getDefault().getLanguage()));
                } else {
                    TTS.setLanguage(Locale.US);
                }
                TTS.setPitch(1.3f);
                TTS.setSpeechRate(0.7f);

                // tts initialized, so speak the temporary string if it has been set
                if (textToSpeakOnInit != null) {
                TTS.speak(textToSpeakOnInit, TextToSpeech.QUEUE_FLUSH, null,null);
                }
            } else if (initStatus == TextToSpeech.ERROR) {

            }
        }
    });



}

public void speak (String string){

    // if tts is not initialized yet, set the temporary speech string
    // that will be spoken when it is initialized.
    if (TTS == null) {
        textToSpeakOnInit = string;
    } else {
        TTS.speak(string, TextToSpeech.QUEUE_FLUSH, null,null);
    }

    


}

}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62913966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档