1
votes

I have implemented an android TTS code from online tutorials. All the tutorials have a text box and a submit button to capture the text which it wants to speak. My aim is to get a text from a file and then speak and no user input is required (as this module will be implemented as a class and all user input will happen in the main activity).

The code that I have implemented is

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MyTextToSpeech extends Activity implements OnInitListener{
    /** Called when the activity is first created. */
    private int MY_DATA_CHECK_CODE = 0;

    private TextToSpeech tts;

    private EditText inputText;
    private Button speakButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //inputText = (EditText) findViewById(R.id.input_text);
       // speakButton = (Button) findViewById(R.id.speak_button);

       // speakButton.setOnClickListener(new OnClickListener() {                     

            //public void onClick(View v) {
             //  String text = inputText.getText().toString();
            //   if (text!=null && text.length()>0) {
                  //  Toast.makeText(MyTextToSpeech.this, "Saying: " + text, Toast.LENGTH_LONG).show();
//tts.speak(text, TextToSpeech.QUEUE_ADD, null);
                 //   
               //}
           // }
        //});
        Intent checkIntent = new Intent();
        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
        tts.speak("hi this is a test", TextToSpeech.QUEUE_ADD, null); //Added by me
   }

   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == MY_DATA_CHECK_CODE) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                    // success, create the TTS instance
                    tts = new TextToSpeech(this, this);

            }
            else {
                    // missing data, install it
                    Intent installIntent = new Intent();
                    installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                    startActivity(installIntent);
            }
     }
   }

    public void onInit(int status) {               
      if (status == TextToSpeech.SUCCESS) {
            Toast.makeText(MyTextToSpeech.this, "Text-To-Speech engine is initialized", Toast.LENGTH_LONG).show();
      }
      else if (status == TextToSpeech.ERROR) {
            Toast.makeText(MyTextToSpeech.this, "Error occurred while initializing Text-To-Speech engine", Toast.LENGTH_LONG).show();
      }
    }       
}

In the code above I have commented out the lines where the text was being captured from the user. The code was functioning perfectly when the 'tts.speak' method was in the onClick method. When I got it out at the end the code is misbehaving and giving a 'null pointer exception' and closing my app.

How do I resolve the above issue.

Thanks a ton in advance.

PS: If I initiate the TTS before by using command tts = new TextToSpeech(this, this); in the main activity the null pointer exception is not there but the app does not speak anything.

1

1 Answers

1
votes

You are initializing the variable tts in your onActivityResult() method.

You call the TextToSpeech.Engine.ACTION_CHECK_TTS_DATA activity in your onCreate() method and when that activity finishes, your onActivityResult() method is called.

This works with the code you've commented out because the user can't actually click on the button to make it talk until after the TTS check activity has completed and returned to your activity and you've set tts = new TextToSpeech(this, this);.

In the code you've posted, you are calling tts.speak() before the variable tts has been set to anything -- that is a sure way to get a NullPointerException.

Also, you need to make sure that onInit() callback has been made before you try to speak anything with your tts reference. That is why, when you initialize the tts reference before, the NullPointerException goes away but it doesn't speak (because the onInit() callback hasn't happened yet).