Java 无法在Android中执行文本到语音转换

Java 无法在Android中执行文本到语音转换,java,android,text-to-speech,Java,Android,Text To Speech,当我设置tts.speak时,使用s字符串变量,它工作得非常好。但是,当我使用随函数调用传入的文本时,它不起作用。两个字符串变量完全相同 private void speek(final String text){ tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if

当我设置
tts.speak
时,使用
s
字符串变量,它工作得非常好。但是,当我使用随函数调用传入的文本时,它不起作用。两个字符串变量完全相同

private void speek(final String text){
    tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if(status == TextToSpeech.SUCCESS){
                int isTTs = tts.setLanguage(Locale.ENGLISH);
                if(isTTs == TextToSpeech.LANG_MISSING_DATA || isTTs == TextToSpeech.LANG_NOT_SUPPORTED){
                    System.out.println("-----------------------------       ++   not working    " + isTTs);
                    System.out.println("-----------------------------       ++   " + TextToSpeech.LANG_MISSING_DATA + "     " + TextToSpeech.LANG_NOT_SUPPORTED);
                }else{
                    System.out.println("-----------------------------       ++   working yay    " + text);
                    tts.setPitch(0.9f);
                    tts.setSpeechRate(0.8f);
                    // if i use the variable s it works
                    String t = "Chapter 1 ...";
                    tts.speak(t, TextToSpeech.QUEUE_ADD, null);
                    // howevet this does not
                    tts.speak(text, TextToSpeech.QUEUE_ADD, null);
                }
            }
        }
    });

}

TextToSpeech tts;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_read_novel);
    // call async task
    new getPage().execute(b.getString("link"));

}


private class getPage extends AsyncTask<String, String, String> {
    @Override
    protected String doInBackground(String... urls) {}

    @Override
    protected void onPostExecute(String result) {
        // call speak function and pass string to be spoken
        speek(result);
    }
}
private void speek(最终字符串文本){
tts=new TextToSpeech(这是new TextToSpeech.OnInitListener(){
@凌驾
公共无效onInit(int状态){
if(status==TextToSpeech.SUCCESS){
int-isTTs=tts.setLanguage(Locale.ENGLISH);
如果(isTTs==TextToSpeech.LANG_缺少数据| | isTTs==TextToSpeech.LANG_不受支持){
System.out.println(“------------------------------++不工作”+isTTs);
System.out.println(“-------------------------------------++”+TextToSpeech.LANG\u缺少数据+”+TextToSpeech.LANG\u不受支持);
}否则{
System.out.println(“------------------------------++working yay”+text);
tts.设定螺距(0.9f);
tts.设定转速(0.8f);
//如果我使用变量s,它就会工作
字符串t=“第1章…”;
tts.speak(t,TextToSpeech.QUEUE\u ADD,null);
//然而,这并不重要
tts.speak(text,TextToSpeech.QUEUE\u ADD,null);
}
}
}
});
}
texttospeechtts;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u read\u novel);
//调用异步任务
新建getPage().execute(b.getString(“链接”);
}
私有类getPage扩展了异步任务{
@凌驾
受保护的字符串doInBackground(字符串…URL){}
@凌驾
受保护的void onPostExecute(字符串结果){
//调用speak函数并传递要说出的字符串
斯佩克(结果);
}
}

如果没有日志或函数调用,我们无法真正找出问题所在

我的第一个猜测是,
text
可能为null(如果在日志中没有看到NPE,则为空),从而触发
speak
方法中的异常或生成空白语音。添加一个空检查和一个空检查,查看调用是否具有您的
speek
函数的正确签名

在这种情况下,
onPostExecute
中的参数可能为空


您可能还需要检查是否存在任何其他限制。

首先,您可以在调用
speak()
方法检查传递给该方法的值之前,尝试打印
文本

我们不知道您的
doInBackground()
方法的内容,但可能您在这里传递了错误的值?在
doInBackground()
方法中,您应该返回将传递给
onPostExecute()
的值

doInBackground
中的
url
是Java varargs机制,因此
url[0]
是传递给
execute()
的第一个参数

执行时:

new getPage().execute("aaa", "bbb", "ccc");
doInBackground
中:

  • URL[0]
    =>
    “aaa”
  • url[1]
    =>
    “bbb”
  • URL[2]
    =>
    “ccc”
您可以尝试返回第一个参数(因此
URL[0]
):
问题是,可以传递给文本到语音引擎的最大字符大小约为4000个,如果字符串包含的字符超过4000个,则无法工作

// this will not work 
tts.speak(text, TextToSpeech.QUEUE_ADD, null);
为了让它正常工作,添加一个setOnPatternanceProgressListener,并使用onDone()在字符串中循环

//工作代码
整数字符计数=3000;
int start=0;
int end=字符计数;
HashMap=newHashMap();
map.put(TextToSpeech.Engine.KEY_-PARAM_-speak_-ID,“UniqueID”);
tts.speak(text.substring(开始、结束)、TextToSpeech.QUEUE\u ADD、map);
setOnPatternanceProgressListener(新的话语进程Listener(){
@凌驾
public void onStart(字符串s){}
@凌驾
公共无效onDone(字符串s){
开始=结束;
end+=字符计数;
end=text.indexOf(“,end”);
如果(结束>=text.length()| |结束==-1){
end=text.length();
}如果(开始>=text.length()){
System.out.println(“文本结尾”);
}否则{
speek();
}
}
@凌驾
public void onError(字符串s){}
});

只需使用日志语句检查变量的执行顺序和内容是否符合预期。显示
doInBackground()
b.getString()
的代码。
// this will not work 
tts.speak(text, TextToSpeech.QUEUE_ADD, null);
// working code
int char_count = 3000;
int start = 0;
int end = char_count;
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "UniqueID");
tts.speak(text.substring(start, end), TextToSpeech.QUEUE_ADD, map);

tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                        @Override
                        public void onStart(String s) {}

                        @Override
                        public void onDone(String s) {
                            start = end;
                            end+= char_count;
                            end = text.indexOf(" ", end);

                            if(end >= text.length() || end == -1){
                                end = text.length();
                            }if(start >= text.length()){
                                System.out.println("end of text");
                            }else {
                                speek();
                            }

                        }

                        @Override
                        public void onError(String s) {}
                    });