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; } }