Search code examples
javaandroidgoogle-text-to-speech

Why are the functions of UtteranceProgressListener not called?


When I call the speak function of its class, the UtteranceProgressListener is called but the methods of the listener are not called i.e. the onStart(),the onDone() and onError().

Ultimately, we want to write a piece of code that can pause the text to speech and resume from the same sentence using play-pause buttons.

package com.example.android.m_tour;

import android.content.Intent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


import com.wnafee.vector.MorphButton;

import java.util.HashMap;
import java.util.Locale;

import static com.example.android.m_tour.R.id.mb;


public class guide extends AppCompatActivity implements MorphButton.OnStateChangedListener {

    private Button settingsButton;
    private String data, s;
    private TextView textView;
    private static TextToSpeech textToSpeech;

    //qr code scanner object
    private MainActivity mainActivity;
    private TTSsettings ttSsettings;
    private MorphButton control;
    private Locale loc;
    private String pr[];


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guide);
        control = (MorphButton) findViewById(mb);
        mainActivity = new MainActivity();
        textView = (TextView) findViewById(R.id.textview);
        textView.setText(mainActivity.getData());
        settingsButton = (Button) findViewById(R.id.settings);
        ttSsettings = new TTSsettings();
        loc = new Locale("en_IN");

        control.setOnStateChangedListener(this);
        settingsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent = new Intent(guide.this, TTSsettings.class);
                startActivity(intent);
                /*textToSpeech.stop();
                Intent intent = new Intent();
                intent.setAction("com.android.settings");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);*/
            }
        });
        data = mainActivity.getData();
        onStart();

        textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int i) {
                if (i == TextToSpeech.SUCCESS) {
                    //set language Locale to US
                    int result = textToSpeech.setLanguage(loc);
                    //check that is language locale available on device or supported
                    if (result == TextToSpeech.LANG_MISSING_DATA
                            || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Toast.makeText(guide.this, "Leanguage not present", Toast.LENGTH_SHORT).show();
                    } else {
                        speakOut();
                    }

                } else {
                    //show toast if initialization failed
                    Toast.makeText(getBaseContext(), "TTS Engine Initilization Failed!", Toast.LENGTH_SHORT).show();
                }

                textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                    @Override
                    public void onStart(String s) {
                        //if ("id".equals(s)
                        Toast.makeText(guide.this, "onStart works", Toast.LENGTH_SHORT).show();

                    }

                    @Override
                    public void onDone(String s) {
                        //if ("id".equals(s))
                            Toast.makeText(guide.this, "onDone works", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onError(String s) {
                        //if ("id".equals(s))
                            Toast.makeText(guide.this, "OnError works", Toast.LENGTH_SHORT).show();
                    }
                });

            }
        });
    }

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

    @Override
    public void onStateChanged(MorphButton.MorphState changedTo, boolean isAnimating) {
        if (changedTo == MorphButton.MorphState.END) {
            textToSpeech.stop();
        } else {
            speakOut();

        }
    }

    private void speakOut() {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "id");
        textToSpeech.setPitch((float) ttSsettings.getPitchRate());
        textToSpeech.setSpeechRate((float) ttSsettings.getSpeechRate());
        textToSpeech.speak(pr[1], TextToSpeech.QUEUE_FLUSH, params);
        }


    //getters
    public String getData() {
        return data;
    }

    public static TextToSpeech getTextToSpeech() {
        return textToSpeech;
    }
}

Solution

  • The setOnUtteranceProgressListener() method must be called before speak() is called. Now you call your speakOut() method first and only afterwards set the listener. It needs to be the other way round as in:

    textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int i) {
            if (i == TextToSpeech.SUCCESS) {
                //set language Locale to US
                int result = textToSpeech.setLanguage(loc);
                //check that is language locale available on device or supported
                if (result == TextToSpeech.LANG_MISSING_DATA
                        || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Toast.makeText(guide.this, "Leanguage not present", Toast.LENGTH_SHORT).show();
                } else {
                    textToSpeech.setOnUtteranceProgressListener(
                        new UtteranceProgressListener() {
                        @Override
                        public void onStart(String s) {
                            //if ("id".equals(s)
                            Toast.makeText(guide.this, "onStart works", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onDone(String s) {
                            //if ("id".equals(s))
                            Toast.makeText(guide.this, "onDone works", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onError(String s) {
                            //if ("id".equals(s))
                            Toast.makeText(guide.this, "OnError works", Toast.LENGTH_SHORT).show();
                        }
                    });                            
    
                    speakOut();
                }
            } else {
                //show toast if initialization failed
                Toast.makeText(getBaseContext(), "TTS Engine Initilization Failed!", Toast.LENGTH_SHORT).show();
            }
        }
    });