0

我在我的应用程序中使用文本到语音,我已经能够让它在我的所有按钮上正常工作。但是,当我尝试在我的启动活动中使用文本到语音时,它会使应用程序崩溃。这是一个空指针异常,所以我知道我只是编码不正确。澄清我想要它做什么。我希望它在飞溅活动中说话。当启动活动休眠时,我希望它再次交谈以告诉用户它已完成加载。我已经为我的启动活动包含了 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();
        }
    }

}
4

3 回答 3

1

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

这段代码应该可以防止 NPE,但是如果 TTS 引擎的初始化时间太长,那么你就不会让它说 Loading。另外,我猜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();
    }
}

}

于 2012-07-27T13:08:29.397 回答
1

在加载 TTS 引擎后,您最好调用您的小加载片段,因此您可以将发言放在 OnActivityResult() 中。

在您的代码中,您实际上无法判断 myTTS 在您调用 speak 时是否已初始化。试试这种方式:

                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();
                }
            }
于 2012-07-27T13:12:13.533 回答
1

你的方法有两个问题。

首先,您的应用程序需要等待init()才能尝试说话。其次,当语音库不可用时,您的应用需要处理。

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

于 2012-07-27T15:27:50.523 回答