Try Tuts+ Premium, Get Cash Back!
Android SDK: Using the Text to Speech Engine

Android SDK: Using the Text to Speech Engine

Tutorial Details
  • Technology: Android SDK
  • Difficulty: Intermediate
  • Est. Completion Time: 1 Hour

This tutorial will teach you to give your applications a voice with the Android SDK text to speech engine!

The Android text to speech engine still seems to be a pretty underused resource in Android apps. However, implementing it in your own applications is straightforward. There are a few potential issues and choices you need to consider, but for most purposes, the process is not a complex one. In this tutorial we jump around a bit within one Android Activity, but don’t worry, the complete code is listed at the end. The aim is to give you a clear idea of the what’s going on at each processing stage so that you can successfully use the function in any app.


Step 1: Start or Open an Android Project

If you already have an application you want to implement Text To Speech with, open it in your IDE. Otherwise, create a new Android project. You can use the code in this tutorial with any Activity class. For demonstration, we will first create some user interface elements. Again, if you already have your own UI, you can use it instead.


Step 2: Create User Interface Elements

Add some user interface elements to your application, allowing the user to enter text and initiate speech playback using a button. In the XML layout file for your Activity, which will be “main.xml” if you created a new project, add the following markup:

<TextView android:id="@+id/intro"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:text="Enter some text:"
/>
<EditText android:id="@+id/enter"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
/>
<Button android:id="@+id/speak"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="Speak"
/>

Your XML layout files should be in the “res/layout” directory within your application package. This code adds three user interface elements: a label with some instructional text in it, an editable text-field, and a button. The user will be able to enter text into the field, then press the button to hear it spoken. If you are using an existing project, you can of course use the interface elements you already have. If you are using these new elements, you can alter them to suit the design of your own app.

Speech App User Interface

Step 3: Listen For User Events

Open the Java file for the Activity you want to implement TTS in. If you created a new app, open the main class file. In Eclipse, your Activity should automatically have the “onCreate” method within it and should extend “Activity” as part of its declaration. At the top of the class file, add the following import statements so that your app can listen for button clicks:

import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;

Alter the class declaration to implement the “OnClickListener” interface, as in the following sample line of code:

public class SpeakingAndroid extends Activity implements OnClickListener

Alter the class name to suit your own application details. Your IDE may display warnings because your class has not yet implemented “OnClickListener” correctly – just ignore these for now. In the “onCreate” method, add the following code:

Button speakButton = (Button)findViewById(R.id.speak);
speakButton.setOnClickListener(this);

If you did not add the button using “speak” as its ID in your XML layout file, alter this code to reflect the correct ID value. This sets your Activity class up to handle user button clicks. Add the following method outline to your class:

public void onClick(View v) {
//handle user clicks here
}

Inside this method you will begin the Text To Speech functionality.


Step 4: Get the Entered Text

When the user clicks the button, your app needs to get any text entered so that you can pass it to the TTS method. Add the following import statement at the top of your class declaration so that your code can refer to the editable text-field:

import android.widget.EditText;

Inside your “onClick” method, add the following code:

EditText enteredText = (EditText)findViewById(R.id.enter);
String words = enteredText.getText().toString();

This code first acquires a reference to the text-field using its ID value, so alter this if you used a different value in your layout XML. Next, the code gets the text from the field and stores it as a string variable. If the user has not entered any text this will be empty. Depending on the logic within your application you may wish to add a conditional test, checking that the string is not null or zero in length, but this is not generally necessary.

Entering Text

Step 5: Create a Speech Method

To keep your Android classes well-organized, it’s advisable to create dedicated methods for processes you may want to use more than once. Add the following method outline to your Activity:

private void speakWords(String speech) {
//implement TTS here
}

This is where your TTS processing will go. Back in the “onClick” listener method, call this new method, passing it the string variable your code copied from the text-field:

speakWords(words);

Using a method for the TTS process means that your code can call on it elsewhere if necessary.


Step 6: Implement TTS Within the Class

To utilize the TTS facility, you need to make a few more changes to your class declaration. Add the following import statements for the TTS classes at the top of your file:

import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;

You also need to implement one more interface, so alter your class declaration outline to add “OnInitListener” as in the following example:

public class SpeakingAndroid extends Activity implements OnClickListener, OnInitListener

Remember to use your own class name. Again, your IDE will alert you to the fact that you haven’t yet implemented this interface but don’t worry, you will soon.


Step 7: Check for TTS Data

Your app needs to check that the user has the data necessary for the TTS function before you call its methods. Declare and instantiate the following instance variable at the top of your Activity class declaration, before the “onCreate” method:

private int MY_DATA_CHECK_CODE = 0;

Add the following import statement at the top of the class:

import android.content.Intent;

In the “onCreate” method, add the following:

Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);

This code creates a new Intent purely for the purposes of checking the user data. When the checking process is complete, the code will call the “onActivityResult” method.

Step 8: Create a TTS Instance

Declare an instance variable for your TTS object at the top of the class declaration, also before the “onCreate” method:

private TextToSpeech myTTS;

Add the “onActivityResult” to your class as follows:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (requestCode == MY_DATA_CHECK_CODE) {
		if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
			myTTS = new TextToSpeech(this, this);
		}
		else {
			Intent installTTSIntent = new Intent();
			installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
			startActivity(installTTSIntent);
		}
        }
}

When the data checking Intent completes, the app calls this method, passing it the “MY_DATA_CHECK_CODE” variable indicating whether or not the user has the TTS data installed. If the data is present, the code goes ahead and creates an instance of the TTS class. If the data is not present, the app will prompt the user to install it.


Step 9: Provide the onInit Method

Your class declaration is implementing “OnInitListener” so you must provide an “onInit” method. In this method, you can carry out any final set-up checks you need, as well as choosing settings for your TTS instance, such as language and locale options. Add the following import statement at the top of your class:

import java.util.Locale;

Add the “onInit” method to the class as follows:

public void onInit(int initStatus) {
	if (initStatus == TextToSpeech.SUCCESS) {
		myTTS.setLanguage(Locale.US);
	}
}

This code checks that the TTS resource is successfully instantiated, then sets a US English Locale for the speech operations. You can optionally output an error message for users if the TTS does not successfully instantiate by adding the following after the “if” block:

else if (initStatus == TextToSpeech.ERROR) {
	Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
}

If you use this code you will also need to import the Toast class by adding the following statement at the top of your file:

import android.widget.Toast;

Your app can carry out checks on the user device, such as available languages, as in the following extended version of the statement creating the TTS object inside the first conditional statement:

if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE) myTTS.setLanguage(Locale.US);

Step 10: Speak!

Finally, your app is ready to speak. Inside the “speakWords” method, add the following code:

myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);

There are lots of options here in terms of how your app handles speech. This code instructs the app to speak the text string immediately. If you want to add consecutive speech operations, you can instruct the app to wait until any current speech operations finish by adding your new speech item to a queue, as follows:

myTTS.speak(speech, TextToSpeech.QUEUE_ADD, null);
Speaking User Text

Once your class is finished with the TTS, you can optionally shut it down as follows:

myTTS.shutdown();

Don’t include this line if you want your users to be able to make the app speak more than once.


Conclusion

To see how all of these elements fit together, here is the complete class declaration:

import android.app.Activity;
import android.os.Bundle;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.view.View;
import android.widget.EditText;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.content.Intent;
import java.util.Locale;
import android.widget.Toast;
public class SpeakingAndroid extends Activity implements OnClickListener, OnInitListener {
		//TTS object
	private TextToSpeech myTTS;
		//status check code
	private int MY_DATA_CHECK_CODE = 0;
		//create the Activity
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
        		//get a reference to the button element listed in the XML layout
        	Button speakButton = (Button)findViewById(R.id.speak);
        		//listen for clicks
        	speakButton.setOnClickListener(this);
			//check for TTS data
	        Intent checkTTSIntent = new Intent();
	        checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
	        startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
	}
		//respond to button clicks
	public void onClick(View v) {
			//get the text entered
	    	EditText enteredText = (EditText)findViewById(R.id.enter);
	    	String words = enteredText.getText().toString();
	    	speakWords(words);
	}
		//speak the user text
	private void speakWords(String speech) {
			//speak straight away
	    	myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
	}
		//act on result of TTS data check
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == MY_DATA_CHECK_CODE) {
			if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
				//the user has the necessary data - create the TTS
			myTTS = new TextToSpeech(this, this);
			}
			else {
					//no data - install it now
				Intent installTTSIntent = new Intent();
				installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
				startActivity(installTTSIntent);
			}
		}
	}
		//setup TTS
	public void onInit(int initStatus) {
			//check for successful instantiation
		if (initStatus == TextToSpeech.SUCCESS) {
			if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE)
				myTTS.setLanguage(Locale.US);
		}
		else if (initStatus == TextToSpeech.ERROR) {
			Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
		}
	}
}

Remember to use your own class name and to indicate your application package at the top of the file. If you are using Eclipse, you should not need to add all of the import statements manually, as the IDE will insert some of them automatically. Run your app in the Android emulator and hear it in action.

This is a basic overview of implementing Text To Speech in your Android apps. The TTS resource provides a wide range of additional options you may want to explore depending on the nature of your apps. When calling the TextToSpeech object “speak” method for example, you can pass a HashMap object indicating the details of more complex playback options.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.akkis.gr Akkis

    Thank you! I will try it asap!

  • Trevor

    Thanks for the excellent tutorial, I wish I had found it earlier.

    I am trying to give the option to select the default engine to use – I have Pico TTS and SVOX Classic TTS installed and want to be able to switch between them.

    I would also like to select which voice to use in SVOX.

    I do not believe that the setEngineByPackageName call is working and I cannot seem to get returned a list of which engines are installed.

    Any help you could give me would be very much appreciated.

  • Ashimita

    Thanks Sue. It was indeed very useful and the article was very well documented. I have created the app following your instructions. Works like a charm. I used Google HTC (Gingerbread). :)

  • http://thibaultlavoisey.com Thibault

    Hi Sue,

    Thanks for this excellent tutorial !

    I have a question : how to add (if possible) a drop-down list to change the language ?

    I added a Spinner with differents languages and a if{}else if{}… which change the value of a Locale object depending the value of the Spinner but like the public void onInit() be called once, the language don’t change.

    have you an idea ?

    Thanks

    (sorry for my english I am a young frenchie ^^)

    • http://benormal.info/ Sue Smith (author)
      Author

      Hi Thibault

      You should be able to use the TTS setLanguage method (myTTS.setLanguage(Locale.US) in the code above) inside your if/ else blocks as long as your TTS object is a class variable (accessible throughout the class) as it is in the example code above.

      Hope that helps and thanks for the feedback.

  • Thilag

    Hi sue smith,

    i have one question, i’m trying your code but not able run whenever i’m running your code it will launching android market login page. why can you please help me on this.

    and one more your needs internet connection?.what your saying in your tutorial whatever we are writing on the Textbox it should read the text i’m right. if my understanding wrong please help me on this.

    Regards
    Thilag.

    • http://benormal.info/ Sue Smith (author)
      Author

      Hi Thilag

      It sounds like you don’t have the TTS data installed. As it says in the text above, users are prompted to install it if they don’t have it. Until you have the data the speech cannot occur and the device needs an Internet connection to download and install the data.

      Hope that helps.

  • divine

    hi Sue!

    Nice Tutorials..I had a question to ask..Is it possible to put TTS codes when tapping a marker in a map?
    Like this one:

    @Override
    protected boolean onTap(final int index) {
    tts.speak(“Landmark Indicator”, TextToSpeech.QUEUE_ADD, null);

    i tried this one but there is no output in my program..do u have an idea regarding this matter?

    Thanks in advance…

    • http://benormal.info/ Sue Smith (author)
      Author

      Hi Divine

      Thanks for the feedback. It’s difficult to say why your code isn’t working but if your class is not an Activity class it can be tricky to get TTS working. What you may need to do is instantiate the TTS in another class and pass it into the class with your onTap method in it. I’m not honestly sure whether that will help but it may be worth a try.

      • divine

        Hi Sue!

        yeah its pretty difficult because onTap method is under the itemizedOverlay class..and i also cant pass a method from the Activity class down to my itemizedOverlay class..T_T i tried different approach but no results at all..can u try it yourself and figure out what’s wrong?? that is if you have time..

        thanks for the reply anyway..

        sincerely,
        Divine

  • Steve

    Hi Sue,

    Thanks for the article – it’s really interesting :-).

    Do you know if anyone has made an Android app that does the text-to-speech function that you’ve shown … ? I’m looking for a ready-made app that I can download (e.g. from Android Market), rather than something that needs creating (because I don’t understand coding).

    For info, my partner’s father has very limited speech, due to a neurological disease. He can, however, use a keyboard, so we’ve been looking for a way in which he can type a word or sentence into a keyboard, and for it to be electronically read out. His partner bought him an accessibility keyboard (i.e. an all in one keyboard with basic software), but it doesn’t work very well – particularly because if you type the start of a word it doesn’t predict the rest of the word, and because it doesn’t correct typos.

    From my own use of my Android phone, I know that the default keyboard (e.g. when writing a text or email) is brilliant – it uses Google’s technology to predict the rest of a word from the first few letters and to correct typos. I also know that Google TalkBack can read out what’s on the screen (i.e. text-to-speech). However, TalkBack seems to be designed primarily for blind people, and therefore tends to read out everything on the screen (e.g. headings, menus, etc), which he doesn’t need. I figure that all he really needs is the following:

    1 – A decent tablet PC running Android.
    2 – Some form of notepad (or compose email) where he can write a sentence using the on-screen keyboard, and with the latter using Google’s technology to predict words, correct typos, etc.
    3 – A button that he can then press to read out the sentence he has just written.

    I’ve spent several hours looking for an app that does the above, and can’t really find anything. When I downloaded Google TalkBack it didn’t provide a button to read out what I wrote (it tended to just read out what was already on the screen, such as options and menus). There are plenty of apps that read out incoming texts and emails (e.g. when you’re driving) but none of these seem suitable. And there are some apps that allow you to type and read out what you’ve typed, but their keyboard doesn’t seem to use Google’s technology, so I’m guessing that the word prediction and correction is likely to be quite basic.

    Sorry for the long post, but I was wondering whether you’ve come across anything, or have any ideas … ?

    Thanks very much,
    Steve

  • Subbu

    Nice tutorial for leaners.i am very happy with your tutorial.i want to know how to create a default tts engine.please share your ideas.TTS engines means SVOX,eSpeak,pico engines.

  • Ajay Kumar

    Hello,
    This Apps is working fine in Emmulater but not able to run on Android Phone, so what shall I do for this to run on Phone(Mobile).
    Thanks
    Ajay

    • Subbu

      Hi Ajay, I tried this source code it is working on device also.you can download this source code again.

  • Anamaria

    Hello! thank you for your tutorial it was quite useful. Do you know what can I do to support JAPANESE? It seems this language is not supported if you do it like this. Maybe there is something else I’m missing? Thank you!

  • http://launchpad.net/TogAirAlpha Dan SeveNeLeVeN Evans

    I suggest you download SL4A_r5 & a stable Python Interpreter on an android device .
    You can see ttsSpeak in action here:
    https://launchpad.net/TogAirAlpha
    ALL required files as well as documentation can be found there.
    If content using emmulators, be sure you have all required files/data before attempting to use my Python3.2.2 Script or this tutorial posted by Sue.
    Thank you for the great read, keep on writing.

    • https://launchpad.net/TogAirAlpha Dan Seveneleven Evans

      I have also had fun with this tts driven python script:
      http://db.tt/RKfkOcHG
      It listens and speaks back to you whatever you say alloud.
      Hopefully these (Opensource) Scripts can give inspiration or help to others.

      Suggestions or Ideas for future python/android projects?
      LPTeam711@gmail.com

  • ret

    could you tell me why my “speak” button overlaps my textbox when I run it?

  • Asher

    Great Great post !!!
    Thank you sooo much :-)

  • Ali J

    Hi,

    Can you please show how to save the output(audio) of the TTS to a .wav OR .mp3 file on the sdcard so that it can be reused ? Please try and reply asap

    Thanks,
    Altamash

  • Akki

    Thanks… Its a great help for my Android Project…

  • Ankit

    thanks for the code and for explanation..

  • http://android9patch.blogspot.com Richard

    Just a quick question.

    I haven’t looked into TTS yet and was wondering if it would be possible to further process TTS audio before it get sent to the speaker(s)?

  • Hilson

    Really help for my project………………………
    thankz mobile tutsplus………….

  • http://www.facebook.com/rayidi999 Radhakrishna Rayidi

    Thanks for the help ! you are awesome….

  • madhu

    nice one

  • madhu

    hai iam new to andriod i need to get meesage from notfication bar display in new actvity pls help me thanks in advnce

  • anonymus

    good tut

  • Dani

    Great tut!