Problems with an App? Comments and bad ratings do not help…

Today I noticed a change in ratings of my application “Read it loud! SMS Reader Basic” – one 5 star rating had gone while a 2 star rating had appeared. Obviously a user had changed his mind after a bad experience with the app. Then I saw a accompanying comment – let me quote:

Worked great with my Evo 4G and my Evo 3D…and worked for a day on my Motorola Photon…but it stopped for some reason…love the app otherwise

I really would love to offer help, to find out what the error was and to correct it – but I can’t.

What most users do not keep in mind is that we developers cannot reply to comments and ratings, we cannot even contact the one who wrote that comment. So what can YOU as a user do instead of just writing negative comments and ratings? Well, if you like the app in general but had some negative experience – may it be an error or a function not working as expected or even a feature wish – then give us developers a chance to give you support and improve our apps. Just contact us – a suitable mail address can be found on every app’s market page. And then tell us what happened. Did you change something on your phone? Was there a software update? Did you notice anything when it stopped working?

We do lots of testing before publishing apps and invest lots of effort to produce quality software – so if you get an error or a problem then there is a good chance that we can fix it in a short time. Which means no bad ratings for us and our apps and better apps for you to use.

Agreed? Thank you!

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:

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:

@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…