Using OnUtteranceCompletedListener, the right way…

You know Androids TextToSpeech-Service? It enables you to enhance your Android apps with voice output in a very convenient way. What I like most is that it runs completely in the background, so that calling myTTSService.speak("Some very long text indeed...");  does not stop your main thread from continuing which is one reason less to get an “Application not responding”-error.

So far so good, but sometimes you just need to know when the TTS-Service has finished speaking a sentence. Well, the API documentation suggests the following: Just make your calling class implement OnUtteranceCompletedListener, register it with the TTS-Service and get notified whenever a sentence is finished. Let source code speak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class MyAwesomeActivity extends Activity implements OnInitListener, OnUtteranceCompletedListener {
    private TextToSpeech myTTS = null;
    private boolean speechInitialized = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //create the TTS-object
        myTTS = new TextToSpeech(this,this);
        //and register ourselves, as we want to be notified on finishing...
        myTTS.setOnUtteranceCompletedListener(this);
    }

    /**
    * Override für OnInitListener.onInit(), gets called when TTS is initialized and ready to speak
    */

    @Override
    public void onInit(int status) {
        speechInitialized = true;
        speak("FIRSTSENTENCE", "Hello World!");
    }

    /**
    * Gets called when TTS has finished speaking a sentence identified by utteranceID
    */

    @Override
    public void onUtteranceCompleted(String utteranceId) {
        //do something, e.g. update the GUI or something like that (beware of threading)
    }

    /**
    * Speak a sentence
    */

    private void speak(String utteranceID, String whatToSpeak) {

        HashMap params=new HashMap();
        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,utteranceID);

        if (myTTS!=null) myTTS.speak(whatToSpeak, TextToSpeech.QUEUE_ADD, params);
    }
}

After compiling and running this code one would expect (at least I did on first try) that the TTS-Engine would
(a) be initialized
(b) would speak “Hello world”
(c) call my method onUtteranceCompleted with “FIRSTSENTENCE” as parameter.

Well, (a) and (b) happened perfectly. Not so much (c), where not so much means not at all. What happened? After trying I lot i found out that the API documentation does not mention on thing: The call myTTS.setOnUtteranceCompletedListener(this); MUST be used AFTER onInit has been called by the TTS -Service.

So changing two methods helps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //create the TTS-object
    myTTS = new TextToSpeech(this,this);
}

    /**
    * Override für OnInitListener.onInit(), gets called when TTS is initialized and ready to speak
    */

    @Override
    public void onInit(int status) {
        speechInitialized = true;
        //and NOW register ourselves, as we want to be notified on finishing...
        myTTS.setOnUtteranceCompletedListener(this);
        speak("FIRSTSENTENCE", "Hello World!");
    }

Nice to know…

Tempolimit – finished. What is next?

Nachdem die App Tempolimit nun auch in meinen Augen das erste mal so richtig “fertig” ist – feature complete – wie man auch gerne sagt, geht es auf zu neuen Projekten. Was das ist, gibt es demnächst an dieser Stelle.

Was aber nicht heissen soll, dass es mit Tempolimit jetzt gar nicht mehr weiter geht – wer also Ideen und Wünsche für neue Funktionen hat, der schreibe einfach mal was in die Kommentare zu diesem Post ;-)

Danke Google, Danke Android-User, oder: Das Wunder der digitalen Distribution

Als ich vor 15 Jahren damit anfing, Software nicht nur für mich, sondern auch für andere zu entwickeln, war ich froh, wenn sich überhaupt mal ein Abnehmer dafür finden liess – heute ist die Welt anders: Dank App Stores und der weiten Verbreitung mobiler Endgeräte, die auf diese App-Stores zugreifen, ist es heute möglich, ohne nennenswerten Aufwand in Marketing oder Vertrieb erstaunlich hohe Absatzzahlen zu erreichen.

Und somit freue ich mich heute, dass die App Tempolimit mehr als 5.000 Downloads alleine im Android Market erreicht hat.

Und deshalb: Danke an Google, dass ihr das möglich gemacht habt, und danke an die 5040 User, die die App bis heute heruntergeladen haben. Noch mehr Dank an die 2365, die sie auch behalten haben ;-) Und am meisten an die 39, die mit positiven Bewertungen und Kommentaren, wie auch mit Ideen zur Weiterentwicklung beigetragen haben!

tempolimit 4.2 ahead

die nächste version der app befindet sich kurz vor der veröffentlichung. neben einigen änderungen unter der haube gibt es neues vor allem für die, die gerne mal mit dem boot auf deutschen binnengewässern unterwegs sind: aufgrund des dort gültigen niedrigen tempolimits von gerade mal 6km/h habe ich die untergrenzen für die untere einstellbare geschwindigkeit, die es bislang in abhängigkeit von der eingestellten geschwindigkeitseinheit gab, entfernt. happy boating also und dank an michael k. für die anregung!