It is amazing how far computing has come in the last 10 years. In 2006 I was part of a very costly and intensive project at NCR to add speech capability to an automated teller machine. We spent months writing firmware and integrating custom hardware for a handful of phrases you might hear while making a bank transaction. Yet today, any computing platform worth developing for has sophisticated text-to-speech capability baked right in. If you’ve ever used Google Maps turn-by-turn navigation, you know Android is no slouch in this department.
This tutorial shows you just how easy it is to teach your Android app to speak. Feel free to follow along or download and import the project directly into Eclipse.
1. Create a new Android project in Eclipse. Target Android 2.2 or higher.
2. In the /res/layout folder, modify activity_main.xml to include a button and an edit text field inside of a relative layout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextViewandroid:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TTS Demonstration" />
<Buttonandroid:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/editText1"
android:layout_centerHorizontal="true"
android:layout_marginTop="43dp"
android:text="Say It" />
<EditText android:id="@+id/editText1"android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="77dp"
android:ems="10"
android:text="Hello world!" />
</RelativeLayout>
3. With the layout in place, we can begin coding the /src/MainActivity.java file. Start by extending the standard Android activity class and implementing the on click and on initialize interfaces. The on create function will load our layout, instantiate the text to speech service, and wire the button.
MainActivity.java package com.authorwjf.hellotts;
import java.util.Locale;
import android.os.Bundle; import android.app.Activity; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnInitListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener, OnInitListener
{
private TextToSpeech tts;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this); findViewById(R.id.button1).setOnClickListener(this);}
}
4. Let’s look at the on initialization callback. This mechanism lets us know our text-to-speech engine is ready to go and is the ideal place to set the language.
@Override public void onInit(int code) { if (code==TextToSpeech.SUCCESS) {tts.setLanguage(Locale.getDefault());
} else { tts = null; Toast.makeText(this, "Failed to initialize TTS engine.",
Toast.LENGTH_SHORT).show();}
}
5. With our text-to-speech engine loaded, we are prepped to handle the user button clicks.
@Override public void onClick(View v) { if (tts!=null) { String text =
((EditText)findViewById(R.id.editText1)).getText().toString(); if (text!=null) { if (!tts.isSpeaking()) { tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);}
}
}
}
6. We need to make sure we clean up the text-to-speech engine when our application shuts down. Failing to do so can result in a crash if the user suddenly switches applications while the engine is in the middle of a sentence.
@Override protected void onDestroy() { if (tts!=null) {tts.stop();
tts.shutdown();
}
super.onDestroy(); }
That’s all there is to it. Load up the APK on the emulator or a device and give it a listen.
Despite the default voice sounding a little like the Speak-N-Spell E.T. used to phone home, the pronunciations are pretty much perfect. I am not a fan of every API in the Android SDK, but the folks at Google deserve some credit for this one. It provides a heck of a lot of functionality and requires a minimum amount of coding.