4

My app crashes and in logcat I find the error

android.speech.tts.TextToSpeech.setLanguage(java.util.Locale)' on a null object reference

Here is my class :

public class cl_txt2speech {

    TextToSpeech txt2speech;
    Activity context;

    String txt2speech_current_language = "" ;
    boolean txt2speech_available = false ;

    //@Override
    protected void onCreate(Bundle savedInstanceState) {

        txt2speech = new TextToSpeech(context.getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status != TextToSpeech.ERROR) {
                    txt2speech_available = true ;
                }
            }
        });
    }

    void txt2speech_change_language( String lang )
    {
        if( lang=="fr" )
        {
            txt2speech.setLanguage(Locale.FRANCE);
        }
        else if( lang=="en" )
        {
            txt2speech.setLanguage(Locale.UK);
        }
        else if( lang=="es" )
        {
            Locale locSpanish = new Locale("spa", "MEX");
            txt2speech.setLanguage(locSpanish);
        }
        txt2speech_current_language = lang ;
    }

    void txt2speech_speak( String lang , String txt )
    {
        if( lang != txt2speech_current_language ){ txt2speech_change_language( lang ); }
        txt2speech.speak(txt, TextToSpeech.QUEUE_FLUSH, null);
    }
}

and here is how I use it

cl_txt2speech txt2speech = new cl_txt2speech();
txt2speech.txt2speech_speak( "fr" , "test, 1 2 3" );

I don't understand what is the problem, I defined TextToSpeech txt2speech ; at the beginning.

update 1 : I did add some System.out.println() to trace what is happening, and it seems that the code in onCreate is never executed. So the problem must come from how I use my class.

update 2 :

I ended up moving everything to my fullscreenActivity.java file instead of using a class, to see what happens.

public class FullscreenActivity extends AppCompatActivity implements
        TextToSpeech.OnInitListener{
...
public TextToSpeech txt2speech;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    txt2speech = new TextToSpeech(this, this);
    ...
}

@Override
public void onInit(int status) {
    System.out.println( "--------------- onInit() -------------" );
    if (status != TextToSpeech.ERROR) {
        txt2speech_available = true;
    }
}

and onInit is never fired here neither...

Also, when calling txt2speech.getDefaultLanguage() I have the error "getDefaultLanguage failed: not bound to TTS engine"

Diego
  • 569
  • 1
  • 9
  • 28
  • You'll need a TTS engine installed on your device: be sure to install one - here's one from google: https://play.google.com/store/apps/details?id=com.google.android.tts&hl=en_US&gl=US . –  Oct 07 '21 at 02:33
  • I did, and I checked that it worked by executing my html5 game in Chrome instead of my app. – Diego Oct 07 '21 at 12:47
  • 1
    Actually, there was in deed a problem with the TTS engine. I uninstalled it and reinstalled it and now it works. Some apps must have messed with it. – Diego Oct 07 '21 at 14:30
  • Good news. Also be advised on string compares (your next issue) - don't use `==` : https://stackoverflow.com/a/513839/2711811 –  Oct 07 '21 at 14:31

3 Answers3

1

You commented out the @Override annotation of the method onCreate() that way it's just a meaningless method which never gets called.

Edit: I just saw your class doesn't extend Activity, that way you can't override the method IIRC. Try refactoring that piece of code into the constructor of your class.

moeux
  • 191
  • 15
  • I add " extends Activity" and uncommented @override, but onCreate() is still never called. – Diego Oct 01 '21 at 13:21
  • How do you call this class? Do you instantiate it with the `new` keyword? Because that won't work if you want the `onCreate()` method to be executed. You have to use `startActivity()`, here is a tutorial: https://developer.android.com/training/basics/firstapp/starting-activity – moeux Oct 04 '21 at 14:57
  • I do not want to change the activity, I just want to use the functions that I wrote, in my main activity. – Diego Oct 04 '21 at 22:23
  • As I said, then you have to put that piece of code into the constructor of your class. After that you can create a new instance of your class inside your main activity and use it without any problems. – moeux Oct 08 '21 at 16:52
1

The txt2speech object never has been initialized. Edit your code like below and then you can create a object of cl_txt2speech class in some activity :

public class cl_txt2speech {

    TextToSpeech txt2speech;

    String txt2speech_current_language = "" ;
    boolean txt2speech_available = false ;

    public cl_txt2speech(Context context) {

        txt2speech = new TextToSpeech(context.getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status != TextToSpeech.ERROR) {
                    txt2speech_available = true ;
                }
            }
        });
    }

    void txt2speech_change_language( String lang )
    {
        if( lang=="fr" )
        {
            txt2speech.setLanguage(Locale.FRANCE);
        }
        else if( lang=="en" )
        {
            txt2speech.setLanguage(Locale.UK);
        }
        else if( lang=="es" )
        {
            Locale locSpanish = new Locale("spa", "MEX");
            txt2speech.setLanguage(locSpanish);
        }
        txt2speech_current_language = lang ;
    }

    void txt2speech_speak( String lang , String txt )
    {
        if( lang != txt2speech_current_language ){ txt2speech_change_language( lang ); }
        txt2speech.speak(txt, TextToSpeech.QUEUE_FLUSH, null);
    }
}

And here is how to use :

cl_txt2speech txt2speech = new cl_txt2speech(this);
txt2speech.txt2speech_speak( "fr" , "test, 1 2 3" );
Hossein
  • 439
  • 3
  • 9
0

Are you missing a super call of the onCreate()?

Try adding it and then give it a try. I believe without super call your onCreate() won't execute.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

}
Vishal Naikawadi
  • 419
  • 6
  • 11