123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- package com.hanghui.senic.common;
- import android.content.Context;
- import android.speech.tts.TextToSpeech;
- import android.text.TextUtils;
- import com.blankj.utilcode.util.LogUtils;
- import com.google.gson.Gson;
- import com.hanghui.senic.MyAppliction;
- import com.hanghui.senic.service.usbserialdemo.utile.MTTSDemo;
- import com.hanghui.senic.service.usbserialdemo.utile.StringIsNull;
- import com.hanghui.senic.service.usbserialdemo.utile.loacat.AppLogUtils;
- import java.lang.reflect.Field;
- import java.util.Locale;
- /**
- * 语音播报
- */
- public class MTTSManager implements TextToSpeech.OnInitListener {
- private static MTTSManager instance;
- private TextToSpeech mTTS;
- private String speakContent = "";
- public MTTSManager() {
- if (mTTS == null) {
- //监听器就直接传入本类
- mTTS = new TextToSpeech(MyAppliction.getContext(), this);
- }
- }
- public static synchronized MTTSManager getInstance() {
- if (instance == null) {
- instance = new MTTSManager();
- }
- return instance;
- }
- public void speak(String text) {
- if (StringIsNull.IsStringNull(text)) {
- AppLogUtils.e(true, "TTS语音播报", "语音内容为空 ");
- return;
- }
- AppLogUtils.e(false, "TTS语音播报", "TTS语音播报内容 : " + text);
- if (ismServiceConnectionUsable(mTTS)) {
- if (mTTS == null) {
- mTTS = new TextToSpeech(MyAppliction.getContext(), this);
- }
- speakContent = text;
- //设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规
- mTTS.setPitch(1.0f);
- //设置语速
- mTTS.setSpeechRate(1.0f);
- //TextToSpeech.QUEUE_ADD添加到队列后面,依次将前面的读完轮序
- //TextToSpeech.QUEUE_FLUSH刷新队列,将之前的队列取消阅读现在的文字
- mTTS.speak(text, TextToSpeech.QUEUE_FLUSH, null);
- } else {//被回收了不可用状态
- if (mTTS != null){
- mTTS.stop();
- mTTS.shutdown();
- }
- mTTS = new TextToSpeech(MyAppliction.getContext(), status -> {
- if (status == TextToSpeech.SUCCESS) {
- int result = mTTS.setLanguage(Locale.CHINA);
- if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE
- && result != TextToSpeech.LANG_AVAILABLE) {
- AppLogUtils.e(true, " TTS - onInit", "TTS语音播报 onInit: 不支持这种语言");
- }
- //设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规
- mTTS.setPitch(1.0f);
- //设置语速
- mTTS.setSpeechRate(1.0f);
- mTTS.speak(text, TextToSpeech.QUEUE_FLUSH, null);
- } else {
- AppLogUtils.e(true, " TTS - onInit", "TTS语音播报 onInit: TTS初始化失败");
- }
- }, "com.iflytek.speechcloud");//科大讯飞语音引擎
- }
- }
- public void init() {
- //监听器就直接传入本类
- mTTS = new TextToSpeech(MyAppliction.getContext(), this);
- }
- public void destroy() {
- if (mTTS != null) {
- mTTS.stop();
- mTTS.shutdown();
- mTTS = null;
- }
- instance = null;
- }
- @Override
- public void onInit(int status) {
- if (mTTS == null) {
- mTTS = new TextToSpeech(MyAppliction.getContext(), this);
- }
- //判断是否转化成功
- if (status == TextToSpeech.SUCCESS) {
- //设置语言为中文
- int languageCode = mTTS.setLanguage(Locale.CHINESE);
- //判断是否支持这种语言,Android原生不支持中文,使用科大讯飞的tts引擎就可以了
- if (languageCode == TextToSpeech.LANG_NOT_SUPPORTED) {
- AppLogUtils.e(true, " TTS - onInit", "TTS语音播报 onInit: 不支持这种语言");
- } else {
- //不支持就改成英文
- mTTS.setLanguage(Locale.US);
- }
- } else {
- // 检查语音数据是否已下载
- if (mTTS.isLanguageAvailable(Locale.CHINESE) >= TextToSpeech.LANG_AVAILABLE) {
- AppLogUtils.e(false, "TTS - onInit", "-----------speakContent " + speakContent);
- speak(speakContent);
- } else {
- AppLogUtils.e(false, " TTS - onInit", "中文语音数据未完整下载。");
- }
- }
- }
- /**
- * TTS初始化之后有时会无法播放语音。
- * 从打印日志看failed: not bound to TTS engine
- * 找到源代码打印处
- * if (mServiceConnection == null) {
- * Log.w(TAG, method + " failed: not bound to TTS engine");
- * return errorResult;
- * }
- * 通过反射判断mServiceConnection是否为空
- *
- * @param tts
- * @return true 可用
- */
- public static boolean ismServiceConnectionUsable(TextToSpeech tts) {
- boolean isBindConnection = true;
- if (tts == null) {
- return false;
- }
- Field[] fields = tts.getClass().getDeclaredFields();
- for (int j = 0; j < fields.length; j++) {
- fields[j].setAccessible(true);
- if (TextUtils.equals("mConnectingServiceConnection", fields[j].getName()) && TextUtils.equals("android.speech.tts.TextToSpeech$Connection", fields[j].getType().getName())) {
- try {
- if (fields[j].get(tts) == null) {
- isBindConnection = false;
- }
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- return isBindConnection;
- }
- }
|