在没有按钮的情况下开始活动时,将文本转换为语音

时间:2012-07-27 13:00:25

标签: java android text-to-speech

我在我的应用程序中使用文本到语音,我已经能够让它在我的所有按钮上工作正常。但是,当我尝试在我的启动活动中使用文本到语音时,它会崩溃应用程序。这是一个nullpointer异常,所以我知道我只是错误编码。澄清我想要它做什么。我希望它在启动活动期间进行讨论。当splash活动休眠时,我希望它再次通话告诉用户它已经完成加载。我已经为我的启动活动包含了java。

public class mainj extends Activity implements OnInitListener {

    private TextToSpeech myTTS;
    // status check code
    private int MY_DATA_CHECK_CODE = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.loadscreen);
        Thread logoTimer = new Thread() {
            public void run() {
                try {
                    try {
                        sleep(5000);
                        speakWords("loading");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    Intent menuIntent = new Intent("android.intent.action.MENU");
                    startActivity(menuIntent);

                    Intent checkTTSIntent = new Intent();
                    checkTTSIntent
                            .setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
                    startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
                }

                finally {
                    finish();
                }
            }

        };
        logoTimer.start();
    }

    // speak the user text
    private void speakWords(String speech) {

        // speak straight away
        myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
    }

    // act on result of TTS data check
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == MY_DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                // the user has the necessary data - create the TTS
                myTTS = new TextToSpeech(this, this);
            } else {
                // no data - install it now
                Intent installTTSIntent = new Intent();
                installTTSIntent
                        .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(installTTSIntent);
            }
        }
    }

    // setup TTS
    public void onInit(int initStatus) {

        // check for successful instantiation
        if (initStatus == TextToSpeech.SUCCESS) {
            if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE)
                myTTS.setLanguage(Locale.US);
        } else if (initStatus == TextToSpeech.ERROR) {
            Toast.makeText(this, "Sorry! Text To Speech failed...",
                    Toast.LENGTH_LONG).show();
        }
    }

}

3 个答案:

答案 0 :(得分:1)

在你睡觉之后你的线程开始时你正在调用speakWords。调用myTTS.speak。在那时查看你的代码,myTTS似乎没有被初始化并且为null因此将与NPE崩溃。

此代码应该阻止NPE,但是如果TTS引擎的初始化花费的时间太长,那么你就不会说它正在加载。此外,我猜测5秒(这是一个非常长的时间顺便说一句)睡眠是允许它初始化?

public class mainj extends Activity implements OnInitListener {

private TextToSpeech myTTS;
// status check code
private int MY_DATA_CHECK_CODE = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.loadscreen);
    Intent checkTTSIntent = new Intent();
    checkTTSIntent
         .setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
    Thread logoTimer = new Thread() {
        public void run() {
            try {
                try {
                    sleep(5000);
                    speakWords("loading");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                Intent menuIntent = new Intent("android.intent.action.MENU");
                startActivity(menuIntent);

            }

            finally {
                finish();
            }
        }

    };
    logoTimer.start();
}

// speak the user text
private void speakWords(String speech) {

    // speak straight away
   if(myTTS != null)
   {
        myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
   }
}

// act on result of TTS data check
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == MY_DATA_CHECK_CODE) {
        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
            // the user has the necessary data - create the TTS
            myTTS = new TextToSpeech(this, this);
        } else {
            // no data - install it now
            Intent installTTSIntent = new Intent();
            installTTSIntent
                    .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
            startActivity(installTTSIntent);
        }
    }
}

// setup TTS
public void onInit(int initStatus) {

    // check for successful instantiation
    if (initStatus == TextToSpeech.SUCCESS) {
        if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE)
            myTTS.setLanguage(Locale.US);
    } else if (initStatus == TextToSpeech.ERROR) {
        Toast.makeText(this, "Sorry! Text To Speech failed...",
                Toast.LENGTH_LONG).show();
    }
}

}

答案 1 :(得分:1)

在加载TTS引擎后,你最好称之为加载小片段,这样你就可以把话语放在OnActivityResult()中。

在你的代码中,当你打电话说话时,你实际上无法判断myTTS是否已被初始化。试试这种方式:

                Intent menuIntent = new Intent("android.intent.action.MENU");
                startActivity(menuIntent);

                Intent checkTTSIntent = new Intent();
                checkTTSIntent
                        .setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
                startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);

      try {
                    sleep(5000);
                    speakWords("loading");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

答案 2 :(得分:1)

您的方法有两个问题。

首先,您的应用在尝试发言之前需要等待init()。 其次,当语音库不可用时,您的应用需要处理。

使用this classthis one来帮助TextToSpeech初始化。它实际上有点复杂,使用TextToSpeech.Engine.ACTION_CHECK_TTS_DATA实际上并不是最好的方法。