目前只支持5種語言,分別是English、 French 、 German 、 Italian 和 Spanish.java
系統要求爲android 1.6以上android
直接上代碼啦:ios
[java] web
public class TTSActivity extends Activity implements TextToSpeech.OnInitListener { app
private static final String TAG = "TextToSpeechDemo"; ide
private TextToSpeech mTts;//首先來個對象,至於TextToSpeech類,按F3能夠查看函數
[java] oop
//TODO complete javadoc + add links to constants 學習
public class TextToSpeech { ui
/**
* 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呀。感受這一步就像是從瞭解一我的的表面到了解其本質...從上到下,從外到內...