0

I am building an android native app for visually impaired people, And I want to use android TTS - android.speech.tts.TextToSpeech to guide the user to use my app. I succeeded in displaying the speech after a click on a button, but also I want to output a welcome message once the Activity is visible. here is a code snippet:


public class MainActivity extends AppCompatActivity  {
    private TextToSpeech textToSpeech;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textToSpeech=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status==TextToSpeech.SUCCESS){
                    int result=textToSpeech.setLanguage(Locale.getDefault());
                    if (result == TextToSpeech.LANG_MISSING_DATA
                            || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Log.e("TTS", "Language not supported");
                    } else {
                        Log.d("TTS","Speech initialized");
                    }
                } else {
                    Log.e("TTS", "Initialization failed");
                }
            }
        });
        speak("welcome");
        speak("Click on the button to begin settings ");

        audio.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                speak("this is a test");
            }
        });
    }
    public void speak(final String S){
    textToSpeech.speak(S,TextToSpeech.QUEUE_ADD,null);
    }
}
agoufx
  • 49
  • 4

2 Answers2

0

The problem is that the tts isn't initialized yet.

The quickest way to fix it is just move the introductory speak commands inside onInit:

@Override
            public void onInit(int status) {
                if (status==TextToSpeech.SUCCESS){
                    int result=textToSpeech.setLanguage(Locale.getDefault());
                    if (result == TextToSpeech.LANG_MISSING_DATA
                            || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Log.e("TTS", "Language not supported");
                    } else {
                        Log.d("TTS","Speech initialized");

                        speak("welcome");
                        speak("Click on the button to begin settings ");
                    }
                } else {
                    Log.e("TTS", "Initialization failed");
                }
            }
Nerdy Bunz
  • 6,040
  • 10
  • 41
  • 100
0

based on [https://stackoverflow.com/a/48354182/13518237][1] I managed to make it work. here is the code

public class Speech  implements TextToSpeech.OnInitListener {
    private boolean initialized;
    private String queuedText;
    private String TAG = "TTS";
    private TextToSpeech tts; //text to speech

    public Speech() {
    }

    public TextToSpeech getTts() {
        return tts;
    }

    public void setTts(TextToSpeech tts) {
        this.tts = tts;
    }
    public void speak(String text) {
        if (!initialized) {
            queuedText = text;
            return;
        }
        queuedText = null;
        HashMap <String, String> params= new HashMap();
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"Done Speaking");
        tts.speak(text, TextToSpeech.QUEUE_ADD, params);
    }
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            initialized = true;
            tts.setLanguage(Locale.ENGLISH);
            if (queuedText != null) {
                speak(queuedText);
            }
        }
    }
}
public class Menu extends AppCompatActivity {
    private RelativeLayout audio;
    private Speech speech = new Speech();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_menu);
        audio= findViewById(R.id.audio);
        speech.setTts(new TextToSpeech(this, speech));
        speech.speak("This is the menu");
 audio.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                speak("this is a test");
            }
        });
    }

    @Override
    public void onDestroy() {
        if (speech.getTts()!=null){
            speech.getTts().stop();
            speech.getTts().shutdown();
        }
        super.onDestroy();
    }
}
agoufx
  • 49
  • 4