package com.jiuqi.njt.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.jiuqi.njt.R;
import com.jiuqi.util.UIUtil;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
public class TextToSpeechUtil {
private String TAG = "TextToSpeechUtil";
private SpeechSynthesizer mTts;
private Context context;
private SharedPreferences Voice;
private String name;
private String speed;
private String volume;
private String pitch;
/**
* 是否需要显示语音提示框
*/
private boolean isShowProgressDialog;
/**
* 是停止还是继续播放 false:停止,TRUE:继续播放
*/
private boolean isStopOrResume;
private Button stopButton;
private SeekBar progressBar;
private PlayThread playThread ;
private int offset; //偏移量
private ImageView curDot;
private LinearLayout seekbarLinearLayout;
private View framelayout;
private int position =0;//逗点偏移未知的索引
private TranslateAnimation anim ;
private int millisInFuture = 700;
private int countDownInterval = 100;
public TextToSpeechUtil(Context context) {
this.context = context;
// 初始化合成对象
mTts = SpeechSynthesizer.createSynthesizer(context, mTtsInitListener);
// mAudioManager =(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
Voice = context.getSharedPreferences(Constants.SOFTSET_SHEAREFILENAME,0);
name = Voice.getString("name", "xiaoyan");
speed = Voice.getString("speed", "50");
volume = Voice.getString("volume", "50");
pitch = Voice.getString("pitch", "50");
String isShow = Voice.getString("isShow", "yes");
isShowProgressDialog = isShow.endsWith("yes");
setParam();
}
/**
* 参数设置
*
* @param param
* @return
*/
private void setParam() {
// 设置合成
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);// 设置方式是网络合成
// 设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, name);
// 设置语速
mTts.setParameter(SpeechConstant.SPEED, speed);
// 设置音调
mTts.setParameter(SpeechConstant.PITCH, pitch);
// 设置音量
mTts.setParameter(SpeechConstant.VOLUME, volume);
// 设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");// 代表音频流类型是音乐
}
/**
* 语音播放取消时间
* @author Administrator
*
*/
private class CancelListener implements View.OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
textdestory();
Message msg = new Message();
msg.what = 4;
handler.sendMessage(msg);
}
}
/**
* 语音播放停止和继续事件
* @author
*
*/
private class StopListener implements View.OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(isStopOrResume){
isStopOrResume = false;
mTts.resumeSpeaking();
stopButton.setBackgroundResource(R.drawable.voice_stop);
}else{
isStopOrResume = true;
mTts.pauseSpeaking();
playThread.interrupt();
stopButton.setBackgroundResource(R.drawable.voice_resume);
}
}
}
/**
* 语音框消失事件
* @author
*
*/
private class DilogCancelListener implements DialogInterface.OnCancelListener{
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
textdestory();
Message msg = new Message();
msg.what = 4;
handler.sendMessage(msg);
}
}
/**
* 播放语音时不显示语音对话框
* @param text
*/
public void textToSpeechTextWithoutDialog(String text) {
isShowProgressDialog= false;
textToSpeech(text);
}
/**
* 播放语音时显示语音对话框
* @param text
*/
public void textToSpeechDialog(String text) {
textToSpeech(text.replace(" ", ""));
}
/**
*开始播放语音
* @param text
*/
private void textToSpeech( String text) {
playThread = new PlayThread(text);
playThread.start();
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
private Button negativeButton;
private AlertDialog dialog;
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 1://显示语音对话框
LayoutInflater mLayoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup rootView = (ViewGroup) mLayoutInflater.inflate(
R.layout.voice_dialog_layout, null);
negativeButton = (Button) rootView.findViewById(R.id.negativeButton);
stopButton = (Button) rootView.findViewById(R.id.stopButton);
stopButton.setBackgroundResource(R.drawable.voice_stop);
curDot = (ImageView)rootView.findViewById(R.id.cur_dot);
curDot.getViewTreeObserver().addOnPreDrawListener(
new OnPreDrawListener() {
public boolean onPreDraw() {
offset = curDot.getWidth();
return true;
}
});
framelayout = rootView.findViewById(R.id.framelayout);
seekbarLinearLayout = (LinearLayout) rootView.findViewById(R.id.seekbarLinearLayout);
progressBar = (SeekBar) rootView.findViewById(R.id.progressBar);
stopButton.setOnClickListener(new StopListener());
negativeButton.setOnClickListener(new CancelListener());
dialog = new AlertDialog.Builder(context).create();
dialog.setOnCancelListener(new DilogCancelListener());
dialog.setView(rootView, -1, -1, -1, -1);
dialog.setCanceledOnTouchOutside(true);
MyCount count = new MyCount(millisInFuture, countDownInterval); //创建一个计时器,每100毫秒更新一下逗点的位置,总共700毫秒
count.start();
dialog.show();
break;
case 2://更新缓冲的进度
Bundle data = msg.getData();
progressBar.setSecondaryProgress(data.getInt("BufferProgress"));
break;
case 3://更新播放的进度
data = msg.getData();
progressBar.setProgress(data.getInt("SpeakProgress"));
break;
case 4://去掉对话框
dialog.dismiss();
break;
case 5://显示进度条
seekbarLinearLayout.setVisibility(View.VISIBLE);
framelayout.setVisibility(View.GONE);
break;
default:
break;
}
}
};
class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onFinish() {
position =0; // 计时完毕后重新开始
MyCount count = new MyCount(millisInFuture, countDownInterval);
count.start();
}
@Override
public void onTick(long millisUntilFinished) {
startAnimation(position);
position++;
}
}
private void startAnimation(int position){
anim = new TranslateAnimation(offset*(position), offset*(position), 0, 0);
anim.setDuration(50);
anim.setFillAfter(true);
curDot.startAnimation(anim);
}
/**
* 语音播放线程
* @author Administrator
*
*/
class PlayThread extends Thread{
private String text;
public PlayThread(String text) {
super();
this.text = text;
}
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();//1、初始化Looper
Message msg = new Message();
if (isShowProgressDialog) {
msg.what = 1;
handler.sendMessage(msg);
}
int code = mTts
.startSpeaking(text, new MySynthesizerListener());
if (code != ErrorCode.SUCCESS) {
if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
Log.e(TAG, "未安装则跳转到提示安装页面");
} else {
Log.e(TAG, "语音合成失败,错误码: " + code);
}
}
Looper.loop();//4、启动消息循环
}
}
/**
* 合成回调监听。
*/
class MySynthesizerListener implements SynthesizerListener {
@Override
public void onSpeakBegin() {
if (isShowProgressDialog) {
Message msg = new Message();
msg.what = 5;
handler.sendMessage(msg);
}
}
@Override
public void onSpeakPaused() {
}
@Override
public void onSpeakResumed() {
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
if (isShowProgressDialog) {
Message msg = new Message();
msg.what = 2;
Bundle bundle = new Bundle();
bundle.putInt("BufferProgress", percent);
msg.setData(bundle );
handler.sendMessage(msg);
}
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
if (isShowProgressDialog) {
Message msg = new Message();
msg.what = 3;
Bundle bundle = new Bundle();
bundle.putInt("SpeakProgress", percent);
msg.setData(bundle );
handler.sendMessage(msg);
}
}
@Override
public void onCompleted(SpeechError error) {
if (error == null) {
Log.e(TAG, "播放完成");
} else if (error != null) {
Log.e(TAG, error.getPlainDescription(true));
}
}
@Override
public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
}
}
/**
* 销毁语音相关对象
*/
public void textdestory() {
if (!(mTts == null)) {
mTts.stopSpeaking();
// 退出时释放连接
mTts.destroy();
}
}
/**
* 初期化监听。
*/
private InitListener mTtsInitListener = new InitListener() {
@Override
public void onInit(int code) {
Log.d(TAG, "InitListener init() code = " + code);
if (code != ErrorCode.SUCCESS) {
UIUtil.showMsg(context, "初始化失败,错误码:" + code);
}
}
};
public List<String> splitText(String text) {
List<String> textlist = new ArrayList<String>();
textlist = Arrays.asList(split(text, 500));
textlist.size();
return textlist;
}
/**
* @author AnjouLee
*
* 按指定长度分割字符串,用于短信
*
* @param msg
* 信息内容
* @param num
* 要分割的长度
* @return
*/
public static String[] split(String msg, int num) {
int len = msg.length();
if (len <= num)
return new String[] { msg };
int count = len / (num - 1);
count += len > (num - 1) * count ? 1 : 0;
String[] result = new String[count];
int pos = 0;
for (int i = 0; i < count; i++) {
if (i == count - 1)
num = len - pos;
result[i] = msg.substring(pos, pos + num);
pos += num;
}
return result;
}
}