一. 简单介绍
在上一篇里
我们讲到了TTS 最主要的一个API
public int speak ( String text, int queueMode, HashMap < String , String > params)
其中我们介绍了前两个参数,第三个参数设置了null
而且我们在介绍Android TTS 提供的功能时,说到TTS 提供了两个接口,第一个初始化接口OnInitListener 我们已经使用过了,而第二个接口OnUtteranceCompletedListener 我们还没有使用到。
首先我们就来简单介绍一下这个接口的使用方式。TTS 引擎进行语音合成的每个语音片段叫做"utterance ", 而且在送给speak 函数进行语音合成时,可以为这次的语音片段"utterance "设置一个ID 。OnUtteranceCompletedListener 这个接口里定义了一个回调函数,当设置了ID 的语音片段"utterance " 语音合成结束后就会调用这个回调函数。然后我们就可以在这回调函数里进行我们需要的操作,比如在某个特定ID
Demo
二. 实例分析
我们希望做的效果如下:
图1 实现效果图
在界面上体现不出这个Demo 的特点,除了一长串英文的爱的表白外,还有一个Speak 按钮。但当点击了Speak
创建一个Android 工程,工程名为AndroidTTSDemoThird, 其中SDK 必须选择1.6
其中Main.xml
[xhtml] view plain copy
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent"
6. >
7. <EditText android:id="@+id/inputText"
8. android:hint="Input the text here!"
9. android:layout_width="fill_parent"
10. android:layout_height="wrap_content">
11. </EditText>
12. <Button android:text="Speak"
13. android:id="@+id/speakBtn"
14. android:layout_width="wrap_content"
15. android:layout_height="wrap_content"
16. android:layout_gravity="center_horizontal"
17. android:enabled="false"
18. ></Button>
19.
20. </LinearLayout>
Java
这次要实现 OnInitListener 和 OnUtteranceCompletedListener 两个接口
[java] view plain copy
1. public class AndroidTTSDemoThird extends Activity implements OnInitListener, OnUtteranceCompletedListener{
2. /** Called when the activity is first created. */
3. @Override
4. public void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.main);
7. }
8.
9. @Override
10. public void onInit(int status) {
11. // TODO Auto-generated method stub
12. //TTS Engine初始化完成
13.
14. }
15. @Override
16. public void onUtteranceCompleted(String utteranceId) {
17. // TODO Auto-generated method stub
18. //一个语音片段结束后的回调函数
19.
20. }
21. }
接着定义好下面要用到的几个变量:
[java] view plain copy
1. //定义变量
2. private EditText inputText = null;
3. private Button speakBtn = null;
4. private TextToSpeech mTts;
5. private static final String TAG = "TTS Demo";
6. private static final String STORE_NAME = "preferenceFile";
7. private static final String loveConfession = "You complete me. You had me at hello, you had me at hello. To the world you maybe one person, but to one person you maybe the world. Please believe me, I was prepared for everything,except you. I love that you are the last person I want to talk to before I go to sleep at night. Love means never having to say you're sorry. So choose me. Marry me. Let me make you happy. ";
8. private String[] loveArray;
9. private int lastUtterance = -1;
10. private HashMap<String, String> params = new HashMap<String, String>();
因为通过前面的两个 Demo ,我们知道已经安装了 TTS 需要的数据,因此这里我们可以在onCreate 函数中直接创建一个 TextToSpeech
[java] view plain copy
1. //创建TextToSpeech实例,初始化完成后会调用OnInitListener(第二个参数)的回调函数
2. mTts = new TextToSpeech(this,
3. this // TextToSpeech.OnInitListener
4. );
成功创建一个 TextToSpeech 后,就会调用接口 OnInitListener
[java] view plain copy
1. @Override
2. public void onInit(int status) {
3. // TODO Auto-generated method stub
4. //TTS Engine初始化完成
5. if(status == TextToSpeech.SUCCESS)
6. {
7. int result = mTts.setLanguage(Locale.US);
8. //设置发音语言
9. if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
10. //判断语言是否可用
11. {
12. "Language is not available");
13. false);
14. }
15. else
16. {
17. true);
18. //设置一个语音片段结束后的回调函数
19. this);
20. }
21. }
22. }
和前面的 Demo 相比,这里多了一句 mTts .setOnUtteranceCompletedListener( this);
就是设置语音片段结束后的回调函数。
接着在 onCreate 函数中设置 EditText和 Button
[java] view plain copy
1. //设置控件
2. inputText = (EditText)findViewById(R.id.inputText);
3. speakBtn = (Button)findViewById(R.id.speakBtn);
4.
5. inputText.setText(loveConfession);
6. new OnClickListener() {
7. public void onClick(View v) {
8. // TODO Auto-generated method stub
9. //处理输入框里的内容
10. new StringTokenizer(inputText.getText().toString(),",.");
11. int i = 0;
12. new String[loveTokens.countTokens()];
13. while(loveTokens.hasMoreTokens())
14. {
15. loveArray[i++] = loveTokens.nextToken();
16. }
17. //朗读输入框里的内容
18. speakText();
19. }
20. });
在 SpeakBtn 的 onClick 事件中,先把输入框中的内容按 ',' 和 '.' 分割成一个个短的部分并保存在字符串数组中,然后调用我们写的 speakText()
speakText()
[java] view plain copy
1. private void speakText()
2. {
3. lastUtterance++;
4. if(lastUtterance >= loveArray.length)
5. {
6. 0;
7. }
8. "the begin utterance is " + lastUtterance);
9. for(int i = lastUtterance; i < loveArray.length; i++)
10. {
11. //为每个语音片段都设置一个标记
12. params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(i));
13. mTts.speak(loveArray[i], TextToSpeech.QUEUE_ADD, params);
14. }
15. }
lastUtterance 变量保存上一个语音片段的 ID , params 是 HashMap<String, String> 类型,键值对形式的变量,在这里我们的键 name 为 TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,是一个 UTTERANCE_ID ,值 value 为 String.valueOf(i) ,其实只要是任何字符串变量都行,为了方便我们设置的为有顺序的数字。然后把这个键值对变量添加给 speak 函数, TTS 引擎就会在这个语音片段朗读结束后通知我们,调用设置好的回调函数 onUtteranceCompleted(String utteranceId)
[java] view plain copy
1. @Override
2. public void onUtteranceCompleted(String utteranceId) {
3. // TODO Auto-generated method stub
4. //一个语音片段结束后的回调函数
5. "Get completed message for the utteranceId " + utteranceId);
6. //用lastUtterance记录当前结束的语音片段
7. lastUtterance = Integer.parseInt(utteranceId);
8. }
很简单,主要就是把当前刚结束的这个语音片段 ID--utteranceId 保存到 lastUtterance
[java] view plain copy
1. @Override
2. protected void onDestroy() {
3. // TODO Auto-generated method stub
4. //释放TTS的资源
5. if(mTts != null)
6. {
7. mTts.stop();
8. mTts.shutdown();
9. }
10. //保存lastUtterance值
11. 0);
12. SharedPreferences.Editor editor = settings.edit();
13. "lastUtterance", lastUtterance);
14. editor.commit();
15. "the stored lastUtterance is " + lastUtterance);
16.
17. super.onDestroy();
18. }
首先是释放 TTS 资源,然后把 lastUtterance 变量的值以键值对的方式保存在系统中,这样下次启动程序时 lastUtterance 就可以从系统中读取上次退出时保存的值。在 onCreate 函数中添加获取保存的 lastUtterance
[java] view plain copy
1. //获得保存的lastUtterance值
2. SharedPreferences settings = getSharedPreferences(STORE_NAME, 0);
3. lastUtterance = settings.getInt("lastUtterance", -1);
4. Log.v(TAG, "the restored lastUtterance is " + lastUtterance);
至此,这个 Demo 完成了,运行后点击 Speak 按钮会朗读文本框中的经典的爱的表白,一小段一小段朗读,每朗读完一小段程序都会调用回调函数 onUtteranceCompleted 记录刚朗读完的那个小段的 ID ,当所有的表白没朗读完就按返回退出程序时,程序在 onDestroy() 里把记录着的片段 ID保存在系统中,这样下次再次打开程序时就可以接着上次继续这爱的表白。
注:文章参加“ 首届Google暑期大学生博客分享大赛——2010 Andriod篇”
分享到:
一. 简单介绍
在上一篇里
我们讲到了TTS 最主要的一个API
public int speak ( String text, int queueMode, HashMap < String , String > params)
其中我们介绍了前两个参数,第三个参数设置了null
而且我们在介绍Android TTS 提供的功能时,说到TTS 提供了两个接口,第一个初始化接口OnInitListener 我们已经使用过了,而第二个接口OnUtteranceCompletedListener 我们还没有使用到。
首先我们就来简单介绍一下这个接口的使用方式。TTS 引擎进行语音合成的每个语音片段叫做"utterance ", 而且在送给speak 函数进行语音合成时,可以为这次的语音片段"utterance "设置一个ID 。OnUtteranceCompletedListener 这个接口里定义了一个回调函数,当设置了ID 的语音片段"utterance " 语音合成结束后就会调用这个回调函数。然后我们就可以在这回调函数里进行我们需要的操作,比如在某个特定ID
Demo
二. 实例分析
我们希望做的效果如下:
图1 实现效果图
在界面上体现不出这个Demo 的特点,除了一长串英文的爱的表白外,还有一个Speak 按钮。但当点击了Speak
创建一个Android 工程,工程名为AndroidTTSDemoThird, 其中SDK 必须选择1.6
其中Main.xml
[xhtml] view plain copy
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent"
6. >
7. <EditText android:id="@+id/inputText"
8. android:hint="Input the text here!"
9. android:layout_width="fill_parent"
10. android:layout_height="wrap_content">
11. </EditText>
12. <Button android:text="Speak"
13. android:id="@+id/speakBtn"
14. android:layout_width="wrap_content"
15. android:layout_height="wrap_content"
16. android:layout_gravity="center_horizontal"
17. android:enabled="false"
18. ></Button>
19.
20. </LinearLayout>
Java
这次要实现 OnInitListener 和 OnUtteranceCompletedListener 两个接口
[java]
view plain
copy
1. public class AndroidTTSDemoThird extends Activity implements OnInitListener, OnUtteranceCompletedListener{
2. /** Called when the activity is first created. */
3. @Override
4. public void onCreate(Bundle savedInstanceState) {
5. super.onCreate(savedInstanceState);
6. setContentView(R.layout.main);
7. }
8.
9. @Override
10. public void onInit(int status) {
11. // TODO Auto-generated method stub
12. //TTS Engine初始化完成
13.
14. }
15. @Override
16. public void onUtteranceCompleted(String utteranceId) {
17. // TODO Auto-generated method stub
18. //一个语音片段结束后的回调函数
19.
20. }
21. }
接着定义好下面要用到的几个变量:
[java]
view plain
copy
1. //定义变量
2. private EditText inputText = null;
3. private Button speakBtn = null;
4. private TextToSpeech mTts;
5. private static final String TAG = "TTS Demo";
6. private static final String STORE_NAME = "preferenceFile";
7. private static final String loveConfession = "You complete me. You had me at hello, you had me at hello. To the world you maybe one person, but to one person you maybe the world. Please believe me, I was prepared for everything,except you. I love that you are the last person I want to talk to before I go to sleep at night. Love means never having to say you're sorry. So choose me. Marry me. Let me make you happy. ";
8. private String[] loveArray;
9. private int lastUtterance = -1;
10. private HashMap<String, String> params = new HashMap<String, String>();
因为通过前面的两个 Demo ,我们知道已经安装了 TTS 需要的数据,因此这里我们可以在onCreate 函数中直接创建一个 TextToSpeech
[java] view plain copy
1. //创建TextToSpeech实例,初始化完成后会调用OnInitListener(第二个参数)的回调函数
2. mTts = new TextToSpeech(this,
3. this // TextToSpeech.OnInitListener
4. );
成功创建一个 TextToSpeech 后,就会调用接口 OnInitListener
[java] view plain copy
1. @Override
2. public void onInit(int status) {
3. // TODO Auto-generated method stub
4. //TTS Engine初始化完成
5. if(status == TextToSpeech.SUCCESS)
6. {
7. int result = mTts.setLanguage(Locale.US);
8. //设置发音语言
9. if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
10. //判断语言是否可用
11. {
12. "Language is not available");
13. false);
14. }
15. else
16. {
17. true);
18. //设置一个语音片段结束后的回调函数
19. this);
20. }
21. }
22. }
和前面的 Demo 相比,这里多了一句 mTts .setOnUtteranceCompletedListener( this);
就是设置语音片段结束后的回调函数。
接着在 onCreate 函数中设置 EditText和 Button
[java] view plain copy
1. //设置控件
2. inputText = (EditText)findViewById(R.id.inputText);
3. speakBtn = (Button)findViewById(R.id.speakBtn);
4.
5. inputText.setText(loveConfession);
6. new OnClickListener() {
7. public void onClick(View v) {
8. // TODO Auto-generated method stub
9. //处理输入框里的内容
10. new StringTokenizer(inputText.getText().toString(),",.");
11. int i = 0;
12. new String[loveTokens.countTokens()];
13. while(loveTokens.hasMoreTokens())
14. {
15. loveArray[i++] = loveTokens.nextToken();
16. }
17. //朗读输入框里的内容
18. speakText();
19. }
20. });
在 SpeakBtn 的 onClick 事件中,先把输入框中的内容按 ',' 和 '.' 分割成一个个短的部分并保存在字符串数组中,然后调用我们写的 speakText()
speakText()
[java] view plain copy
1. private void speakText()
2. {
3. lastUtterance++;
4. if(lastUtterance >= loveArray.length)
5. {
6. 0;
7. }
8. "the begin utterance is " + lastUtterance);
9. for(int i = lastUtterance; i < loveArray.length; i++)
10. {
11. //为每个语音片段都设置一个标记
12. params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.valueOf(i));
13. mTts.speak(loveArray[i], TextToSpeech.QUEUE_ADD, params);
14. }
15. }
lastUtterance 变量保存上一个语音片段的 ID , params 是 HashMap<String, String> 类型,键值对形式的变量,在这里我们的键 name 为 TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,是一个 UTTERANCE_ID ,值 value 为 String.valueOf(i) ,其实只要是任何字符串变量都行,为了方便我们设置的为有顺序的数字。然后把这个键值对变量添加给 speak 函数, TTS 引擎就会在这个语音片段朗读结束后通知我们,调用设置好的回调函数 onUtteranceCompleted(String utteranceId)
[java] view plain copy
1. @Override
2. public void onUtteranceCompleted(String utteranceId) {
3. // TODO Auto-generated method stub
4. //一个语音片段结束后的回调函数
5. "Get completed message for the utteranceId " + utteranceId);
6. //用lastUtterance记录当前结束的语音片段
7. lastUtterance = Integer.parseInt(utteranceId);
8. }
很简单,主要就是把当前刚结束的这个语音片段 ID--utteranceId 保存到 lastUtterance
[java] view plain copy
1. @Override
2. protected void onDestroy() {
3. // TODO Auto-generated method stub
4. //释放TTS的资源
5. if(mTts != null)
6. {
7. mTts.stop();
8. mTts.shutdown();
9. }
10. //保存lastUtterance值
11. 0);
12. SharedPreferences.Editor editor = settings.edit();
13. "lastUtterance", lastUtterance);
14. editor.commit();
15. "the stored lastUtterance is " + lastUtterance);
16.
17. super.onDestroy();
18. }
首先是释放 TTS 资源,然后把 lastUtterance 变量的值以键值对的方式保存在系统中,这样下次启动程序时 lastUtterance 就可以从系统中读取上次退出时保存的值。在 onCreate 函数中添加获取保存的 lastUtterance
[java] view plain copy
1. //获得保存的lastUtterance值
2. SharedPreferences settings = getSharedPreferences(STORE_NAME, 0);
3. lastUtterance = settings.getInt("lastUtterance", -1);
4. Log.v(TAG, "the restored lastUtterance is " + lastUtterance);
至此,这个 Demo 完成了,运行后点击 Speak 按钮会朗读文本框中的经典的爱的表白,一小段一小段朗读,每朗读完一小段程序都会调用回调函数 onUtteranceCompleted 记录刚朗读完的那个小段的 ID ,当所有的表白没朗读完就按返回退出程序时,程序在 onDestroy() 里把记录着的片段 ID保存在系统中,这样下次再次打开程序时就可以接着上次继续这爱的表白。