1

我在我的应用程序中的一个课程中使用这种文本到语音(代码编辑以显示前景和确切要求。)。我将在我的视图中显示一些内容,如果我们单击按钮,我想通过使用这个 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

}

注意:- 这也符合我的要求,如何在不使用任何 onClicks 等的情况下直接从 TEXTTOSPEECH 引擎播放声音......因为我也想只使用 Android 的 Text-To-Speech 引擎播放启动声音......

4

4 回答 4

3

那是因为您在引擎准备好之前单击了按钮。

您必须检查 TTS 引擎是否已成功初始化您的onInit()方法并相应地启用/禁用播放按钮。

假设在您的代码中有bt某种方法:ViewsetEnabled(boolean)

@Override
public void onInit(int status) {
    bt.setEnabled(status == TextToSpeech.SUCCESS);
}

您始终必须假设引擎尚未初始化,因此默认情况下禁用播放按钮。

于 2013-06-04T14:07:45.507 回答
0

我使用 RXJava 制作了一个解决这个问题的类。如果您想使用 speak 方法时您的 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'

然后在你的activity或者fragment的onCreate方法中创建这个类的一个实例。现在你可以将字符串和队列模式传递给speak方法。

pronunciation.speak("Hi", TextToSpeech.QUEUE_FLUSH));

不要忘记在 onDestroy 或 onDetach 中调用 stop 方法以避免内存泄漏

@Override
public void onDetach() {
    super.onDetach();
    pronunciation.stop();
}
于 2020-09-19T05:51:12.730 回答
-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);
于 2017-01-04T09:25:42.187 回答
-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);
    }
}

}

于 2017-10-31T07:42:59.467 回答