Android车机之TextToSpeech
一、引言
TextToSpeech将一段文字转换为语音。TextToSpeech是Android系统自带的类,不用导入别的包。
客户端调用步骤:
- new TextToSpeech类
- 初始化TextToSpeech引擎,即重写onInit()方法
- 设置朗读参数,调用朗读方法speak()
- 销毁TextToSpeech,调用stop()和shutdown()方法
二、需求
系统集成了第三方应用,第三方应用需要调用原生TextToSpeech进行文字播报。
三、分析
系统集成了第三方语音引擎,目前行业较多使用讯飞语音,其他包括腾讯、同行者等。均可通过第三方语音提供的接口实现TTS播报。故考虑将原生TextToSpeech接口适配,供第三方应用使用。
四、实现
(1)服务端
语音中间件实现TextToSpeechService抽象类,主要是设置当前支持语言,及调用第三方语音引擎进行TTS播报。
// MyTextToSpeechService.java
package com.example.testapplication;
import android.content.Intent;
import android.speech.tts.SynthesisCallback;
import android.speech.tts.SynthesisRequest;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeechService;
import android.text.TextUtils;
import android.util.Log;
import java.util.Locale;
public class MyTextToSpeechService extends TextToSpeechService {
private static final String TAG = "MyTextToSpeechService";
@Override
protected int onIsLanguageAvailable(String lang, String country, String variant) {
Log.w(TAG, "onIsLanguageAvailable lang= " + lang
+ ",country= " + country + ", variant= " + variant);
if(Locale.US.getISO3Language().equals(lang)
|| Locale.CHINA.getISO3Language().equals(lang)) {
Log.w(TAG, "onIsLanguageAvailable LANG_COUNTRY_AVAILABLE");
return TextToSpeech.LANG_COUNTRY_AVAILABLE;
}
Log.w(TAG, "onIsLanguageAvailable LANG_NOT_SUPPORTED");
return TextToSpeech.LANG_NOT_SUPPORTED;
}
@Override
protected String[] onGetLanguage() {
return new String[0];
}
@Override
protected int onLoadLanguage(String lang, String country, String variant) {
Log.w(TAG, "onLoadLanguage lang= " + lang
+ ",country= " + country + ", variant= " + variant);
if(Locale.US.getISO3Language().equals(lang)
|| Locale.CHINA.getISO3Language().equals(lang)) {
Log.w(TAG, "onLoadLanguage LANG_COUNTRY_AVAILABLE");
return TextToSpeech.LANG_COUNTRY_AVAILABLE;
}
Log.w(TAG, "onLoadLanguage LANG_NOT_SUPPORTED");
return TextToSpeech.LANG_NOT_SUPPORTED;
}
@Override
protected void onStop() {
// Do nothing, or stop playing text
}
@Override
protected void onSynthesizeText(SynthesisRequest synthesisRequest,
SynthesisCallback synthesisCallback) {
playTts(synthesisRequest.getCharSequenceText().toString());
}
private void playTts(String text) {
// use third engine play tts
if(TextUtils.isEmpty(text)) {
return;
}
Log.w(TAG, "playTts text: " + text);
Intent intent = new Intent("com.my.asr.MY_RECEIVE_SERVICE_ACTION");
intent.setPackage("com.demo.asr");
intent.putExtra("key",100);
intent.putExtra("command","demo.only.tts");
String json="{'tts':'" + text + "'}";
intent.putExtra("json",json);
startService(intent);
}
}
另外,Manifest文件中配置为TextToSpech的Action:
// AndroidManifest.xml
<service android:name=".MyTextToSpeechService">
<intent-filter>
<action android:name="android.intent.action.TTS_SERVICE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
(2) 默认语音引擎
配置默认语音引擎服务包名,Settings数据库中添加Settings.Secure.TTS_DEFAULT_SYNTH的默认值。
调试时可使用settings put secure tts_default_synth com.example.testapplication
(3)应用端
应用端调用示例如下:
TextToSpeech tts;
private void testTextToSpeech() {
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int result) {
Log.d(TAG, "onInit result= " + result);
int resultL = tts.setLanguage(Locale.CHINA);
//int resultL = tts.setLanguage(Locale.UK);
Log.d(TAG, "onInit resultL= " + resultL);
if(resultL >= TextToSpeech.LANG_AVAILABLE) {
tts.speak("123hello测试", TextToSpeech.QUEUE_FLUSH, null, null);
}
}
});
}