Search code examples
androidlistviewtext-to-speech

Creating reuseable TTS Object


I want to create a app that shows data from a local db in a ListView, lets you add strings to the db and then read whatever word is selected. For OO purpose I want a reuseable TTS-Object.

Currently everything is implemented and if I select a word in the ListView the entry is shown as a toast which means I have a string of the word.

problem: When I am creating my TTS Object I am getting a NullPointerException.

Here is the code that shows what happens, when a entry in the ListView is selected:

    list.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Cursor cursor = (SQLiteCursor) list.getItemAtPosition(position); 
            String title = cursor.getString(1);
            Toast.makeText(getApplicationContext(), "selected: " + title , Toast.LENGTH_SHORT).show();

//--> App chrashes here
            AndroidTextToSpeechActivity attsa = new AndroidTextToSpeechActivity();
            attsa.speakOut(title);

        }
    }); }

Here is the logcat:

07-22 20:25:58.718: W/dalvikvm(18373): threadid=1: thread exiting with uncaught exception (group=0x40a6b1f8) 07-22 20:25:58.738: E/AndroidRuntime(18373): FATAL EXCEPTION: main 07-22 20:25:58.738: E/AndroidRuntime(18373): java.lang.NullPointerException 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.content.ContextWrapper.getPackageName(ContextWrapper.java:127) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.speech.tts.TextToSpeech.(TextToSpeech.java:545) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.speech.tts.TextToSpeech.(TextToSpeech.java:522) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.speech.tts.TextToSpeech.(TextToSpeech.java:507) 07-22 20:25:58.738: E/AndroidRuntime(18373): at eu.tuts.dbexample.obj.AndroidTextToSpeechActivity.(AndroidTextToSpeechActivity.java:20) 07-22 20:25:58.738: E/AndroidRuntime(18373): at eu.tuts.dbexample.activities.Datenbanken$1.onItemClick(Datenbanken.java:79) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.widget.AdapterView.performItemClick(AdapterView.java:292) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.widget.AbsListView.performItemClick(AbsListView.java:1060) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2516) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.widget.AbsListView$1.run(AbsListView.java:3170) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.os.Handler.handleCallback(Handler.java:605) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.os.Handler.dispatchMessage(Handler.java:92) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.os.Looper.loop(Looper.java:137) 07-22 20:25:58.738: E/AndroidRuntime(18373): at android.app.ActivityThread.main(ActivityThread.java:4575) 07-22 20:25:58.738: E/AndroidRuntime(18373): at java.lang.reflect.Method.invokeNative(Native Method) 07-22 20:25:58.738: E/AndroidRuntime(18373): at java.lang.reflect.Method.invoke(Method.java:511) 07-22 20:25:58.738: E/AndroidRuntime(18373): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 07-22 20:25:58.738: E/AndroidRuntime(18373): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 07-22 20:25:58.738: E/AndroidRuntime(18373): at dalvik.system.NativeStart.main(Native Method)

and here is the full sourcecode of the TTS Object. Sorry for posting the full Sorcecode - i dont know where the error happens.

    package eu.tuts.dbexample.obj;

import java.util.Locale;
import eu.tuts.dbexample.R;
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class AndroidTextToSpeechActivity extends Activity implements TextToSpeech.OnInitListener {
    /** Called when the activity is first created. */

    private TextToSpeech tts = new TextToSpeech(this, this);

    @Override
    public void onDestroy() {
        // Don't forget to shutdown tts!
        if (tts != null) {
            tts.stop();
            tts.shutdown();
        }
        super.onDestroy();
    }

    public void onInit(int status) {

        if (status == TextToSpeech.SUCCESS) {

            int result = tts.setLanguage(Locale.US);

            if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS", "This Language is not supported");
            } else {
                //speakOut();
                Log.d("TTS", "TTS init okay");
            }

        } else {
            Log.e("TTS", "Initilization Failed!");
        }

    }

    public void speakOut(String text) {

        tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
    }
    }

Solution

  • You cannot create the TextToSpeech instance in the constructor of the Activity, because the first parameter in the constructor of TextToSpeech is a Context and the context isn't set up until onCreate() is called in the Activity.

    Change this:

    private TextToSpeech tts = new TextToSpeech(this, this);
    

    to this:

    private TextToSpeech tts;
    

    and put this code in onCreate() in your activity:

    tts = new TextToSpeech(this, this);