跨进程通讯
This commit is contained in:
@@ -31,6 +31,15 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<service
|
||||||
|
android:name=".TTSService"
|
||||||
|
android:exported="true"
|
||||||
|
android:process=":ttsP"
|
||||||
|
>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.mogo.tts.ttsservice" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -5,8 +5,18 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.widget.AppCompatButton
|
import androidx.appcompat.widget.AppCompatButton
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.mogo.tts.common.IMogoTTSCallback
|
||||||
|
import com.mogo.tts.common.log.TtsLogManager
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private val ttsManager = TtsManager()
|
||||||
|
|
||||||
|
private val TAG = "MainActivity"
|
||||||
|
|
||||||
|
private val ranx = Random(10)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
@@ -17,10 +27,31 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findViewById<AppCompatButton>(R.id.actv_test_tts1).setOnClickListener {
|
findViewById<AppCompatButton>(R.id.actv_test_tts1).setOnClickListener {
|
||||||
TtsManager.speakTTSVoice("此时每个单兵要负责自己的一个视线防区")
|
//TtsInnerManager.speakTTSVoice("此时每个单兵要负责自己的一个视线防区")
|
||||||
|
val info = "此时每个单兵要负责自己的一个视线防区${ranx.nextInt()}"
|
||||||
|
TtsLogManager.d(TAG,"要播放的语音:${info}")
|
||||||
|
ttsManager.speakTTSVoice(info,object :IMogoTTSCallback{
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
TtsLogManager.d(TAG,"onSpeakStart:${speakText}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?) {
|
||||||
|
TtsLogManager.d(TAG,"onSpeakComple:${speakText}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTts(speakText: String?) {
|
||||||
|
TtsLogManager.d(TAG,"onStopTts:${speakText}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||||
|
TtsLogManager.d(TAG,"onSpeakError:${speakText}")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
findViewById<AppCompatButton>(R.id.actv_test_tts2).setOnClickListener {
|
findViewById<AppCompatButton>(R.id.actv_test_tts2).setOnClickListener {
|
||||||
TtsManager.stopTTS()
|
ttsManager.stopTTS()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ttsManager.bindService(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ class MoGoApplication : Application() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initTts() {
|
private fun initTts() {
|
||||||
TtsManager.init(this)
|
TTSService.start(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import android.os.Build
|
|||||||
object PhoneUtilsExtend {
|
object PhoneUtilsExtend {
|
||||||
|
|
||||||
fun getDevicesSn(): String {
|
fun getDevicesSn(): String {
|
||||||
return Build.getSerial()
|
return "name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.mogo.tts;
|
||||||
|
|
||||||
|
import com.mogo.tts.ITTSCallbackBinder;
|
||||||
|
|
||||||
|
interface ICoreBinder {
|
||||||
|
|
||||||
|
void speakTTSVoice1(String tts);
|
||||||
|
|
||||||
|
void speakTTSVoice2(String tts,in ITTSCallbackBinder callback);
|
||||||
|
|
||||||
|
void speakTTSVoic3(String tts, int languageType,in ITTSCallbackBinder callback);
|
||||||
|
|
||||||
|
void registerTtsListener(String tag,in ITTSCallbackBinder callback);
|
||||||
|
|
||||||
|
void unRegisterTtsListener(String tag);
|
||||||
|
|
||||||
|
void clearTtsListener();
|
||||||
|
|
||||||
|
void stopTts();
|
||||||
|
|
||||||
|
void stopTtsByText(String tts);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.mogo.tts;
|
||||||
|
|
||||||
|
|
||||||
|
oneway interface ITTSCallbackBinder {
|
||||||
|
void onSpeakStart(String speakText);
|
||||||
|
void onSpeakComple(String speakText);
|
||||||
|
void onStopTts(String speakText);
|
||||||
|
void onSpeakError(String speakText,String errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
package com.mogo.tts
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.Service
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.IBinder
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import com.mogo.tts.common.IMogoTTSCallback
|
||||||
|
import com.mogo.tts.common.LangTtsEntity
|
||||||
|
import com.mogo.tts.common.R
|
||||||
|
import com.mogo.tts.common.log.TtsLogManager
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
class TTSService : Service() {
|
||||||
|
|
||||||
|
private val TAG = "TTSService"
|
||||||
|
|
||||||
|
private val globalStart = "global_"
|
||||||
|
|
||||||
|
// 🔥 最佳方案:ConcurrentHashMap 管理回调(key = tag,value = 回调)
|
||||||
|
private val callbackMap = ConcurrentHashMap<String, ITTSCallbackBinder>()
|
||||||
|
|
||||||
|
|
||||||
|
private val iCorebinder = object : ICoreBinder.Stub() {
|
||||||
|
override fun speakTTSVoice1(tts: String?) {
|
||||||
|
// 防御空字符串
|
||||||
|
val text = tts?.takeIf { it.isNotEmpty() } ?: return
|
||||||
|
TtsInnerManager.speakTTSVoice(tts)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun speakTTSVoice2(tts: String?, callback: ITTSCallbackBinder?) {
|
||||||
|
// 防御空字符串
|
||||||
|
val text = tts?.takeIf { it.isNotEmpty() } ?: return
|
||||||
|
if(callback==null){
|
||||||
|
TtsInnerManager.speakTTSVoice(tts)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 先缓存 callback
|
||||||
|
callbackMap[text] = callback
|
||||||
|
|
||||||
|
TtsInnerManager.speakTTSVoice(tts,object :IMogoTTSCallback{
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakStart(speakText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?){
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakComple(speakText)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTts(speakText: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onStopTts(speakText)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakError(speakText,errorMsg)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun speakTTSVoic3(tts: String?, languageType: Int, callback: ITTSCallbackBinder?) {
|
||||||
|
// 防御空字符串
|
||||||
|
val text = tts?.takeIf { it.isNotEmpty() } ?: return
|
||||||
|
if(callback==null){
|
||||||
|
TtsInnerManager.speakTTSVoice(tts)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 先缓存 callback
|
||||||
|
callbackMap[text] = callback
|
||||||
|
|
||||||
|
val langTtsEntity = LangTtsEntity.getLangTtsEntity(tts, languageType)
|
||||||
|
|
||||||
|
TtsInnerManager.speakTTSVoice(langTtsEntity,object :IMogoTTSCallback{
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakStart(speakText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakComple(speakText)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTts(speakText: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onStopTts(speakText)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||||
|
val cb = callbackMap[speakText] ?: return
|
||||||
|
safeCallback {
|
||||||
|
cb.onSpeakError(speakText,errorMsg)
|
||||||
|
}
|
||||||
|
// ✅ 执行完自动销毁 callback
|
||||||
|
callbackMap.remove(speakText)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerTtsListener(tag: String?, callback: ITTSCallbackBinder?) {
|
||||||
|
if(tag.isNullOrEmpty()){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(callback==null){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val key = "${globalStart}${tag}"
|
||||||
|
callbackMap[key] = callback
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unRegisterTtsListener(tag: String?) {
|
||||||
|
if(tag.isNullOrEmpty()){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val key = "${globalStart}${tag}"
|
||||||
|
callbackMap.remove(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearTtsListener() {
|
||||||
|
callbackMap.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopTts() {
|
||||||
|
TtsInnerManager.stopTTS()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun stopTtsByText(tts: String?) {
|
||||||
|
// TODO: 如果正在播放直接停止、如果在排队播放从队伍中移除
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object{
|
||||||
|
fun start(context: Context) {
|
||||||
|
val serviceIntent = Intent(context, TTSService::class.java)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
context.startForegroundService(serviceIntent)
|
||||||
|
} else {
|
||||||
|
context.startService(serviceIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
TtsLogManager.d(TAG,"onCreate")
|
||||||
|
TtsInnerManager.init(applicationContext)
|
||||||
|
TtsInnerManager.registerTtsListener(object :IMogoTTSCallback{
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
callbackMap.forEach {
|
||||||
|
if (it.key.startsWith(globalStart)) {
|
||||||
|
safeCallback {
|
||||||
|
it.value.onSpeakStart(speakText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?) {
|
||||||
|
callbackMap.forEach {
|
||||||
|
if (it.key.startsWith(globalStart)) {
|
||||||
|
safeCallback {
|
||||||
|
it.value.onSpeakComple(speakText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String) {
|
||||||
|
callbackMap.forEach {
|
||||||
|
if (it.key.startsWith(globalStart)) {
|
||||||
|
safeCallback {
|
||||||
|
it.value.onSpeakError(speakText,errorMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
|
TtsLogManager.d(TAG,"onBind")
|
||||||
|
return iCorebinder
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
TtsLogManager.d(TAG,"onStartCommand")
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
if (manager != null) {
|
||||||
|
val nc = NotificationChannel("Voice", "语音服务", NotificationManager.IMPORTANCE_HIGH)
|
||||||
|
manager.createNotificationChannel(nc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val notification: Notification = NotificationCompat.Builder(applicationContext, "Voice")
|
||||||
|
.setContentTitle("语音服务运行中")
|
||||||
|
.setSmallIcon(R.drawable.voice_manager_icon)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
startForeground(1, notification)
|
||||||
|
return START_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
TtsLogManager.d(TAG,"onDestroy")
|
||||||
|
super.onDestroy()
|
||||||
|
TtsInnerManager.unRegisterTtsListener()
|
||||||
|
TtsInnerManager.release()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 跨进程回调安全工具方法
|
||||||
|
private inline fun safeCallback(call: () -> Unit) {
|
||||||
|
try {
|
||||||
|
call()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
TtsLogManager.e(TAG,e.toString(),e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.mogo.tts
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.mogo.tts.common.IMogoTTS
|
||||||
|
import com.mogo.tts.common.IMogoTTSCallback
|
||||||
|
import com.mogo.tts.common.LangTtsEntity
|
||||||
|
import com.mogo.tts.common.LanguageType
|
||||||
|
import com.mogo.tts.common.log.TtsLogManager
|
||||||
|
|
||||||
|
object TtsInnerManager {
|
||||||
|
|
||||||
|
private const val TAG = "TtsManager"
|
||||||
|
|
||||||
|
private var mTTS: IMogoTTS? = null
|
||||||
|
|
||||||
|
fun init(context: Context) {
|
||||||
|
try {
|
||||||
|
// 暂时换成反射,解决死锁问题
|
||||||
|
var clazz1: Class<*>? = null
|
||||||
|
try {
|
||||||
|
// clazz1 = Class.forName("com.mogo.tts.iflytek.offline.IFlyTekOfflineTts")
|
||||||
|
clazz1 = Class.forName("com.k2fsa.sherpa.onnx.MogoOfflineTTS")
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clazz1 != null) {
|
||||||
|
mTTS = clazz1.getConstructor().newInstance() as IMogoTTS
|
||||||
|
}
|
||||||
|
mTTS?.initTts(context)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
TtsLogManager.d(TAG, "TTS 模块初始化异常")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun speakTTSVoice(tts: String?) {
|
||||||
|
if(tts.isNullOrEmpty()) return
|
||||||
|
speakTTSVoice(tts,null)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun speakTTSVoice(tts: String?, callBack: IMogoTTSCallback?) {
|
||||||
|
if(tts.isNullOrEmpty()) return
|
||||||
|
speakTTSVoice(LangTtsEntity(tts, LanguageType.CHINESE), callBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun speakTTSVoice(ttsEntity: LangTtsEntity, callBack: IMogoTTSCallback?) {
|
||||||
|
if(ttsEntity.ttsContent.isEmpty()){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mTTS?.speakTTSVoice(ttsEntity, callBack)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerTtsListener(callback: IMogoTTSCallback) {
|
||||||
|
mTTS?.registerTtsListener(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unRegisterTtsListener() {
|
||||||
|
mTTS?.unRegisterTtsListener()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopTTS() {
|
||||||
|
mTTS?.stopTts()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun release() {
|
||||||
|
mTTS?.release()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,42 +1,33 @@
|
|||||||
package com.mogo.tts
|
package com.mogo.tts
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.mogo.tts.common.IGlobalTtsCallback
|
import android.content.Intent
|
||||||
import com.mogo.tts.common.IMogoTTS
|
import android.content.ServiceConnection
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.os.RemoteException
|
||||||
|
import com.elegant.utils.UiThreadHandler
|
||||||
import com.mogo.tts.common.IMogoTTSCallback
|
import com.mogo.tts.common.IMogoTTSCallback
|
||||||
import com.mogo.tts.common.LangTtsEntity
|
import com.mogo.tts.common.LangTtsEntity
|
||||||
import com.mogo.tts.common.LanguageType
|
import com.mogo.tts.common.LanguageType
|
||||||
import com.mogo.tts.common.log.TtsLogManager
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
object TtsManager {
|
class TtsManager {
|
||||||
|
companion object {
|
||||||
private const val TAG = "TtsManager"
|
private const val SERVER_PACKAGE: String = "com.mogo.tts"
|
||||||
|
|
||||||
private var mTTS: IMogoTTS? = null
|
|
||||||
|
|
||||||
fun init(context: Context) {
|
|
||||||
try {
|
|
||||||
// 暂时换成反射,解决死锁问题
|
|
||||||
var clazz1: Class<*>? = null
|
|
||||||
try {
|
|
||||||
//clazz1 = Class.forName("com.mogo.tts.iflytek.offline.IFlyTekOfflineTts")
|
|
||||||
clazz1 = Class.forName("com.k2fsa.sherpa.onnx.MogoOfflineTTS")
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clazz1 != null) {
|
|
||||||
mTTS = clazz1.getConstructor().newInstance() as IMogoTTS
|
|
||||||
}
|
|
||||||
mTTS?.initTts(context)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
TtsLogManager.d(TAG, "TTS 模块初始化异常")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val isBind = AtomicBoolean(false)
|
||||||
|
private val isServiceException = AtomicBoolean(false) //服务绑定成功后出现异常
|
||||||
|
protected var binder: ICoreBinder? = null
|
||||||
|
|
||||||
|
private var context: Context? = null
|
||||||
|
|
||||||
fun speakTTSVoice(tts: String?) {
|
fun speakTTSVoice(tts: String?) {
|
||||||
if(tts.isNullOrEmpty()) return
|
if(tts.isNullOrEmpty()) return
|
||||||
speakTTSVoice(tts,null)
|
speakTTSVoice(LangTtsEntity(tts, LanguageType.CHINESE), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -49,24 +40,172 @@ object TtsManager {
|
|||||||
if(ttsEntity.ttsContent.isEmpty()){
|
if(ttsEntity.ttsContent.isEmpty()){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mTTS?.speakTTSVoice(ttsEntity, callBack)
|
if(binder!=null){
|
||||||
|
try {
|
||||||
|
binder?.speakTTSVoic3(ttsEntity.ttsContent,ttsEntity.getLanguageDef(),object :
|
||||||
|
ITTSCallbackBinder.Stub() {
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
callBack?.onSpeakStart(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?) {
|
||||||
|
callBack?.onSpeakComple(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTts(speakText: String?) {
|
||||||
|
callBack?.onStopTts(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||||
|
callBack?.onSpeakError(speakText,errorMsg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerTtsListener(key: String, callback: IGlobalTtsCallback) {
|
fun registerTtsListener(tag:String,callback: IMogoTTSCallback) {
|
||||||
mTTS?.registerTtsListener(key, callback)
|
if(binder!=null){
|
||||||
|
try {
|
||||||
|
binder?.registerTtsListener(tag,object :ITTSCallbackBinder.Stub(){
|
||||||
|
override fun onSpeakStart(speakText: String?) {
|
||||||
|
callback.onSpeakStart(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakComple(speakText: String?) {
|
||||||
|
callback.onSpeakComple(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTts(speakText: String?) {
|
||||||
|
callback.onStopTts(speakText)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSpeakError(speakText: String?, errorMsg: String?) {
|
||||||
|
callback.onSpeakError(speakText,errorMsg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unRegisterTtsListener(key: String) {
|
fun unRegisterTtsListener(tag: String) {
|
||||||
mTTS?.unRegisterTtsListener(key)
|
if(binder!=null){
|
||||||
|
try {
|
||||||
|
binder?.unRegisterTtsListener(tag)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopTTS() {
|
fun stopTTS() {
|
||||||
mTTS?.stopTts()
|
if(binder!=null){
|
||||||
|
try {
|
||||||
|
binder?.stopTts()
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun release() {
|
fun stopTTS(tts:String) {
|
||||||
mTTS?.release()
|
if(binder!=null){
|
||||||
|
try {
|
||||||
|
binder?.stopTtsByText(tts)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val connection = object : ServiceConnection {
|
||||||
|
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||||
|
binder = ICoreBinder.Stub.asInterface(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onServiceDisconnected(name: ComponentName?) {
|
||||||
|
isServiceException.set(true);
|
||||||
|
unbind()
|
||||||
|
delayBind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bindService(
|
||||||
|
context: Context,
|
||||||
|
) {
|
||||||
|
this.context = context
|
||||||
|
bindService()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindService() {
|
||||||
|
context?.let {
|
||||||
|
if (!isBind.get()) {
|
||||||
|
if (isServerInstalled()) {
|
||||||
|
isBind.set(true)
|
||||||
|
val intent = Intent("com.mogo.tts.ttsservice")
|
||||||
|
intent.setPackage(SERVER_PACKAGE)
|
||||||
|
val isSuccess: Boolean =
|
||||||
|
it.bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||||
|
if (!isSuccess) {
|
||||||
|
unbind()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unbind() {
|
||||||
|
if (binder != null) {
|
||||||
|
try {
|
||||||
|
binder?.clearTtsListener()
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
binder = null
|
||||||
|
}
|
||||||
|
context?.let {
|
||||||
|
if (isBind.get()) {
|
||||||
|
isBind.set(false)
|
||||||
|
try {
|
||||||
|
it.unbindService(connection)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun delayBind() {
|
||||||
|
if (isServiceException.get()) {
|
||||||
|
isServiceException.set(false)
|
||||||
|
UiThreadHandler.postDelayed({
|
||||||
|
bindService()
|
||||||
|
}, 4000L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isServerInstalled(): Boolean {
|
||||||
|
context?.let {
|
||||||
|
val pm: PackageManager = it.getPackageManager()
|
||||||
|
return try {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
pm.getApplicationInfo(
|
||||||
|
SERVER_PACKAGE,
|
||||||
|
PackageManager.ApplicationInfoFlags.of(0)
|
||||||
|
).enabled
|
||||||
|
} else {
|
||||||
|
pm.getApplicationInfo(SERVER_PACKAGE, 0).enabled
|
||||||
|
}
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
package com.mogo.tts.common
|
package com.mogo.tts.common
|
||||||
|
|
||||||
interface IGlobalTtsCallback {
|
interface IGlobalTtsCallback {
|
||||||
fun onTtsSpeakStart()
|
fun onTtsSpeakStart(speakText: String?)
|
||||||
|
|
||||||
fun onTtsSpeakEnd()
|
fun onTtsSpeakEnd(speakText: String?)
|
||||||
|
|
||||||
|
fun onTtsSpeakComple(speakText: String?)
|
||||||
|
|
||||||
|
fun onTtsSpeakError(speakText: String?, errorMsg: String)
|
||||||
}
|
}
|
||||||
@@ -18,9 +18,9 @@ interface IMogoTTS {
|
|||||||
*/
|
*/
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
void registerTtsListener(String key, IGlobalTtsCallback callback);
|
void registerTtsListener(IMogoTTSCallback callback);
|
||||||
|
|
||||||
void unRegisterTtsListener(String key);
|
void unRegisterTtsListener();
|
||||||
|
|
||||||
void speakTTSVoice(LangTtsEntity ttsEntity, IMogoTTSCallback callBack);
|
void speakTTSVoice(LangTtsEntity ttsEntity, IMogoTTSCallback callBack);
|
||||||
|
|
||||||
|
|||||||
@@ -9,46 +9,10 @@ public
|
|||||||
*/
|
*/
|
||||||
interface IMogoTTSCallback {
|
interface IMogoTTSCallback {
|
||||||
|
|
||||||
/**
|
|
||||||
* 新SDK接口
|
|
||||||
*
|
|
||||||
* @param ttsId
|
|
||||||
* @param tts
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
default void onTTSStart( String ttsId, String tts ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新SDK接口
|
|
||||||
*
|
|
||||||
* @param ttsId
|
|
||||||
* @param tts
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
default void onTTSEnd( String ttsId, String tts ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新SDK接口
|
|
||||||
*
|
|
||||||
* @param ttsId
|
|
||||||
* @param tts
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
default void onTTSError( String ttsId, String tts ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
default void onSpeakStart( String speakText ) {
|
default void onSpeakStart( String speakText ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
default void onSpeakComple( String speakText ) {
|
||||||
* 语音播报完毕
|
|
||||||
*
|
|
||||||
* @param speakText 播报内容
|
|
||||||
*/
|
|
||||||
default void onSpeakEnd( String speakText ) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void onStopTts( String speakText ) {
|
default void onStopTts( String speakText ) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.mogo.tts.common
|
||||||
|
|
||||||
|
data class LangTtsEntity(
|
||||||
|
var ttsContent: String,
|
||||||
|
var language: LanguageType
|
||||||
|
) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ttsContent is:$ttsContent,language is:${language.langName}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLanguageDef(): Int {
|
||||||
|
return when (language) {
|
||||||
|
LanguageType.CHINESE -> LanguageTypeDef.MODE_CHINESE
|
||||||
|
LanguageType.ENGLISH -> LanguageTypeDef.MODE_ENGLISH
|
||||||
|
LanguageType.KOREAN -> LanguageTypeDef.MODE_KOREAN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getLangTtsEntity(tts: String, languageType: Int): LangTtsEntity {
|
||||||
|
val languageType = when (languageType) {
|
||||||
|
LanguageTypeDef.MODE_ENGLISH -> {
|
||||||
|
LanguageType.ENGLISH
|
||||||
|
}
|
||||||
|
|
||||||
|
LanguageTypeDef.MODE_KOREAN -> {
|
||||||
|
LanguageType.KOREAN
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
LanguageType.CHINESE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LangTtsEntity(tts, languageType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.mogo.tts.common;
|
||||||
|
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface LanguageTypeDef{
|
||||||
|
public static final int MODE_CHINESE = 0;
|
||||||
|
public static final int MODE_ENGLISH = 1;
|
||||||
|
public static final int MODE_KOREAN = 2;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package com.mogo.tts.common
|
|
||||||
|
|
||||||
data class MultiLangTtsEntity(
|
|
||||||
private var ttsList: List<LangTtsEntity>
|
|
||||||
) {
|
|
||||||
companion object {
|
|
||||||
private const val TIMEOUT_MILLIS = 60000
|
|
||||||
}
|
|
||||||
|
|
||||||
private val stringBuffer by lazy {
|
|
||||||
StringBuffer()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var ttsIndex = 0
|
|
||||||
private var timeStamp: Long = 0
|
|
||||||
|
|
||||||
fun ttsNext(): LangTtsEntity? {
|
|
||||||
return if (ttsIndex in ttsList.indices) {
|
|
||||||
ttsList[ttsIndex++]
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun markTime() {
|
|
||||||
timeStamp = System.currentTimeMillis()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isTimeout():Boolean {
|
|
||||||
return timeStamp > 0 && System.currentTimeMillis() - timeStamp >= TIMEOUT_MILLIS
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return stringBuffer.let {
|
|
||||||
it.setLength(0)
|
|
||||||
ttsList.forEachIndexed { index, langTtsEntity ->
|
|
||||||
if (index != ttsList.size - 1) {
|
|
||||||
it.append("${langTtsEntity};")
|
|
||||||
} else {
|
|
||||||
it.append(langTtsEntity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
it.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class LangTtsEntity(
|
|
||||||
var ttsContent: String,
|
|
||||||
var language: LanguageType
|
|
||||||
) {
|
|
||||||
override fun toString(): String {
|
|
||||||
return "ttsContent is:$ttsContent,language is:${language.langName}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@ import android.content.Context;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import com.elegant.utils.UiThreadHandler;
|
import com.elegant.utils.UiThreadHandler;
|
||||||
import com.mogo.tts.common.IGlobalTtsCallback;
|
|
||||||
import com.mogo.tts.common.IMogoTTS;
|
import com.mogo.tts.common.IMogoTTS;
|
||||||
import com.mogo.tts.common.IMogoTTSCallback;
|
import com.mogo.tts.common.IMogoTTSCallback;
|
||||||
import com.mogo.tts.common.LangTtsEntity;
|
import com.mogo.tts.common.LangTtsEntity;
|
||||||
@@ -20,7 +19,7 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
protected volatile LangTtsEntity curTtsEntity = null;
|
protected volatile LangTtsEntity curTtsEntity = null;
|
||||||
|
|
||||||
protected HashMap<String, IMogoTTSCallback> speakVoiceMap = new HashMap<>();
|
protected HashMap<String, IMogoTTSCallback> speakVoiceMap = new HashMap<>();
|
||||||
protected HashMap<String, IGlobalTtsCallback> mGlobalTtsCallback = new HashMap<>();
|
protected IMogoTTSCallback mGlobalTtsCallback = null;
|
||||||
|
|
||||||
protected String getTAG() {
|
protected String getTAG() {
|
||||||
return "BaseMogoTTS";
|
return "BaseMogoTTS";
|
||||||
@@ -31,14 +30,12 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerTtsListener(String key,IGlobalTtsCallback callback) {
|
public void registerTtsListener(IMogoTTSCallback callback) {
|
||||||
if (!mGlobalTtsCallback.containsKey(key)) {
|
this.mGlobalTtsCallback = callback;
|
||||||
this.mGlobalTtsCallback.put(key,callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unRegisterTtsListener(String key){
|
public void unRegisterTtsListener(){
|
||||||
this.mGlobalTtsCallback.remove(key);
|
this.mGlobalTtsCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,7 +56,6 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void speakMultiLangTTS(LangTtsEntity ttsEntity){
|
protected void speakMultiLangTTS(LangTtsEntity ttsEntity){
|
||||||
this.curTtsEntity = ttsEntity;
|
|
||||||
// 合成并播放
|
// 合成并播放
|
||||||
TtsLogManager.d(getTAG(), "tts准备合成:"+ttsEntity);
|
TtsLogManager.d(getTAG(), "tts准备合成:"+ttsEntity);
|
||||||
}
|
}
|
||||||
@@ -80,7 +76,7 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
if (speakVoiceMap.containsKey(key)) {
|
if (speakVoiceMap.containsKey(key)) {
|
||||||
IMogoTTSCallback remove = speakVoiceMap.remove(key);
|
IMogoTTSCallback remove = speakVoiceMap.remove(key);
|
||||||
if(remove!=null) {
|
if(remove!=null) {
|
||||||
remove.onStopTts(key);
|
remove.onStopTts(curTtsEntity.getTtsContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curTtsEntity = null;
|
curTtsEntity = null;
|
||||||
@@ -89,31 +85,27 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onSpeakBegin() {
|
public void onSpeakBegin() {
|
||||||
if(!mGlobalTtsCallback.isEmpty()) {
|
if(mGlobalTtsCallback != null) {
|
||||||
for (IGlobalTtsCallback callback : mGlobalTtsCallback.values()) {
|
mGlobalTtsCallback.onSpeakStart(curTtsContent);
|
||||||
callback.onTtsSpeakStart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (curTtsEntity!=null) {
|
if (curTtsEntity!=null) {
|
||||||
String key = curTtsEntity.toString();
|
String key = curTtsEntity.toString();
|
||||||
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
||||||
if(iMogoTTSCallback!=null){
|
if(iMogoTTSCallback!=null){
|
||||||
iMogoTTSCallback.onSpeakStart(key);
|
iMogoTTSCallback.onSpeakStart(curTtsEntity.getTtsContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleCompleteEvent() {
|
public void handleCompleteEvent() {
|
||||||
if(!mGlobalTtsCallback.isEmpty()) {
|
if(mGlobalTtsCallback!=null) {
|
||||||
for (IGlobalTtsCallback callback : mGlobalTtsCallback.values()) {
|
mGlobalTtsCallback.onSpeakComple(curTtsContent);
|
||||||
callback.onTtsSpeakEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (curTtsEntity!=null) {
|
if (curTtsEntity!=null) {
|
||||||
String key = curTtsEntity.toString();
|
String key = curTtsEntity.toString();
|
||||||
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
||||||
if(iMogoTTSCallback!=null){
|
if(iMogoTTSCallback!=null){
|
||||||
iMogoTTSCallback.onSpeakEnd(key);
|
iMogoTTSCallback.onSpeakComple(curTtsEntity.getTtsContent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curTtsEntity = null;
|
curTtsEntity = null;
|
||||||
@@ -121,18 +113,19 @@ public abstract class BaseMogoTTS implements IMogoTTS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void handleErrorEvent(String error) {
|
public void handleErrorEvent(String error) {
|
||||||
|
if(mGlobalTtsCallback!=null) {
|
||||||
|
mGlobalTtsCallback.onSpeakError(curTtsContent,error);
|
||||||
|
}
|
||||||
if (curTtsEntity != null) {
|
if (curTtsEntity != null) {
|
||||||
String key = curTtsEntity.toString();
|
String key = curTtsEntity.toString();
|
||||||
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(key);
|
||||||
if(iMogoTTSCallback!=null){
|
if(iMogoTTSCallback!=null){
|
||||||
iMogoTTSCallback.onSpeakError(key,
|
iMogoTTSCallback.onSpeakError(curTtsEntity.getTtsContent(), error);
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(curTtsContent);
|
IMogoTTSCallback iMogoTTSCallback = speakVoiceMap.get(curTtsContent);
|
||||||
if(iMogoTTSCallback!=null){
|
if(iMogoTTSCallback!=null){
|
||||||
iMogoTTSCallback.onSpeakError(curTtsContent,
|
iMogoTTSCallback.onSpeakError(curTtsContent, error);
|
||||||
error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curTtsEntity = null;
|
curTtsEntity = null;
|
||||||
|
|||||||
@@ -48,4 +48,12 @@ object TtsLogManager {
|
|||||||
}
|
}
|
||||||
logListener?.writeLog(LogLevel.error,tag,message)
|
logListener?.writeLog(LogLevel.error,tag,message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun e(tag: String, message: String,tr:Throwable?) {
|
||||||
|
if(isDebug) {
|
||||||
|
Log.e(tag, message,tr)
|
||||||
|
}
|
||||||
|
logListener?.writeLog(LogLevel.error,tag,message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
||||||
|
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,15c1.66,0 2.99,-1.34 2.99,-3L15,6c0,-1.66 -1.34,-3 -3,-3S9,4.34 9,6v6c0,1.66 1.34,3 3,3zM17.3,12c0,3 -2.54,5.1 -5.3,5.1S6.7,15 6.7,12L5,12c0,3.42 2.72,6.23 6,6.72L11,22h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z"/>
|
||||||
|
|
||||||
|
</vector>
|
||||||
@@ -129,6 +129,7 @@ class IFlyTekOfflineTts : BaseMogoTTS() {
|
|||||||
|
|
||||||
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
|
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
|
||||||
langTtsEntity?.let {
|
langTtsEntity?.let {
|
||||||
|
curTtsEntity = it
|
||||||
curTtsContent = it.ttsContent
|
curTtsContent = it.ttsContent
|
||||||
realSpeak(it.ttsContent)
|
realSpeak(it.ttsContent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ class MogoOfflineTTS : BaseMogoTTS() {
|
|||||||
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
|
private fun startSpeak(langTtsEntity: LangTtsEntity?) {
|
||||||
stopTts()
|
stopTts()
|
||||||
langTtsEntity?.let {
|
langTtsEntity?.let {
|
||||||
|
this.curTtsEntity = langTtsEntity;
|
||||||
curTtsContent = it.ttsContent
|
curTtsContent = it.ttsContent
|
||||||
realSpeak(it.ttsContent)
|
realSpeak(it.ttsContent)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user