地图导航没有语音播报,只给出了语音的文字,所以需要自己集成一个语音播报的功能,把导航返回的文字给说出来;
语音这方面选择了科大讯飞,https://www.xfyun.cn/,注册用户、新建项目,下载SDK;讯飞会把你需要的服务生成一个sdk,下载就行了;创建完成后会给你一个APPID,初始化语音时会使用到;
按照指示添加so和jar:
在build.gradle中Android{}中添加:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
1、先初始化,最好放在AppLocation中吧;APPID就是创建项目时给的;
SpeechUtility.createUtility(mC.getApplicationContext(), SpeechConstant.APPID +"=12345678");
2、在使用的类中初始化合成对象和设置参数:
private void initTts() {
if (mTts == null){
mTts = SpeechSynthesizer.createSynthesizer(mC, new InitListener() {
@Override
public void onInit(int i) {
if ( i != ErrorCode.SUCCESS){
Log.i("TTS", "语音初始化失败,错误码:"+i);
}
}
});}
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoqi");
//设置语速,值范围:[0, 100],默认值:50
mTts.setParameter(SpeechConstant.SPEED, "49");
//设置音量
mTts.setParameter(SpeechConstant.VOLUME, "tts_volume");
//设置语调
mTts.setParameter(SpeechConstant.PITCH, "tts_pitch");
}
3、开始合成语音、语音播报;
mTts.startSpeaking("你好",null); //第一个参数是需要播报的文字,第二个参数是回调;
好了这样就完成了;可以先试一下效果;
我在使用模拟导航时,语音播报会特别快;有时第一句话还没有说完再调用startSpeaking方法,就把第一句停掉开始说第二句了;于是做了一些处理;把传过来的文字放在List集合中,逐条去播放;
public class TtsUtils {
private Context mC;
//初始化
public TtsUtils(Context mC){
this.mC = mC;
}
private SpeechSynthesizer mTts;
public TtsUtils init(){
SpeechUtility.createUtility(mC.getApplicationContext(), SpeechConstant.APPID +"=5bc6d436");
initTts();
return this;
}
private void initTts() {
if (mTts == null){
mTts = SpeechSynthesizer.createSynthesizer(mC, new InitListener() {
@Override
public void onInit(int i) {
if ( i != ErrorCode.SUCCESS){
Log.i("TTS", "语音初始化失败,错误码:"+i);
}
}
});}
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoqi");
//设置语速,值范围:[0, 100],默认值:50
mTts.setParameter(SpeechConstant.SPEED, "49");
//设置音量
mTts.setParameter(SpeechConstant.VOLUME, "tts_volume");
//设置语调
mTts.setParameter(SpeechConstant.PITCH, "tts_pitch");
}
private int position = 0;
private boolean isSpeak = false;
private ArrayList mTtsDatas = new ArrayList();
public void startSpeakingOrAddText(String s){
Log.i("TTS", "Tts: "+s+",第几条 = "+(++position));
//如果传过来的文字 不是空 就加入到列表中
if (!TextUtils.isEmpty(s)){
mTtsDatas.add(s);
}
//如果不是正在说话,并且文字列表大于0,就去说话;
if (!isSpeak && mTtsDatas.size() > 0){
mTts.startSpeaking(mTtsDatas.get(0),c);
//说完后把当前这条删除了
mTtsDatas.remove(0);
}
}
private SynthesizerListener c = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
//开始说了;
isSpeak = true;
}
@Override
public void onBufferProgress(int i, int i1, int i2, String s) {
}
@Override
public void onSpeakPaused() {
isSpeak = true;
}
@Override
public void onSpeakResumed() {
isSpeak = true;
}
@Override
public void onSpeakProgress(int i, int i1, int i2) {
}
@Override
public void onCompleted(SpeechError speechError) {
//说完了
isSpeak = false;
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(200); //延迟0.2秒
startSpeakingOrAddText(null); //传递null,让语音继续轮播播报下一条;
}
}).start();
}
@Override
public void onEvent(int i, int i1, int i2, Bundle bundle) {
}
};
public void destroy(){
mTtsDatas = null;
if( null != mTts ){
mTts.stopSpeaking();
// 退出时释放连接
mTts.destroy();
}
}
}
使用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.et);
mC = this;
mTts = new TtsUtils(mC).init();
}
public void click(View view) {
mTts.startSpeakingOrAddText(et.getText().toString());
}
OK!