一.
简单介绍
在上一篇里
http://blog.csdn.net/ichliebephone/archive/2010/08/10/5802044.aspx
我们简单的介绍了Android里的TTS功能并实现了一个最简单的Demo例子--AndroidTTSDemoFirst,在这篇文章中我们将具体介绍用到的TTS API,并给上一个Demo增加语言选择功能,可以使用TTS引擎支持的
English、
French
、
German
、
Italian
和
Spanish
这
5大语言来进行相应的语音合成,并用这
5
种外语向她说出“我爱你”。
二.
实例分析
我们希望做的效果如下:
图1 实现效果图
有了上一个例子做基础,这个Demo比较好实现,主要是增加了一个语言选择的控件Spinner,选择不同的语言,就会用对应的语言表达“我爱你”。
接下来就边实现这个Demo边讲解用到的TTS API。也是先创建一个Android工程,工程名为AndroidTTSDemoSecond,其中SDK必须选择1.6版本及以上。
其中Main.xml文件也还是很简单,在前一个AndroidTTSDemoFirst例子的基础上增加了一个Spinner控件,
如下所示:
Java文件的编写:
因为这个Demo例子只是在上一个AndroidTTSDemoFirst基础上的增加,因此可以使用上一个编写的java文件,只要把class名字改为AndroidTTSDemoSecond,如下所示:
//检查TTS数据是否已经安装并且可用
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, REQ_TTS_STATUS_CHECK);
inputText = (EditText)findViewById(R.id.inputText);
speakBtn = (Button)findViewById(R.id.speakBtn);
inputText.setText("This is an example of speech synthesis.");
speakBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mTts.speak(inputText.getText().toString(), TextToSpeech.QUEUE_ADD, null);
//朗读输入框里的内容
}
});
}
//实现TTS初始化接口
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
//TTS Engine初始化完成
if(status == TextToSpeech.SUCCESS)
{
int result = mTts.setLanguage(Locale.US);
//设置发音语言
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
//判断语言是否可用
{
Log.v(TAG, "Language is not available");
speakBtn.setEnabled(false);
}
else
{
mTts.speak("This is an example of speech synthesis.", TextToSpeech.QUEUE_ADD, null);
speakBtn.setEnabled(true);
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQ_TTS_STATUS_CHECK)
{
switch (resultCode) {
case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
//这个返回结果表明TTS Engine可以用
{
mTts = new TextToSpeech(this, this);
Log.v(TAG, "TTS Engine is installed!");
}
break;
case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
//需要的语音数据已损坏
case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
//缺少需要语言的语音数据
case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
//缺少需要语言的发音数据
{
//这三种情况都表明数据有错,重新下载安装需要的数据
Log.v(TAG, "Need language stuff:"+resultCode);
Intent dataIntent = new Intent();
dataIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(dataIntent);
}
break;
case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
//检查失败
default:
Log.v(TAG, "Got a failure. TTS apparently not available");
break;
}
}
else
{
//其他Intent返回的结果
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(mTts != null)
//activity暂停时也停止TTS
{
mTts.stop();
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//释放TTS的资源
mTts.shutdown();
}
}
下面简单介绍下上面代码中和TTS相关的一些API使用。
首先是实现
OnInitListener
这个接口,这个接口中只有一个抽象函数
void
onInit(
int
status)
,在
TextToSpeech
引擎初始化完成后调用,在这个函数里就可以根据状态
status(为
TextToSpeech.SUCCESS
或者
TextToSpeech.
Error
)判断TTS
初始化成功与否进行相应的操作。
接着在使用TTS
时,会先启动一个
Activity
检查
TTS
引擎需要的
TTS
数据是否已经安装并且可用,
checkIntent.
setAction
(
TextToSpeech
.Engine.
ACTION_CHECK_TTS_DATA
);
这个
Activity会返回如下结果之一:
CHECK_VOICE_DATA_PASS
,
CHECK_VOICE_DATA_FAIL
,
CHECK_VOICE_DATA_BAD_DATA
,
CHECK_VOICE_DATA_MISSING_DATA
,
或者
CHECK_VOICE_DATA_MISSING_VOLUME
.
只有第一个结果
CHECK_VOICE_DATA_PASS
表明
TTS数据可用,其他都是数据不可用的结果,可以启动一个
Activity
去安装需要的
TTS
数据,
dataIntent.setAction(TextToSpeech.Engine.
ACTION_INSTALL_TTS_DATA
);
当数据可用时,就可以创建一个TextToSpeech
实例,
public TextToSpeech (
Context
context,
TextToSpeech.OnInitListener
listener)
这里需要两个参数,一个是
TTS
实例运行的
Context;
另一个是初始化接口的实现,在实例的创建过程中,如果TTS
引擎没有运行的话,则会初始化
TTS
引擎,并且在初始化完成后调用其第二个参数
listener
。
有了
TextToSpeech实例,接下来就可以对文本进行语音合成并发音了,对应的
API为
public int speak (
String
text, int queueMode,
HashMap
<
String
,
String
> params)
这里需要三个参数,第一个为要合成的文本;
第二个为使用
TTS队列的方式,因为使用TTS合成语音时需要时间,TTS引擎就会把还没有轮到的部分放在其队列中排队,后来的内容有两种使用队列的方式:
QUEUE_ADD
或者
QUEUE_FLUSH
,
QUEUE_ADD
表示把当前需要合成的内容添加到
TTS队列的后面,等前面的都完成了后再轮到他,
QUEUE_FLUSH
表示清除队列中原有的内容,直接使
TTS引擎对当前内容进行语音合成,一般来说适合比较紧急的情况使用,但因为在
Android
中可能不止你一个程序使用
TTS
引擎,因此为了不破坏其他人的数据,建议使用
QUEUE_ADD
参数;
第三个为键值对表示的一个参数,我们后面再来介绍,目前可以使其为
null
。
前半部分简单的介绍了前一个Demo
用到的
API
,下半部分添加这个
Demo
中新的语言选择部分。
首先为
Spinner
控件
新增加两个变量,
接着添加
Spinner
的使用,
inputText.setText("I love you");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
langSelect.setAdapter(adapter);
langSelect.setSelection(0);
和TTS
相关的部分是
Spinner
控件的
item selected事件的处理,
break;
case 1:
{
inputText.setText("Je t'aime");
result = mTts.setLanguage(Locale.FRENCH);
}
break;
case 2:
{
inputText.setText("Ich liebe dich");
result = mTts.setLanguage(Locale.GERMAN);
}
break;
case 3:
{
inputText.setText("Ti amo");
result = mTts.setLanguage(Locale.ITALIAN);
}
break;
case 4:
{
inputText.setText("Te quiero");
result = mTts.setLanguage(new Locale("spa", "ESP"));
}
break;
default:
break;
}
//设置发音语言
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED)
//判断语言是否可用
{
Log.v(TAG, "Language is not available");
speakBtn.setEnabled(false);
}
else
{
speakBtn.setEnabled(true);
}
}
public void onNothingSelected(AdapterView<?> arg) {
// TODO Auto-generated method stub
}
});
在选择不同的
item时,为
inputText
设置不同语言“我爱你”对应的文本,并且为
TTS实例设置语言。
为TTS
引擎设置语言的
API
为
public int setLanguage (
Locale
loc)
;
使用Locale
这个表示语言及国家区域的类来设置语言,目前支持
English、
French
、
German
、
Italian
和
Spanish
这
5大语言,
返回的结果为
LANG_AVAILABLE
,
LANG_COUNTRY_AVAILABLE
,
LANG_COUNTRY_VAR_AVAILABLE
,
LANG_MISSING_DATA
和
LANG_NOT_SUPPORTED
。其中
LANG_MISSING_DATA
和
LANG_NOT_SUPPORTED
表示无法使用当前进行设置的语言,另外的几个表示设置的语言有效。
至此,增加了语言选择的新的Demo
完成了,程序运行后可以选择不同的语言说出“我爱你”,简单效果图如下所示:
图2
简单效果图
文章对应的完整代码例子可以在这里下载:
http://download.csdn.net/source/2611687
注:文章参加“
首届Google暑期大学生博客分享大赛——2010 Andriod篇”