我在我的应用程序中使用此类文本进行演讲(代码编辑以显示前景和确切要求。)。我将在我的观点和展示中展示一些内容。如果我们点击按钮,我想通过使用这个texttospeech引擎播放声音...但是对于第一次它没有播放声音。从下一次点击开始,TEXTTOSPEECH引擎运行良好
我想知道如何克服这个问题......
public class LearnActivity extends Activity implements OnClickListener, OnInitListener {
AudioManager audioManager;
float volume;
TextToSpeech textToSpeech;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_learn);
textToSpeech = new TextToSpeech(this, this);
textToSpeech.setLanguage(Locale.US);
textToSpeech.setSpeechRate(0.95f);
method();
}
public void method(){
bt.setonClickListener(new onClickListener(){
public void onClick(View v){
playSound(datasource.getItemSound);
}
});
}
public void playSound(String sound){
textToSpeech.speak(sound,TextToSpeech.QUEUE_FLUSH,null);
}
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
}
注意: - 这也符合我的要求,如何直接播放TEXTTOSPEECH引擎的声音,而不使用任何onClicks等...,因为我也想用Android播放启动声音仅限文字转语音引擎......
答案 0 :(得分:1)
那是因为你在引擎准备好之前点击了按钮。
您必须检查TTS引擎是否已在onInit()
方法上成功初始化,并相应地启用/禁用播放按钮。
假设代码中的bt
是View
某种setEnabled(boolean)
方法:
@Override
public void onInit(int status) {
bt.setEnabled(status == TextToSpeech.SUCCESS);
}
您始终必须假设引擎尚未初始化,因此默认情况下会禁用播放按钮。
答案 1 :(得分:0)
我使用RXJava制作了一个解决此问题的类。如果要使用语音方法时TTS引擎尚未准备就绪,它将等待引擎准备就绪,然后说出给定的字符串。
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.util.Pair;
import android.widget.Toast;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
public class Pronunciation {
private TextToSpeech textToSpeech;
private int languageResult;
private boolean noError;
private final String errorMessage="Something went wrong with your text to speech engine";
private PublishSubject<Boolean> engineIsReady=PublishSubject.create();
private PublishSubject<Pair<String,Integer>> speakObservable=PublishSubject.create();
private CompositeDisposable compositeDisposable=new CompositeDisposable();
public Pronunciation(Context context) {
textToSpeech=new TextToSpeech(context, status -> {
if (status!=TextToSpeech.ERROR){
languageResult= textToSpeech.setLanguage(Locale.ENGLISH);
engineIsReady.onNext(true);
} else {
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}
});
if (languageResult==TextToSpeech.LANG_MISSING_DATA||languageResult== TextToSpeech.LANG_NOT_SUPPORTED){
noError =false;
Toast.makeText(context,errorMessage
,Toast.LENGTH_LONG).show();
}else { noError =true;}
compositeDisposable.add( Observable.combineLatest(speakObservable, engineIsReady,
(stringIntegerPair, aBoolean) -> stringIntegerPair)
.subscribeOn(Schedulers.io())
.subscribe(pair->{
if (noError)
textToSpeech.speak( (pair).first
,(pair).second,null,null);
}));
}
public void speak(String text,int queueMode){
speakObservable.onNext(new Pair<>(text,queueMode));
}
public void stop(){
if (textToSpeech!=null){
textToSpeech.stop();
textToSpeech.shutdown();
}
compositeDisposable.clear();
}
}
首先在您的Gradle文件中添加RxJava依赖项
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
然后在活动或片段的onCreate方法中创建此类的实例。现在,您可以将字符串和队列模式传递给语音方法。
pronunciation.speak("Hi", TextToSpeech.QUEUE_FLUSH));
不要忘记在onDestroy或onDetach中调用stop方法,以避免内存泄漏
@Override
public void onDetach() {
super.onDetach();
pronunciation.stop();
}
答案 2 :(得分:-1)
你应该写你的程序......
public class MainActivity extends Activity implements TextToSpeech.OnInitListener, OnUtteranceCompletedListener {
TextToSpeech t1;
protected void onCreate(Bundle savedInstanceState) {
t1=new TextToSpeech(MainActivity.this, MainActivity.this);
}/////on creat
protected void onDestroy() {
if(t1!=null) {
t1.stop();
t1.shutdown();
t1=null;
}
super.onDestroy();
}
public void onInit(int arg0) {
t1.setOnUtteranceCompletedListener(this);
}
}//mainactivity
单击按钮或在任何想要说文本的位置添加此命令。
t1.speak(text, TextToSpeech.QUEUE_FLUSH, null);
答案 3 :(得分:-2)
只需延迟5秒钟就可以在没有任何按钮的情况下工作点击
public class Final_Text_To_Speech_Activity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private TextToSpeech tts; // For Text to Speech
CardView ScanProduct, SearchProduct;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this);
init();
// Just Put Delay For 5 Second And It's Working without any button Click
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
SpeakOutOnce("Welcome to Text To Speech Application");
}
}, 5000);
}
@Override
protected void onResume() {
super.onResume();
}
public void init() {
ScanProduct = (CardView) findViewById(R.id.scan_product);
SearchProduct = (CardView) findViewById(R.id.search_product);
// Search On Button Click
ScanProduct.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
speakOut("You have Just pressed Scan Option");
}
});
SearchProduct.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
speakOut("You have Just pressed Search Option ");
}
});
}
@Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
@Override
public void onInit(int status) {
int result = tts.setLanguage(Locale.US);
if (status == TextToSpeech.SUCCESS) {
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
} else {
speakOut("");
}
} else if (status == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...",
Toast.LENGTH_LONG).show();
}
}
private void speakOut(String text) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
private void SpeakOutOnce(String text) {
if (tts != null) {
tts.setPitch(1.0f); //Normal Pitch
tts.setSpeechRate(0.7f); // 1.0 is Normal speech Rate
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
}