Java 在活动开始时不使用按钮播放文字到语音

Java 在活动开始时不使用按钮播放文字到语音,java,android,text-to-speech,Java,Android,Text To Speech,我在我的应用程序中使用文本到语音,我已经能够让它在我所有的按钮上正常工作。然而,当我尝试在我的splash活动中使用文本转换语音时,它会使应用程序崩溃。这是一个空指针异常,所以我知道我只是编码不正确。澄清我希望它做什么。我想让它在飞溅活动中说话。当splash活动休眠时,我希望它再次对话,告诉用户它已完成加载 public class mainj extends Activity implements OnInitListener { private TextToSpeech myTT

我在我的应用程序中使用文本到语音,我已经能够让它在我所有的按钮上正常工作。然而,当我尝试在我的splash活动中使用文本转换语音时,它会使应用程序崩溃。这是一个空指针异常,所以我知道我只是编码不正确。澄清我希望它做什么。我想让它在飞溅活动中说话。当splash活动休眠时,我希望它再次对话,告诉用户它已完成加载

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();
        }
    }

}

就在你睡觉后的帖子开头,你在呼唤speakWords。这就叫myTTS.speak。在这一点上看你的代码,myTTS似乎没有被初始化,并且是空的,因此会在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();
    }
}

}

就在你睡觉后的帖子开头,你在呼唤speakWords。这就叫myTTS.speak。在这一点上看你的代码,myTTS似乎没有被初始化,并且是空的,因此会在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();
    }
}

}

加载TTS引擎后,最好调用You's little loading snippet,这样就可以将speak放入OnActivityResult()

在您的代码中,当您调用speak时,实际上无法判断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();
                }
            }

加载TTS引擎后,最好调用You's little loading snippet,这样就可以将speak放在OnActivityResult()中

在您的代码中,当您调用speak时,实际上无法判断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();
                }
            }

你的方法有两个问题

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


使用或帮助TextToSpeech初始化。这实际上有点复杂,使用
TextToSpeech.Engine.ACTION\u CHECK\u TTS\u DATA
实际上不是最好的方法。

你的方法有两个问题

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


使用或帮助TextToSpeech初始化。它实际上有点复杂,使用
TextToSpeech.Engine.ACTION\u CHECK\u TTS\u DATA
实际上并不是最好的方法。

我知道这是一个noob问题,但如何初始化它?@SamBevins TextToSpeech myTTS=new TextToSpeech()或其他构造函数,我不知道它是如何工作的。@Kaediil Ok,我尝试了您的代码,现在在执行intent-intent-checkttsinent=new-checkttsinent.setAction时出现错误(.new之后的CheckttsInt部分带有下划线,表示无法解析为类型OK,我应该猜到错误吗?另外,我没有您的所有资源文件,因此我试图给出代码的想法。请告诉我错误是什么,我可以尝试帮助您。我告诉过您错误是什么。错误是我提到的带下划线的部分,不能是rE已解决类型。由于出现错误,我甚至无法运行应用程序。我知道这是一个noob问题,但如何初始化它?@SamBevins TextToSpeech myTTS=new TextToSpeech()或者另一个构造函数,我不知道它是如何工作的。@Kaediil好的,我试过你的代码,现在当你做intent-intent-checkttsinent=new-checkttsinent.setAction时,我有一个错误(.new之后的CheckttsInt部分带有下划线,表示无法解析为类型OK,我应该猜到错误吗?另外,我没有您的所有资源文件,因此我试图给出代码的想法。请告诉我错误是什么,我可以尝试帮助您。我告诉过您错误是什么。错误是我提到的带下划线的部分,不能是rE属于某一类型。我甚至无法运行应用程序,因为出现错误。不起作用。它仍然崩溃,但只是在不同的位置。你能发布堆栈跟踪吗?不起作用。它仍然崩溃,但只是在不同的位置。你能发布堆栈跟踪吗?这是一些很好的信息。当我能够使用这些时,我会努力。这是一些很好的信息n、 当我有能力时,我会努力使用这些。