Explorar o código

增加语音播报功能,需要先安装tts,默认暂时关闭

weizhengliang hai 11 meses
pai
achega
7ec067625c

+ 165 - 26
lcd_board/src/main/java/com/wdkl/lcd_board/activity/MainActivity.kt

@@ -1,15 +1,18 @@
 package com.wdkl.lcd_board.activity
 
+import android.app.NotificationManager
 import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.graphics.Color
 import android.net.ConnectivityManager
+import android.net.Uri
 import android.os.Build
 import android.os.Handler
 import android.os.Looper
 import android.os.Message
+import android.provider.Settings
 import android.text.TextUtils
 import android.util.Log
 import android.view.View
@@ -24,10 +27,9 @@ import com.wdkl.lcd_board.BuildConfig
 import com.wdkl.lcd_board.R
 import com.wdkl.lcd_board.databinding.ActivityMainLayoutBinding
 import com.wdkl.lcd_board.entity.Program
-import com.wdkl.lcd_board.helper.AppUpdateHelper
-import com.wdkl.lcd_board.helper.NetHelper
-import com.wdkl.lcd_board.helper.ServerConfigDialogHelper
+import com.wdkl.lcd_board.helper.*
 import com.wdkl.lcd_board.launch.MainLaunch
+import com.wdkl.lcd_board.settings.SettingConfig
 import com.wdkl.ncs.android.lib.base.BaseActivity
 import com.wdkl.ncs.android.lib.base.BaseApplication
 import com.wdkl.ncs.android.lib.utils.*
@@ -45,6 +47,7 @@ import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
 import com.wdkl.ncs.android.middleware.model.vo.DeviceNurseInfoVO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
 import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
 import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
 import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
@@ -60,6 +63,7 @@ import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import java.lang.ref.WeakReference
 import java.util.*
+import java.util.concurrent.Executors
 import java.util.concurrent.TimeUnit
 
 
@@ -163,6 +167,27 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
 
         animationIn = AnimationUtils.loadAnimation(this@MainActivity, R.anim.slide_in)
 
+        if (Constant.VOICE_ON) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                if (!Settings.System.canWrite(BaseApplication.appContext)) {
+                    val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS)
+                    intent.data = Uri.parse("package:" + BaseApplication.appContext.packageName)
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    startActivity(intent)
+                } else {
+                    updateTime(true)
+                }
+            }
+
+            startScheduledExecutor()
+
+            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
+                SpeechUtil.getInstance().init(activity) {
+                    //
+                }
+            }
+        }
+
         //test
         /*handler.postDelayed({
             val program1 = Program()
@@ -300,6 +325,7 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
         unRegReceiver()
         EventBus.getDefault().unregister(this)
         Constant.CALL_STATE = Constant.CALL_STANDBY
+        SpeechUtil.getInstance().release()
 
         handler.removeCallbacksAndMessages(null)
         callHandler.removeCallbacksAndMessages(null)
@@ -307,7 +333,6 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
 
     //数据加载错误
     override fun onError(message: String, type: Int) {
-        //errorLog("error",message)
         showMessage("数据加载错误")
     }
 
@@ -353,18 +378,17 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
         startTcp()
         showMessage("tcp开始连接...host: " + Constant.TCP_SERVER_URL + ", port: " + Constant.TCP_PORT)
 
-        Thread(Runnable {
+        Thread {
             while (!initialized) {
-                runOnUiThread(Runnable {
-                    initDevice()
-                })
+                initDevice()
+
                 try {
-                    Thread.sleep(20000)
+                    Thread.sleep(30000)
                 } catch (e: Exception) {
                     //
                 }
             }
-        }).start()
+        }.start()
     }
 
     //显示设备信息
@@ -414,7 +438,20 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
 
 
     override fun setPartSettings(partSetting: PartSettingDO) {
-        //
+        Log.e(TAG,"收到返回的设置配置信息 ")
+
+        try {
+            //白天夜晚音量
+            SettingConfig.setHostDaytimeVolume(this.activity, partSetting.dayVol)
+            SettingConfig.setHostNightVolume(this.activity, partSetting.nightVol)
+
+            //响铃次数
+            SettingConfig.setCallNumber(this, partSetting.dayRingTimes)
+        } catch (e: Exception) {
+            Log.i(TAG,"解析科室设置数据异常" + e.message)
+        }
+
+        updateTime(true)
     }
 
     override fun loadAppVersion(appInfo: AppVersionDO) {
@@ -435,22 +472,19 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
         }
     }
 
-    fun startTcp() {
+    private fun startTcp() {
         if (!TextUtils.isEmpty(Constant.TCP_SERVER_URL) && !tcpConnect) {
             tcpConnect = true
-            Thread(Runnable {
+            Thread {
                 TcpClient.getInstance().init(Constant.TCP_SERVER_URL, Constant.TCP_PORT, Constant.TCP_HEART_BEAT)
-                TcpClient.getInstance().setTcpCallback {
-                    //updateSendTcpInfo(it)
-                }
-            }).start()
+            }.start()
         }
     }
 
     private fun regReceiver() {
         receiver = TimeReceiver()
-        var intentFilter = IntentFilter()
-        intentFilter.addAction(Intent.ACTION_TIME_TICK)
+        val intentFilter = IntentFilter()
+        //intentFilter.addAction(Intent.ACTION_TIME_TICK)
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
         registerReceiver(receiver, intentFilter)
     }
@@ -484,6 +518,14 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                         if (tcpModel.action == TcpAction.VoiceAction.CALL) {
                             val callInteractionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
                             val bedCall: String = callInteractionVO.fromFrameFullName + BED_CALL
+                            //语音播报
+                            if (Constant.VOICE_ON) {
+                                if (!TextUtils.isEmpty(callInteractionVO.fromFrameFullName)) {
+                                    val speakText = Util.appendSpace(callInteractionVO.fromFrameFullName.replace("-", ",")) + "," + BED_CALL
+                                    SpeechUtil.getInstance().addSpeech(speakText, false)
+                                }
+                            }
+
                             for (program in programs) {
                                 if (bedCall == program.text) {
                                     programs.remove(program)
@@ -502,6 +544,14 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                             val callInteractionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
                             val bedCall: String = callInteractionVO.fromFrameFullName + BED_CALL
 
+                            //移除语音播报
+                            if (Constant.VOICE_ON) {
+                                if (!TextUtils.isEmpty(callInteractionVO.fromFrameFullName)) {
+                                    val speakText = Util.appendSpace(callInteractionVO.fromFrameFullName.replace("-", ",")) + "," + BED_CALL
+                                    SpeechUtil.getInstance().removeSpeak(speakText)
+                                }
+                            }
+
                             deleteCall(bedCall)
                         }
                     } else if (tcpModel.type == TcpType.SOS) {
@@ -520,6 +570,12 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                                 sosCall = sosInteractionVO.fromFrameFullName + SOS_CALL
                             }
 
+                            //语音播报
+                            if (Constant.VOICE_ON) {
+                                val speakText = Util.appendSpace(sosCall.replace("-", ","))
+                                SpeechUtil.getInstance().addSpeech(speakText,true)
+                            }
+
                             for (program in programs) {
                                 if (sosCall == program.text) {
                                     programs.remove(program)
@@ -539,6 +595,12 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                                 sosCall = sosInteractionVO.fromFrameFullName + SOS_CALL
                             }
 
+                            //移除语音播报
+                            if (Constant.VOICE_ON) {
+                                val speakText = Util.appendSpace(sosCall.replace("-", ","))
+                                SpeechUtil.getInstance().removeSpeak(speakText)
+                            }
+
                             deleteCall(sosCall)
                         } else if (tcpModel.action == TcpAction.SOSAction.RECEIVED
                             || tcpModel.action == TcpAction.SOSAction.NO_MATCH) {
@@ -555,6 +617,12 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                                     sosCall = sosInteractionVO.fromFrameFullName + SOS_CALL
                                 }
 
+                                //语音播报
+                                if (Constant.VOICE_ON) {
+                                    val speakText = Util.appendSpace(sosCall.replace("-", ","))
+                                    SpeechUtil.getInstance().addSpeech(speakText,true)
+                                }
+
                                 for (program in programs) {
                                     if (sosCall == program.text) {
                                         programs.remove(program)
@@ -693,16 +761,82 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
         }
     }
 
+    private fun updateTime(forceSet: Boolean) {
+        if (!Constant.VOICE_ON) {
+            return
+        }
 
-    inner class TimeReceiver: BroadcastReceiver() {
-        override fun onReceive(context: Context, intent: Intent) {
-            if (intent.action == Intent.ACTION_TIME_TICK) {
-                updateNetState()
-                if (initialized) {
+        val currentTimestamp = System.currentTimeMillis()
+        val date = TimeTransition.getDateTime("yyyy-MM-dd")
+        //白天起始时间戳
+        val dayStartTimeStamp = TimeTransition.dateToStamp(date + " " + SettingConfig.getInitialDayTime(activity) + ":00")
+        //白天结束时间戳
+        val endOfDayTimeStamp = TimeTransition.dateToStamp(date + " " + SettingConfig.getEndOfDay(activity) + ":00")
+        Log.e(TAG, "dayStartTimeStamp: " + dayStartTimeStamp + "----endOfDayTimeStamp: " + endOfDayTimeStamp)
+
+        val curInday = dayStartTimeStamp < currentTimestamp && currentTimestamp < endOfDayTimeStamp
+        if (curInday) {
+            //当前是白天并且原来不是白天
+            if (Constant.day_state != 0 || forceSet) {
+                //设置白天系统音量和响铃音
+                setTheSystemVolume(SettingConfig.getHostDaytimeVolume(activity))
+            }
+            Constant.day_state = 0
+        } else {
+            //当前是夜晚并且原来不是夜晚
+            if (Constant.day_state != 1 || forceSet) {
+                //设置晚上系统音量和响铃音
+                setTheSystemVolume(SettingConfig.getHostNightVolume(activity))
+            }
+            Constant.day_state = 1
+        }
+    }
+
+    /**
+     * 设置系统音量
+     */
+    private fun setTheSystemVolume(value:Int) {
+        try {
+            if (value <= 15) {
+                val nm =
+                    this.activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !nm.isNotificationPolicyAccessGranted) {
+                    val intent = Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
+                    startActivity(intent)
+                } else {
+                    VoiceManagerUtil.setSystemVoice(this.activity, value)
+                    VoiceManagerUtil.setMusicVoice(this.activity, value)
+                }
+            } else {
+                VoiceManagerUtil.setSystemVoice(this.activity, value)
+                VoiceManagerUtil.setMusicVoice(this.activity, value)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    private fun startScheduledExecutor() {
+        val timerTask: TimerTask = object : TimerTask() {
+            override fun run() {
+                try {
                     updateNetState()
-                    resetPrograms()
+                    if (initialized) {
+                        resetPrograms()
+                        updateTime(false)
+                    }
+                } catch (e: Exception) {
+                    //
                 }
-            } else if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
+            }
+        }
+        val executor = Executors.newSingleThreadScheduledExecutor()
+        executor.scheduleAtFixedRate(timerTask, 100, 60, TimeUnit.SECONDS)
+    }
+
+    inner class TimeReceiver: BroadcastReceiver() {
+        override fun onReceive(context: Context, intent: Intent) {
+            if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
                 updateNetState()
             }
         }
@@ -753,6 +887,11 @@ class MainActivity :BaseActivity<MainActivityPresenter, ActivityMainLayoutBindin
                                 handlerMemoryActivity.tv_call_info.setTextColor(Color.WHITE)
                                 handlerMemoryActivity.tv_call_info.setText("祝   您   安   康")
                                 handlerMemoryActivity.tv_call_info.startAnimation(handlerMemoryActivity.animationIn)
+
+                                if (Constant.VOICE_ON) {
+                                    //停止语音播报
+                                    SpeechUtil.getInstance().stopSpeak(true)
+                                }
                             }
                         }
                     }

+ 211 - 0
lcd_board/src/main/java/com/wdkl/lcd_board/helper/SpeechUtil.java

@@ -0,0 +1,211 @@
+package com.wdkl.lcd_board.helper;
+
+import android.content.Context;
+import android.os.Build;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.support.annotation.RequiresApi;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.wdkl.lcd_board.settings.SettingConfig;
+import com.wdkl.ncs.android.lib.base.BaseApplication;
+import com.wdkl.ncs.android.middleware.common.Constant;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+public class SpeechUtil {
+    private static final String TAG = "SpeechUtil";
+
+    private TextToSpeech textToSpeech;
+    private static SpeechUtil speech;
+    private int speakIndex = 0;
+    private int loopCount = 2;
+    private int loopIndex = 0;
+    private boolean isStop = true;
+    public volatile static ArrayList<String> speechTextList = new ArrayList<>();
+    private Thread speechThread;
+    private boolean isSpeechLoop = true;
+    private String speakSpeech;
+    private final Object lockObject = new Object();
+
+    public static SpeechUtil getInstance() {
+        if (speech == null) {
+            synchronized (SpeechUtil.class) {
+                if (speech == null) {
+                    speech = new SpeechUtil();
+                }
+            }
+        }
+        return speech;
+    }
+
+    public void init(Context context, final TtsCallback callback) {
+        textToSpeech = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
+            @Override
+            public void onInit(int status) {
+                if (status == TextToSpeech.SUCCESS) {
+                    int supported = textToSpeech.setLanguage(Locale.CHINESE);
+                    if ((supported != TextToSpeech.LANG_AVAILABLE) && (supported != TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
+                        Constant.TTS_STATUS = 1;
+                        Log.d(TAG, "onInit: 当前不支持中文");
+                        if (callback != null) {
+                            callback.onInit(false);
+                        }
+                    } else {
+                        Constant.TTS_STATUS = 2;
+                        Log.d(TAG, "onInit: 支持中文");
+                        if (callback != null) {
+                            callback.onInit(true);
+                        }
+                    }
+                    Log.d(TAG, "onInit: TTS引擎初始化成功");
+                } else {
+                    Constant.TTS_STATUS = 0;
+                    Log.d(TAG, "onInit: TTS引擎初始化失败");
+                    if (callback != null) {
+                        callback.onInit(false);
+                    }
+                }
+            }
+        }, "com.iflytek.speechcloud");
+
+        textToSpeech.setSpeechRate(0.5f);
+    }
+
+    public void addSpeech(String text, boolean emergency) {
+        synchronized (lockObject) {
+            Log.d(TAG, "start add text speech: " + text);
+
+            if (speechTextList.contains(text)) {
+                return;
+            }
+            Log.d(TAG, "truely add text speech: " + text);
+
+            if (emergency) {
+                speechTextList.add(0, text);
+                stopSpeak(false);
+            } else {
+                speechTextList.add(text);
+            }
+            startSpeechThread();
+        }
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+    public synchronized void speak(final String text) {
+        Log.d(TAG, "tts speak: " + text);
+
+        isStop = false;
+        textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, "uniqueId");
+        textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
+            @Override
+            public void onStart(String utteranceId) {
+                //LogUtil.d(TAG, "speak onStart..." + utteranceId);
+            }
+
+            @Override
+            public void onDone(String utteranceId) {
+                speakIndex++;
+                //LogUtil.d(TAG, "speak onDone...index: " + speakIndex + ", loop: " + loopCount);
+                if (speakIndex < loopCount) {
+                    //循环播报
+                    speak(text);
+                } else {
+                    //语音播报完毕
+                    speakIndex = 0;
+                    isStop = true;
+                }
+            }
+
+            @Override
+            public void onError(String utteranceId) {
+                isStop = true;
+                Log.d(TAG, "speak onError..." + utteranceId);
+            }
+        });
+    }
+
+    public void stopSpeak(boolean removeAll) {
+        if (removeAll) {
+            speechTextList.clear();
+        }
+        if (textToSpeech != null && textToSpeech.isSpeaking()) {
+            textToSpeech.stop();
+            isStop = true;
+            speakIndex = 0;
+            loopIndex = 0;
+
+            Log.d(TAG, "stop speak removeAll: " + removeAll);
+        }
+    }
+
+    public void removeSpeak(String text) {
+        synchronized (lockObject) {
+            if (!TextUtils.isEmpty(text) && !TextUtils.isEmpty(speakSpeech)) {
+                Log.d(TAG, "remove speak: " + text);
+
+                if (text.equals(speakSpeech) && textToSpeech.isSpeaking()) {
+                    textToSpeech.stop();
+                    speechTextList.remove(text);
+                    isStop = true;
+                    speakIndex = 0;
+                } else {
+                    speechTextList.remove(text);
+                }
+            }
+        }
+    }
+
+    public void setSpeechLoopCount(int count) {
+        loopCount = count;
+    }
+
+    public void release() {
+        speechTextList.clear();
+        isStop = true;
+        speakIndex = 0;
+        if (textToSpeech != null) {
+            textToSpeech.stop();
+            textToSpeech.shutdown();
+            textToSpeech = null;
+        }
+    }
+
+    public void startSpeechThread() {
+        if (null == speechThread) {
+            speechThread = new Thread(new SpeechRunnable());
+            speechThread.start();
+        } else if (!speechThread.isAlive()) {
+            speechThread.start();
+        }
+    }
+
+    public class SpeechRunnable implements Runnable {
+        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+        public void run() {
+            while (isSpeechLoop) {
+                if (speechTextList.size() > 0 && isStop) {
+                    loopIndex = 0;
+                    speakSpeech = speechTextList.get(loopIndex);
+                    Log.d(TAG, "speakSpeech: " + speakSpeech + ", speak loopIndex: " + loopIndex + ", speech size: " + speechTextList.size());
+                    speak(speakSpeech);
+
+                    speechTextList.remove(speakSpeech);
+                }
+
+                try {
+                    Thread.sleep(500);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    public interface TtsCallback {
+        void onInit(boolean success);
+    }
+}

+ 86 - 0
lcd_board/src/main/java/com/wdkl/lcd_board/helper/TimeTransition.kt

@@ -0,0 +1,86 @@
+package com.wdkl.lcd_board.helper
+
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.*
+
+
+object TimeTransition {
+
+    fun stampToDate(s:Long):String{
+        return getDateTime(s,"yyyy-MM-dd")
+    }
+
+    /**
+     * 时间戳转时间 不带时区
+     */
+    fun stampToTime(s:Long):String{
+        return TimeStampToTime(s,"HH:mm:ss")
+    }
+
+    fun stampToDateTime(s:Long):String{
+        return TimeStampToTime(s,"MM-dd HH:mm:ss")
+    }
+
+    /**
+     * 时间戳转时间 不带时区
+     */
+    fun TimeStampToTime(s:Long, timestamp:String):String{
+        val res: String
+        val simpleDateFormat = SimpleDateFormat(timestamp)
+        val lt = s
+        val date = Date(lt)
+        res = simpleDateFormat.format(date)
+        return res
+}
+
+    /**
+     * 获取当前的时间 带时区
+     */
+    fun getDateTime(format: String): String {
+        val date = Date(System.currentTimeMillis())
+        val sdf = SimpleDateFormat(format)
+        //sdf.timeZone = TimeZone.getTimeZone("GMT+8")
+        return sdf.format(date)
+    }
+
+    /**
+     * 时间戳转时间字符串
+     */
+    fun getDateTime(timeMillis: Long, format: String): String {
+        if (timeMillis > 0) {
+            val date = Date(timeMillis)
+            val sdf = SimpleDateFormat(format)
+            //sdf.timeZone = TimeZone.getTimeZone("GMT+8")
+            return sdf.format(date)
+        }
+        return "null"
+    }
+
+    /**
+     * 时间转时间戳
+     */
+    fun dateToStamp(s: String): Long {
+        return dateToStamp(s, "yyyy-MM-dd HH:mm:ss")
+    }
+
+    /**
+     * 将时间转换为时间戳
+     */
+    fun dateToStamp(s: String, pattern: String): Long {
+        val simpleDateFormat = SimpleDateFormat(pattern)
+        var date: Date? = null
+        try {
+            //simpleDateFormat.timeZone = TimeZone.getTimeZone("GMT+8")
+            date = simpleDateFormat.parse(s)
+
+            return date!!.time
+        } catch (e: ParseException) {
+            e.printStackTrace()
+        }
+
+        return 0
+    }
+
+
+}

+ 30 - 0
lcd_board/src/main/java/com/wdkl/lcd_board/helper/Util.kt

@@ -0,0 +1,30 @@
+package com.wdkl.lcd_board.helper
+
+import android.content.Context
+import android.util.DisplayMetrics
+import android.view.WindowManager
+
+
+object Util {
+
+    fun appendSpace(para: String): String {
+        val length = para.length
+        val value = CharArray(length shl 1)
+        var i = 0
+        var j = 0
+        while (i < length) {
+            value[j] = para[i]
+            value[1 + j] = ' '
+            ++i
+            j = i shl 1
+        }
+        return String(value)
+    }
+
+    fun getPixelsFromDp(context: Context, size: Int): Int {
+        val metrics = DisplayMetrics()
+        val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+        wm.getDefaultDisplay().getMetrics(metrics)
+        return size * metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT
+    }
+}

+ 194 - 0
lcd_board/src/main/java/com/wdkl/lcd_board/helper/VoiceManagerUtil.java

@@ -0,0 +1,194 @@
+package com.wdkl.lcd_board.helper;
+
+import android.content.Context;
+import android.media.AudioManager;
+
+/**
+ * 类名称:VoiceManagerUtil <br>
+ * 类描述:声音控制工具类 <br>
+ * 创建人:Waderson Shll (TEL:15675117662)<br>
+ * 创建时间:2018-03-15 <br>
+ * 特别提醒:如有需要该类可任意创建与调用;在未通知本人的情况下该类禁止任何修改!<br>
+ */
+public class VoiceManagerUtil {
+    /**
+     * 获取提示音音量最大值
+     *
+     * @param context
+     */
+    public static int getAlarmMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
+    }
+
+    /**
+     * 获取提示音音量当前值
+     *
+     * @param context
+     */
+    public static int getAlarmNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
+    }
+
+    /**
+     * 获取多媒体音量最大值
+     *
+     * @param context
+     */
+    public static int getMusicMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+    }
+
+    /**
+     * 获取多媒体音量当前值
+     *
+     * @param context
+     */
+    public static int getMusicNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+    }
+
+    /**
+     * 获取铃声音量最大值
+     *
+     * @param context
+     */
+    public static int getRingMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
+    }
+
+    /**
+     * 获取铃声音量当前值
+     *
+     * @param context
+     */
+    public static int getRingNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
+    }
+
+    /**
+     * 获取系统音量最大值
+     *
+     * @param context
+     */
+    public static int getSystemMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);
+    }
+
+    /**
+     * 获取系统音量当前值
+     *
+     * @param context
+     */
+    public static int getSystemNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
+    }
+
+    /**
+     * 获取通话音量最大值
+     *
+     * @param context
+     */
+    public static int getCallMax(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
+    }
+
+    /**
+     * 获取通话音量当前值
+     *
+     * @param context
+     */
+    public static int getCallNow(Context context) {
+        AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+    }
+
+    /**
+     * 设置提示音音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setAlarmVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_ALARM, (int) (getAlarmMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置多媒体音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setMusicVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int) (getMusicMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置铃声音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setRingVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_RING, (int) (getRingMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置系统音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setSystemVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_SYSTEM, (int) (getSystemMax(context) * vPercent), 0);
+    }
+
+    /**
+     * 设置通话音量
+     *
+     * @param context
+     * @param percent (百分比;只能0--100之间)
+     */
+    public static void setCallVoice(Context context, int percent) {
+        float vPercent=((float)percent)/100f;
+        vPercent = vPercent < 0 ? 0 : vPercent;
+        vPercent = vPercent > 1 ? 1 : vPercent;
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, (int) (getCallMax(context) * vPercent), 0);
+    }
+
+    public static void switchAudioMode(Context context, boolean speakerOn) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setSpeakerphoneOn(speakerOn);
+        if (speakerOn) {
+            audioManager.setMode(AudioManager.MODE_NORMAL);
+        } else {
+            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+        }
+    }
+
+}

+ 71 - 0
lcd_board/src/main/java/com/wdkl/lcd_board/settings/SettingConfig.java

@@ -3,6 +3,8 @@ package com.wdkl.lcd_board.settings;
 import android.content.Context;
 import android.content.SharedPreferences;
 
+import com.wdkl.lcd_board.helper.SpeechUtil;
+
 
 public class SettingConfig {
 
@@ -23,6 +25,17 @@ public class SettingConfig {
     private static final String KEY_SP_END_OF_DAY_LOCATION = "KEY_SP_END_OF_DAY_LOCATION";
     private static final String end_of_day_location = "38";
 
+    //主机白天音量
+    private static final String KEY_SP_HOST_DAYTIME_VOLUME = "KEY_SP_HOST_DAYTIME_VOLUME";
+    private static final int host_daytime_volume = 100;
+    //主机晚上音量
+    private static final String KEY_SP_HOST_NIGHT_VOLUME = "KEY_SP_HOST_NIGHT_VOLUME";
+    private static final int host_night_volume = 80;
+
+    //播报次数
+    private static final String KEY_SP_CALL_NUMBER = "KEY_SP_CALL_NUMBER";
+    private static final int call_number = 2;
+
 
     //分机白天亮度
     private static final String KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS = "KEY_SP_EXTENSION_DAYTIME_BRIGHTNESS";
@@ -72,6 +85,64 @@ public class SettingConfig {
     //网络异常重启次数
     private static final String KEY_SP_NET_ERR_RESET_COUNT = "KEY_SP_NET_ERR_RESET_COUNT";
 
+
+    /**
+     * 获取主机白天音量
+     *
+     * @return
+     */
+    public static int getHostDaytimeVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_HOST_DAYTIME_VOLUME, host_daytime_volume);
+    }
+
+    /**
+     * 设置主机白天音量
+     *
+     * @param value
+     */
+    public static void setHostDaytimeVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_HOST_DAYTIME_VOLUME, value).apply();
+    }
+
+    /**
+     * 获取主机晚上音量
+     *
+     * @return
+     */
+    public static int getHostNightVolume(Context context) {
+        return getSP(context).getInt(KEY_SP_HOST_NIGHT_VOLUME, host_night_volume);
+    }
+
+    /**
+     * 设置主机晚上音量
+     *
+     * @param value
+     */
+    public static void setHostNightVolume(Context context, int value) {
+        getEditor(context).putInt(KEY_SP_HOST_NIGHT_VOLUME, value).apply();
+    }
+
+    /**
+     * 获取播报次数
+     *
+     * @return
+     */
+    public static int getCallNumber(Context context) {
+        return getSP(context).getInt(KEY_SP_CALL_NUMBER, call_number);
+    }
+
+    /**
+     * 设置播报次数
+     *
+     * @param value
+     */
+    public static void setCallNumber(Context context, int value) {
+        if (value > 0) {
+            SpeechUtil.getInstance().setSpeechLoopCount(value);
+        }
+        getEditor(context).putInt(KEY_SP_CALL_NUMBER, value).apply();
+    }
+
     /**
      * 获取分机白天亮度
      *

+ 5 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constant.java

@@ -50,6 +50,11 @@ public class Constant {
     //佛山项目开启自动接听
     public static boolean autoAnswer = false;
 
+    //是否开启语音播报
+    public static boolean VOICE_ON = false;
+    //tts服务是否可用: 0-不可用, 1-可用但不支持中文, 2-可用且支持中文
+    public static int TTS_STATUS = 0;
+
     //MAC地址
     public static String LOCAL_MAC = "";
     public static String LOCAL_IP = "";