Привет всем, я пытаюсь поместить текст в речь в свой CountDownTimer. Я хотел бы, чтобы он сказал "Осталось x секунд" после определенного количества времени. Я только начал использовать TextToSpeech, и я не совсем уверен, что я делаю.
package com.android.countdown;
import java.util.Locale;
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.speech.tts.TextToSpeech;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class countdown extends Activity implements TextToSpeech.OnInitListener{
CountDownTimer Counter1;
CountDownTimer Counter2;
CountDownTimer Counter3;
int Interval = 1;
TextToSpeech tts;
public String formatTime(long millis) {
String output = "0:00";
long seconds = millis / 1000;
long minutes = seconds / 60;
seconds = seconds % 60;
minutes = minutes % 60;
String secondsD = String.valueOf(seconds);
String minutesD = String.valueOf(minutes);
if (seconds < 10)
secondsD = "0" + seconds;
if (minutes < 10)
minutesD = "0" + minutes;
output = minutesD + " : " + secondsD;
return output;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Declare Start/Stop timer
Button btnstart = (Button)findViewById(R.id.btnstart);
Button btnstop = (Button)findViewById(R.id.btnstop);
//Text field to show time left
final TextView mCounter1TextField=(TextView)findViewById(R.id.counter1);
final TextView mCounter2TextField = (TextView)findViewById(R.id.counter2);
final TextView mCounter3TextField=(TextView)findViewById(R.id.counter3);
//Counter 1
Counter1 = new CountDownTimer(20000 , Interval) {
public void onTick(long millisUntilFinished){
mCounter1TextField.setText("Seconds left: " + formatTime(millisUntilFinished));
if (millisUntilFinished == 10000) {
instantiate();
}
}
public void onFinish() {
Counter1.start();
}
};
//Counter 2
Counter2 = new CountDownTimer(80000 , Interval) {
public void onTick(long millisUntilFinished) {
mCounter2TextField.setText("Seconds left: " + formatTime(millisUntilFinished));
}
public void onFinish() {
mCounter2TextField.setText("Finished!");
Counter2.start();
}
};
//Counter 3
Counter3 = new CountDownTimer(3000 , Interval) {
public void onTick(long millisUntilFinished) {
mCounter3TextField.setText("Seconds left: " + formatTime(millisUntilFinished));
}
public void onFinish() {
mCounter3TextField.setText("Finished!");
Counter3.start();
}
};
//Start Button
btnstart.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Counter1.start();
Counter2.start();
Counter3.start();
}
});
//Stop Button
btnstop.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Counter1.cancel();
Counter2.cancel();
Counter3.cancel();
if (tts != null) {
tts.stop();
tts.shutdown();
}
}
});
}
public void instantiate() {
tts = new TextToSpeech(this, this);
tts.setLanguage(Locale.US);
tts.speak("You have 10 seconds remaining", TextToSpeech.QUEUE_ADD, null);
}
@Override
public void onInit(int status) {
}
@Override
public void onDestroy() {
// Don't forget to shutdown!
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
}
Второй аргумент в tts = new TextToSpeech(this, this)
не реализует TextToSpeech.OnInitListener
.
У вас должен быть countdown
или другой класс TextToSpeech.OnInitListener
:
public class countdown extends Activity implements TextToSpeech.OnInitListener {
Затем реализуем onInit() в указанном классе:
void onInit(int status){
// implementation
}
И, наконец, передайте класс, который реализует OnInitListener в конструкторе TextToSpeech
:
// The second 'this' will be replaced with another class if you
// decide to use a class other than countdown to implement the interface.
tts = new TextToSpeech(this, this);
Ознакомьтесь с учебным пособием TextToSpeechActivity.java для полного рабочего примера.
ИЗМЕНИТЬ
Как упоминалось NickT, вам также нужно добавить фигурные скобки в оператор if в onTick:
if (millisUntilFinished == 10000) {
tts = new TextToSpeech(this, this);
tts.setLanguage(Locale.US);
tts.speak("You have 10 seconds remaining", TextToSpeech.QUEUE_ADD, null);
}
Иначе вы будете выполнять setLanguage
и speak
всегда, что даст вам NullPointerException
, если только millisUntilFinished == 10000
не является истинным.
http://developer.android.com/reference/android/speech/tts/TextToSpeech.OnInitListener.html
Другой подход, который не должен реализовывать TextToSpeech.OnInitListener
в вашей деятельности, то есть более чистый код (на мой взгляд):
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status){
if(status == TextToSpeech.SUCCESS) {
Log.d("myapp", "TextToSpeech enabled");
}
}
});
Если вы хотите "запросить" данные tts. Я делаю это так:
// I have this code inside onCreate(), but you can call it elsewhere.
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, 6);
// Then, in the activity add this code:
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (requestCode == 6) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status){
if(status == TextToSpeech.SUCCESS) {
Log.d("myapp", "TextToSpeech prepared");
}
}
});
}
}
}
Почти то же самое, что и TextToSpeech.isLanguageAvailable()
. Я собираюсь изменить его в будущем.