将 class 中的文字转语音与 activity class 分开
Call text to speech from class separate to activity class
我正在尝试创建一个 class 可以从任何 activity 调用它来读出 EditText 框中的文本。当我 运行 我目前拥有的代码时,它会播放警报声音,但随后无法播放文本到语音内容。我需要更改什么才能让文本也播放?我知道 activity 布局 XML 代码是正确的,因为 Text To Speech 代码在直接位于 activity class 中时有效。我四处寻找解决方案,但没有其他地方概述如何从线程上下文执行此操作。
我在下面包含了我的代码:
在 AircraftMain.java
View.OnClickListener speakBtnOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String toSpeak = textToSpeak.getText().toString();
TextToSpeak speak = new TextToSpeak(AircraftMain.this, toSpeak);
speak.run();
}
};
TextToSpeak.java
import android.app.Activity;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import java.util.Locale;
public class TextToSpeak implements Runnable {
private Activity activity;
private static String text;
private static TextToSpeech talk;
public TextToSpeak(Activity activity, String toSpeak) {
this.activity = activity;
text = toSpeak;
}
public void run() {
talk = new TextToSpeech(activity, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
talk.setLanguage(Locale.UK);
}
}
});
talk.addEarcon("Attention", "com.kieronmc.aircraftgps", R.raw.warning_beep);
talk.playEarcon("Attention", QUEUE_ADD,null);
talk.setLanguage(Locale.UK);
talk.speak(text, TextToSpeech.QUEUE_ADD, null);
}
}
试试这个代码,它应该可以工作:
1) 创建一个文本转语音初始化器如下:
public class TextToSpeechInitializer{
private Context context;
private static TextToSpeech talk;
private TextToSpeechIniListener callback;
private Locale locale;
public TextToSpeechInitializer(Context context , Locale locale , TextToSpeechIniListener l) {
this.context = context;
if(l != null) {
callback = l;
}
this.locale = locale;
initialize();
}
private void initialize() {
talk = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
talk.setLanguage(locale); //TODO: Check if locale is available before setting.
callback.onSucces(talk);
}else{
callback.onFailure(talk);
Log.e("TTS","TextToSpeechInitializeError");
}
}
});
}
}
2) 上面的初始化器class调用这个接口class来通知下面的activity(TTS成功或失败):
public interface TextToSpeechIniListener {
public void onSucces(TextToSpeech tts);
public void onFailure(TextToSpeech tts);
}
3) Activity
public class Demo7 extends AppCompatActivity implements TextToSpeechIniListener {
private Button b;
private TextToSpeechInitializer i;
private TextToSpeech talk;
private boolean flag = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo7);
i = new TextToSpeechInitializer(this, Locale.UK, this);
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(flag) {
talk.addEarcon("Attention", getPackageName(), R.raw.androidcalm);
talk.playEarcon("Attention", QUEUE_ADD, null);
//talk.setLanguage(Locale.UK);
talk.speak("Hello, Testing", QUEUE_ADD, null);
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if(talk != null){
talk.stop();
talk.shutdown();
}
}
@Override
public void onSucces(TextToSpeech tts) {
this.talk = tts;
flag = true;
}
@Override
public void onFailure(TextToSpeech tts) {
flag = false;
finish();
}
}
布局demo7.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/b"
android:text="speak"/>
</LinearLayout>
我正在尝试创建一个 class 可以从任何 activity 调用它来读出 EditText 框中的文本。当我 运行 我目前拥有的代码时,它会播放警报声音,但随后无法播放文本到语音内容。我需要更改什么才能让文本也播放?我知道 activity 布局 XML 代码是正确的,因为 Text To Speech 代码在直接位于 activity class 中时有效。我四处寻找解决方案,但没有其他地方概述如何从线程上下文执行此操作。
我在下面包含了我的代码:
在 AircraftMain.java
View.OnClickListener speakBtnOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String toSpeak = textToSpeak.getText().toString();
TextToSpeak speak = new TextToSpeak(AircraftMain.this, toSpeak);
speak.run();
}
};
TextToSpeak.java
import android.app.Activity;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import java.util.Locale;
public class TextToSpeak implements Runnable {
private Activity activity;
private static String text;
private static TextToSpeech talk;
public TextToSpeak(Activity activity, String toSpeak) {
this.activity = activity;
text = toSpeak;
}
public void run() {
talk = new TextToSpeech(activity, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
talk.setLanguage(Locale.UK);
}
}
});
talk.addEarcon("Attention", "com.kieronmc.aircraftgps", R.raw.warning_beep);
talk.playEarcon("Attention", QUEUE_ADD,null);
talk.setLanguage(Locale.UK);
talk.speak(text, TextToSpeech.QUEUE_ADD, null);
}
}
试试这个代码,它应该可以工作:
1) 创建一个文本转语音初始化器如下:
public class TextToSpeechInitializer{
private Context context;
private static TextToSpeech talk;
private TextToSpeechIniListener callback;
private Locale locale;
public TextToSpeechInitializer(Context context , Locale locale , TextToSpeechIniListener l) {
this.context = context;
if(l != null) {
callback = l;
}
this.locale = locale;
initialize();
}
private void initialize() {
talk = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
talk.setLanguage(locale); //TODO: Check if locale is available before setting.
callback.onSucces(talk);
}else{
callback.onFailure(talk);
Log.e("TTS","TextToSpeechInitializeError");
}
}
});
}
}
2) 上面的初始化器class调用这个接口class来通知下面的activity(TTS成功或失败):
public interface TextToSpeechIniListener {
public void onSucces(TextToSpeech tts);
public void onFailure(TextToSpeech tts);
}
3) Activity
public class Demo7 extends AppCompatActivity implements TextToSpeechIniListener {
private Button b;
private TextToSpeechInitializer i;
private TextToSpeech talk;
private boolean flag = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo7);
i = new TextToSpeechInitializer(this, Locale.UK, this);
b = (Button) findViewById(R.id.b);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(flag) {
talk.addEarcon("Attention", getPackageName(), R.raw.androidcalm);
talk.playEarcon("Attention", QUEUE_ADD, null);
//talk.setLanguage(Locale.UK);
talk.speak("Hello, Testing", QUEUE_ADD, null);
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if(talk != null){
talk.stop();
talk.shutdown();
}
}
@Override
public void onSucces(TextToSpeech tts) {
this.talk = tts;
flag = true;
}
@Override
public void onFailure(TextToSpeech tts) {
flag = false;
finish();
}
}
布局demo7.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/b"
android:text="speak"/>
</LinearLayout>