在Android Studio中初始化TextToSpeech类

时间:2017-05-11 22:25:16

标签: java android initialization text-to-speech

我正在努力制作我的第一个Android应用程序,而且我无法让文本转语音起作用。

应用程序的要点:用户选择他们想要设置闹钟的时间(使用TimePicker),然后应用程序计算剩余的时间,不断更新剩余的时间。

我希望使用文本到语音引擎以5分钟的间隔口头更新用户他们离开的时间。

所有内容都编译并运行没有错误,但文本到语音只是没有做任何事情。我已经找了几天了解如何在java中正确初始化TextToSpeech类,但我发现的所有内容似乎都是根据具体情况以不同方式初始化它。

在尝试了多个不同的实现之后,所有实现都具有相同的结果,我决定只创建一个单独的内部类来进行编辑并更轻松地尝试新事物,我可以创建一个Voice类并在其上调用方法。

我只用Java编写了几个月的代码,这是我的第一个Android应用程序,所以我很难自己排序。

下面是我用来初始化TextToSpeech类的单独(内部/嵌套)类:

    private class Voice implements TextToSpeech.OnInitListener {
    Context context = getApplicationContext();
    TextToSpeech tts = new TextToSpeech(context, this);

    public void onInit(int initStatus) {
        if (initStatus == TextToSpeech.SUCCESS) {
            tts.setLanguage(Locale.US);
        }
    }

    private void say(String announcement) {
        tts.speak(announcement, TextToSpeech.QUEUE_FLUSH, null);
    }
}

以下是活动中的其余代码(我使用单独的活动来显示倒计时)

import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.os.*;
import android.widget.*;
import java.util.*;
import java.lang.*;


public class TimerActivity extends AppCompatActivity{

private int alarmHour = MainActivity.alarmHour;
private int alarmMinute = MainActivity.alarmMinute;
private Calendar alarmTime;
private Calendar currentTime;
private TextView timerText;
private TextView lateText;
private int hoursLeft;
private int minutesLeft;
private long difference;
private long calculatedMinutes;
private boolean late = false;
private String lateMessageString = "LATE!";
private String timeRemainingString = "remaining";
private Handler handler = new Handler();
private TextToSpeech tts;
private double pitch = 1;
private double speed = 1;
private int MY_DATA_CHECK_CODE = 0;
private Voice voice;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_timer);
    voice = new Voice();
    voice.say("This is some bullshit.");
    initializeTimer();
}

private void initializeTimer () {
    voice.say("Yes, hello. Is it me you're looking for?");
    timerText = (TextView) findViewById(R.id.timerText);
    lateText = (TextView) findViewById(R.id.lateText);
    setAlarm();
    calculateTimeLeft();
    String timerString = getTimerString();
    timerText.setText(timerString);
    if (late) {
        lateText.setText(lateMessageString);
    }
    else {
        lateText.setText(timeRemainingString);
    }

    Timer timer = new Timer();
    timer.schedule(new UpdateTimer(),100,60000);
}



private class UpdateTimer extends TimerTask {
    public void run() {
        handler.post(new Runnable() {
            public void run() {
                calculateTimeLeft();
                String timerString = getTimerString();
                timerText.setText(timerString);
                if (late) {
                    lateText.setText(lateMessageString);
                }
                else {
                    lateText.setText(timeRemainingString);
                }
            }

        });
    }
}


private void setAlarm() {
    alarmTime = Calendar.getInstance();
    currentTime = Calendar.getInstance();
    alarmTime.setTimeInMillis(System.currentTimeMillis());
    alarmTime.set(Calendar.HOUR_OF_DAY, alarmHour);
    alarmTime.set(Calendar.MINUTE, alarmMinute);
    // If alarm is set for the past, then set the alarm for the next day at the specified time
    if (alarmTime.getTimeInMillis() - System.currentTimeMillis() < 0) {
        alarmTime.set(Calendar.DAY_OF_YEAR, alarmTime.get(Calendar.DAY_OF_YEAR) + 1);
    }
}

private void calculateTimeLeft() {
    currentTime.setTimeInMillis(System.currentTimeMillis());
    difference = alarmTime.getTimeInMillis() - System.currentTimeMillis();
    long seconds = difference/1000; // convert to seconds
    long calculatedHours = seconds / 3600; // Find the number of hours until alarm
    calculatedMinutes = (seconds % 3600) / 60; // Use mod to remove the number of hours, leaving only seconds since the last hour, then divide by 60 to get minutes

    hoursLeft = (int)Math.abs(calculatedHours); // Get the absolute value of the time left for the string
    minutesLeft = (int)Math.abs(calculatedMinutes); // Absolute value of the minutes for string use
}

private String getTimerString() {
    // Format the string showing the time remaining
    String timeLeftString;
    if (hoursLeft == 0) {
        timeLeftString = "";
    }
    else if (hoursLeft == 1) {
        timeLeftString = hoursLeft + "hr ";
    }
    else {
        timeLeftString = hoursLeft +"hrs ";
    }
    if (hoursLeft == 0) {
        timeLeftString += minutesLeft;
    }
    /*
    else if (minutesLeft < 10 && calculatedMinutes > 0) {
        timeLeftString += "0" + minutesLeft;
    }
    */
    else {
        timeLeftString += minutesLeft;
    }
    if (calculatedMinutes >= 0 && hoursLeft > 0) {
        timeLeftString += " mins";
    }
    else if (calculatedMinutes > 0) {
        timeLeftString += " mins";
    }
    else if (difference <= 0) {
        late = true;
    }
    return timeLeftString;
}




private class Voice implements TextToSpeech.OnInitListener {
    Context context = getApplicationContext();
    TextToSpeech tts = new TextToSpeech(context, this);

    public void onInit(int initStatus) {
        if (initStatus == TextToSpeech.SUCCESS) {
            tts.setLanguage(Locale.US);
        }
    }

    private void say(String announcement) {
        tts.speak(announcement, TextToSpeech.QUEUE_FLUSH, null);
    }
}

}

1 个答案:

答案 0 :(得分:0)

我认为你无法听到任何你想要的声音。

因为TextToSpeech类在调用构造函数后不能立即说出来。

TextToSpeech类实例在初始化时需要连接到系统TTS服务。

如果实例连接到服务成功,onInit的{​​{1}}将被激活!

因此,您可以在TextToSpeech.OnInitListener功能完成后听到声音。尝试将onInit函数移至voice.say函数。

onInit