Saturday, October 30, 2010

The Speech App using XML Layout

In our previous example we created a Text to Speech app in which we created an instance of the view object and passed it to the on-create-view macro. In this example we will use the android XML layout facility. You will see how simple our apps become.

First edit the "res/layout/main.xml" file to read as follows.

<?xml version="1.0" encoding="utf-8"?>
  <TextView android:text="@string/label_text"
  <EditText android:id="@+id/edit_text"
  <Button android:text="@string/button_text"

Notice the second to last line. We are setting the onClickListener of the button to a public method in the activity class called "onSpeakButtonClick". Next edit the "res/values/strings.xml" file to read as follows.

<?xml version="1.0" encoding="utf-8"?>
  <string name="app_name">hello</string>
  <string name="label_text">Enter the text to speak here</string>
  <string name="button_text">Speak!</string>

Now let us look at the source code. Edit your "src/kawa/android/hello.scm" file to read as follows.

(require 'android-defs)

(activity hello
  (mTts ::android.speech.tts.TextToSpeech)
    (set! mTts
        (lambda (i) ()))))
  ((onSpeechButtonClick (v ::android.view.View)) ::void
      ((as <android.widget.EditText>

First we create the class using the 'activity' macro, with the name 'hello'.  Inside the hello class we define an instance variable and two methods. First we define the instance variable mTTs. Next we use the 'create-view' macro to create the classes 'onCreate' method. Here, we did not use the 'on-create-view' macro as we did in the previous examples. Thats because we want to call the 'setContentView' method ourselves.
In the line above we 'setContentView' to 'kawa.speaker.R$layout:main'. We have to use the full qualified package name. We use the '$' in 'R$layout' because that is how inner classes are generated by the compiler.

If you noticed we did not call the super class onCreate method ourselves. This is called behind the scenes by the 'on-create' macro. This is one of the advantages in developing with scheme. We can simplify coding using macros. We then set! the mTts instance variable to a new instance of the android.speech.tts.TextToSpeech class.

We don't have a macro to create the onSpeakButtonClick method for us. So we define the method itself here. The rest of the code is the same as the one we saw in the previous example.

Now build your app and run it.


  1. Hi Santosh,

    Thanks for the nice posts. Can you publish an app written in Kawa to the Android market?


  2. Hi Santosh, I cannot get this to compile:

    [java] (compiling /home/Code/Android/KawaText2Speech/src/kawa/android/hellokawa.scm to
    [java] /home/Code/Android/KawaText2Speech/src/kawa/android/speech.scm:15:11: no known slot 'edit_text' in java.lang.Object

    it seems to have a problem with this line:$id:edit_text)):getText)

    Any idea ? Thanks

  3. My code compiles fine. I re checked. You should have only one scm file called hello.scm. Hope this helps.

  4. Build failed due to a compilation warning. I removed "warn-as-error- from the ant file and it now builds successfully.

    Kawa seems to spit out quite a lot of "no known slot .... in java.lang.Object", should I be concerned ?

  5. Please post this question to the Kawa framework mailing list, where you can get a response from the author himself. Here is the link.

  6. It doesn't work as published. The XML file says "onSpeakButtonClick" but the code defines a method called "onSpeechButtonClick".

    If you correct that mistake I can confirm it works a treat... my *next* Android app will be in Scheme, I loathe coding in Java!

    All the best,
    Sean Charles.