非活动类/ View Adapter类中的TextToSpeech说话失败:未绑定到TTS引擎

时间:2017-01-11 07:16:12

标签: android adapter actionlistener text-to-speech google-text-to-speech

我已经使用Tabbed-Fragments中的RecyclerView为我的应用开发了一个模块。

方案

使用RecyclerView在每个片段中显示多个动态加载的图像。当用户点击任何图像时,系统会使用TextToSpeech说出一些有关它的信息。

当前代码

我使用RecyclerView的适配器类成功地将图像加载到视图中。这是代码:

import android.speech.tts.TextToSpeech;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private ArrayList<CreateList> galleryList;
private Context context;
TextToSpeech tts;

public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
    this.galleryList = galleryList;
    this.context = context;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
.....
}

@Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
.....
.....
viewHolder.img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        .....
        .....
        tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {

                    @Override
                    public void onInit(int status) {
                        // TODO Auto-generated method stub
                        if(status !=TextToSpeech.ERROR){
                            tts.setLanguage(Locale.UK);
                        }
                    }
                });
        tts.setPitch(pitch);
        tts.setSpeechRate(speechRate);
        tts.speak(StringToSpeak, TextToSpeech.QUEUE_FLUSH, null);
}

@Override
public int getItemCount() {
    return galleryList.size();
}
.....
.....
}

正如您所看到的,我在viewHolder上添加了OnClickListener,它使用onInitListener初始化TTS对象并说出信息。但每当我点击片段中的任何图像/视图/项目时,它都不会说出任何内容。在LogCat中没有崩溃,没有异常,我得到的是跟随其他消息的消息:

I/TextToSpeech: Sucessfully bound to com.google.android.tts
W/TextToSpeech: speak failed: not bound to TTS engine

我尝试调试应用程序并发现在初始化TTS对象时它在此行返回engine=Null

tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {
....});

在扩展Activity的其他类中,代码和TTS完全正常工作,但在我的Adapter / Non-Activity类中,它不能启动TTS,因为它无法绑定到TTS引擎。我尝试使用以下函数在我的适配器类中实现接口implements TextToSpeech.OnInitListener

@Override
public void onInit(int status) {

    if (status == TextToSpeech.SUCCESS) {
        tts.setLanguage(Locale.UK);
    }
}

但没有结果:(我还尝试创建一个扩展Activity的抽象类,在OnCreate()中实现TTS并包含我尝试在我的适配器中调用的自定义函数SpeakMessage()上课但失败。我试图找出问题及其解决方案需要几个小时,深入研究StackOverFlow和其他网站上的每个TTS相关问题,但无法找到任何问题。我的问题的解决方案。请帮助我找出问题及其正确的解决方案。非常感谢。另外一件事,在视图的同一动作监听器中,使用MediaPlayer播放录制的音频消息非常完美。唯一的问题是说出字符串消息使用TTS。

2 个答案:

答案 0 :(得分:3)

我已成功实施文字转语音

以下是我的代码

我为&lt; 20 api实现了两个方法,一个用于&gt; 21api

@SuppressWarnings("deprecation")
private void ttsUnder20(String text) {
    HashMap<String, String> map = new HashMap<>();
    map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
    tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(String text) {
    String utteranceId = this.hashCode() + "";
    Bundle params = new Bundle();
    params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
   tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, utteranceId);
}

这是调用此方法的方法。

 private void playNextChunk(String text) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ttsGreater21(text);
    } else {
        ttsUnder20(text);
    }}

从onInit方法调用playChunk方法

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void onInit(int status) {

    if (status == TextToSpeech.SUCCESS) {
       playNextChunk(String text)
      }
   }

如果你的字符串大于4000,你需要以块的形式播放它,另外一个建议的文本到语音一次可以说4000个字符。为此你需要实现这个监听器tts.setOnUtteranceProgressListener

答案 1 :(得分:1)

尝试使用此代码,我已在适配器中添加了代码。

public class MyAdapter extends  
    RecyclerView.Adapter<MyAdapter.ViewHolder>{
    private ArrayList<CreateList> galleryList;
    private Context context;
    TextToSpeech tts;
    public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
    this.galleryList = galleryList;
    this.context = context;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
.....
}

@Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
.....
.....
viewHolder.img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        .....
        .....
        tts=new TextToSpeech(context, new TextToSpeech.OnInitListener() {

                    @Override
                    public void onInit(int status) {
                        // TODO Auto-generated method stub
                        if(status =TextToSpeech.SUCCESS){
                            tts.setLanguage(Locale.UK);
                            playNextChunk(StringToSpeak);
                        }
                    }
                });

}
    private void playNextChunk(String text) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ttsGreater21(text);
        } else {
            ttsUnder20(text);
        }}
    @SuppressWarnings("deprecation")
    private void ttsUnder20(String text) {
        HashMap<String, String> map = new HashMap<>();
        map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
        tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
    }
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void ttsGreater21(String text) {
        String utteranceId = this.hashCode() + "";
        Bundle params = new Bundle();
        params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
        tts.speak(text, TextToSpeech.QUEUE_FLUSH, params, utteranceId);
    }
    @Override
public int getItemCount() {
    return galleryList.size();
}
.....
.....
}