目前只支持5种语言,分别是English、 French 、 German 、 Italian 和 Spanish.
系统要求为android 1.6以上
直接上代码啦:
[java]
- public class TTSActivity extends Activity implements TextToSpeech.OnInitListener {
- private static final String TAG = "TextToSpeechDemo";
private TextToSpeech mTts;//首先来个对象,至于TextToSpeech类,按F3可以查看
[java]
- //TODO complete javadoc + add links to constants
- public class TextToSpeech {
- /**
- * Denotes a successful operation.
- */
- public static final int SUCCESS = 0;
- /**
- * Denotes a generic operation failure.
- */
- public static final int ERROR = -1;
以上只包含部分代码,其他的就省略了。
[java]
- mTts = new TextToSpeech(this,
- this // TextToSpeech.OnInitListener
- );
然后是实例化,构造函数参数也可以F3一下
[java]
- public TextToSpeech(Context context, OnInitListener listener) {
- mContext = context;
- mPackageName = mContext.getPackageName();
- mInitListener = listener;
- mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value
- mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE;
- mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE;
- mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY;
- mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT;
- mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM;
- mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID;
- mCachedParams[Engine.PARAM_POSITION_RATE + 1] =
- String.valueOf(Engine.DEFAULT_RATE);
- // initialize the language cached parameters with the current Locale
- Locale defaultLoc = Locale.getDefault();
- mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
- mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
- mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
- mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
- String.valueOf(Engine.DEFAULT_STREAM);
- mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
- initTts();
- }
context也就是那个Activity
[java]
- public abstract class Context {
- /**
- * File creation mode: the default mode, where the created file can only
- * be accessed by the calling application (or all applications sharing the
- * same user ID).
- * @see #MODE_WORLD_READABLE
- * @see #MODE_WORLD_WRITEABLE
- */
- public static final int MODE_PRIVATE = 0x0000;
- /**
- * File creation mode: allow all other applications to have read access
- * to the created file.
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_WRITEABLE
- */
- public static final int MODE_WORLD_READABLE = 0x0001;
- /**
- * File creation mode: allow all other applications to have write access
- * to the created file.
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_READABLE
- */
listener是个初始化监听接口
[java]
- /**
- * Called when the TTS has initialized.
- *
- * The InitListener must implement the onInit function. onInit is passed a
- * status code indicating the result of the TTS initialization.
- */
- public interface OnInitListener {
- public void onInit(int status);
- }
implements Listener代码如下:(这是APIDemo里面的)
[java]
- // Implements TextToSpeech.OnInitListener.
- public void onInit(int status) {
- // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
- if (status == TextToSpeech.SUCCESS) {
- // Set preferred language to US english.
- // Note that a language may not be available, and the result will indicate this.
- int result = mTts.setLanguage(Locale.US);
- // Try this someday for some interesting results.
- // int result mTts.setLanguage(Locale.FRANCE);
- if (result == TextToSpeech.LANG_MISSING_DATA ||
- result == TextToSpeech.LANG_NOT_SUPPORTED) {
- // Lanuage data is missing or the language is not supported.
- Log.e(TAG, "Language is not available.");
- } else {
- // Check the documentation for other possible result codes.
- // For example, the language may be available for the locale,
- // but not for the specified country and variant.
- // The TTS engine has been successfully initialized.
- // Allow the user to press the button for the app to speak again.
- mAgainButton.setEnabled(true);
- // Greet the user.
- sayHello();
- }
- } else {
- // Initialization failed.
- Log.e(TAG, "Could not initialize TextToSpeech.");
- }
- }
status这个在构造函数中赋值,(Ctrl+F可以在源码中找到)
[java]
- mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
- String.valueOf(Engine.DEFAULT_STREAM);
- mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
- initTts();//构造函数最后这个地方
- }
- private void initTts() {
- mStarted = false;
- // Initialize the TTS, run the callback after the binding is successful
- mServiceConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized(mStartLock) {
- mITts = ITts.Stub.asInterface(service);
- mStarted = true;
- if (mInitListener != null) {
- // TODO manage failures and missing resources
- mInitListener.onInit(SUCCESS);//这里给status赋值
- }
- }
- }
setLanguage方法源码:
[java]
- public int setLanguage(Locale loc) {
- synchronized (mStartLock) {
- int result = LANG_NOT_SUPPORTED;
- if (!mStarted) {
- return result;
- }
- try {
- mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
- mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
- mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant();
- // the language is not set here, instead it is cached so it will be associated
- // with all upcoming utterances. But we still need to report the language support,
- // which is achieved by calling isLanguageAvailable()
- result = mITts.isLanguageAvailable(
- mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
- mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
- mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] );
- } catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - setLanguage", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
- }
- }
- }
Locale.US定义如下:
[java]
- public static final Locale UK = new Locale("en", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
- /**
- * Locale constant for en_US.
- *
- * @since Android 1.0
- */
- public static final Locale US = new Locale("en", "US"); //$NON-NLS-1$//$NON-NLS-2$
Locale构造器源码:
[java] view plaincopy
<EMBED id=ZeroClipboardMovie_11 name=ZeroClipboardMovie_11 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=11&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">
- /**
- * Constructs a new {@code Locale} using the specified language and country codes.
- *
- * @param language
- * the language this {@code Locale} represents.
- * @param country
- * the country this {@code Locale} represents.
- * @since Android 1.0
- */
- public Locale(String language, String country) {
- this(language, country, ""); //$NON-NLS-1$
- }
这里每按一次按钮就有一个Speech
[java]
- private void sayHello() {
- String left = "Please turn left";
- String right="Please turn right";
- if(mDirection==0){
- mTts.speak(left,
- TextToSpeech.QUEUE_FLUSH, // Drop all pending entries in the playback queue.
- null);
- mDirection=1;
- }else{
- mTts.speak(right, TextToSpeech.QUEUE_FLUSH, null);
- mDirection=0;
- }
speak函数源码:各参数都有相应的解释,我就不啰嗦了
[java]
- /**
- * Speaks the string using the specified queuing strategy and speech
- * parameters. Note that the speech parameters are not universally supported
- * by all engines and will be treated as a hint. The TTS library will try to
- * fulfill these parameters as much as possible, but there is no guarantee
- * that the voice used will have the properties specified.
- *
- * @param text
- * The string of text to be spoken.
- * @param queueMode
- * The queuing strategy to use.
- * See QUEUE_ADD and QUEUE_FLUSH.
- * @param params
- * The hashmap of speech parameters to be used.
- *
- * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
- */
- public int speak(String text, int queueMode, HashMap<String,String> params)
- {
- synchronized (mStartLock) {
- int result = ERROR;
- Log.i("TTS received: ", text);
- if (!mStarted) {
- return result;
- }
- try {
- if ((params != null) && (!params.isEmpty())) {
- String extra = params.get(Engine.KEY_PARAM_STREAM);
- if (extra != null) {
- mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
- }
- extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
- if (extra != null) {
- mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
- }
- }
- result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
- } catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - speak", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- resetCachedParams();
- return result;
- }
- }
- }
还有在Activity退出时作一些操作
[java]
- @Override
- public void onDestroy() {
- // Don‘t forget to shutdown!
- if (mTts != null) {
- mTts.stop();
- mTts.shutdown();
- }
- super.onDestroy();
- }
能看到源码真好...深入学习...呵呵
我们再看下android 到底是怎样stop和shutdown的
[java] view plaincopy
<EMBED id=ZeroClipboardMovie_15 name=ZeroClipboardMovie_15 type=application/x-shockwave-flash align=middle pluginspage=http://www.macromedia.com/go/getflashplayer height=18 width=18 src=http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf wmode="transparent" flashvars="id=15&width=18&height=18" allowfullscreen="false" allowscriptaccess="always" bgcolor="#ffffff" quality="best" menu="false" loop="false">
- /**
- * Stops speech from the TTS.
- *
- * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
- */
- public int stop() {
- synchronized (mStartLock) {
- int result = ERROR;
- if (!mStarted) {
- return result;
- }
- try {
- result = mITts.stop(mPackageName);
- } catch (RemoteException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "RemoteException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (NullPointerException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "NullPointerException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } catch (IllegalStateException e) {
- // TTS died; restart it.
- Log.e("TextToSpeech.java - stop", "IllegalStateException");
- e.printStackTrace();
- mStarted = false;
- initTts();
- } finally {
- return result;
- }
- }
- }
还有shutdown函数:
[java]
- /**
- * Shuts down the TTS. It is good practice to call this in the onDestroy
- * method of the Activity that is using the TTS so that the TTS is stopped
- * cleanly.
- */
- public void shutdown() {
- try {
- mContext.unbindService(mServiceConnection);
- } catch (IllegalArgumentException e) {
- // Do nothing and fail silently since an error here indicates that
- // binding never succeeded in the first place.
- }
- }
还有Activity的destroy函数:
[java]
- /**
- * Perform any final cleanup before an activity is destroyed. This can
- * happen either because the activity is finishing (someone called
- * {@link #finish} on it, or because the system is temporarily destroying
- * this instance of the activity to save space. You can distinguish
- * between these two scenarios with the {@link #isFinishing} method.
- *
- * <p><em>Note: do not count on this method being called as a place for
- * saving data! For example, if an activity is editing data in a content
- * provider, those edits should be committed in either {@link #onPause} or
- * {@link #onSaveInstanceState}, not here.</em> This method is usually implemented to
- * free resources like threads that are associated with an activity, so
- * that a destroyed activity does not leave such things around while the
- * rest of its application is still running. There are situations where
- * the system will simply kill the activity‘s hosting process without
- * calling this method (or any others) in it, so it should not be used to
- * do things that are intended to remain around after the process goes
- * away.
- *
- * <p><em>Derived classes must call through to the super class‘s
- * implementation of this method. If they do not, an exception will be
- * thrown.</em></p>
- *
- * @see #onPause
- * @see #onStop
- * @see #finish
- * @see #isFinishing
- */
- protected void onDestroy() {
- mCalled = true;
- // dismiss any dialogs we are managing.
- if (mManagedDialogs != null) {
- final int numDialogs = mManagedDialogs.size();
- for (int i = 0; i < numDialogs; i++) {
- final Dialog dialog = mManagedDialogs.valueAt(i);
- if (dialog.isShowing()) {
- dialog.dismiss();
- }
- }
- }
- // close any cursors we are managing.
- int numCursors = mManagedCursors.size();
- for (int i = 0; i < numCursors; i++) {
- ManagedCursor c = mManagedCursors.get(i);
- if (c != null) {
- c.mCursor.close();
- }
- }
- }
好了,这个TTS就到这里。
至于现在到底是否支持中文发音这个我还没调查过。实在不行的话我们就做English版的软件也不错,单词发音,语音导航等等都是可以运用TTS的。
还有再唠叨一下,最近居然看到源码了,爽YY呀。感觉这一步就像是从了解一个人的表面到了解其本质...从上到下,从外到内...