|
|

楼主 |
发表于 2025-9-18 16:06:31
|
显示全部楼层
遇到的第二个问题:
初始化成功之后,报初始化不完全,就应用tts来Speak了,因此报错:
TextToSpeech cn.unicoder.myttstest W speak failed: TTS engine connection not fully set up
这个警告信息与之前的问题类似,是因为 TTS 引擎连接尚未完全建立就尝试调用 speak 方法。我们需要在 TTS 完全初始化后再调用 speak 方法。
问题分析
TTS 引擎初始化是异步过程
你在初始化完成前就调用了 speak 方法
即使加了 try-catch,仍然会有警告信息
解决方案
修改 TtsHelper.java 文件,添加初始化状态检查和回调机制
- package cn.unicoder.myttstest;
- import android.content.Context;
- import android.speech.tts.TextToSpeech;
- import android.util.Log;
- import java.util.Locale;
- public class TtsHelper {
- private TextToSpeech mTTS;
- private boolean isInitialized = false;
- public TtsHelper(Context context) {
- mTTS = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
- @Override
- public void onInit(int status) {
- if (status == TextToSpeech.SUCCESS) {
- // TTS engine is successfully initialized.
- Log.d("TTS", "初始化成功");
- isInitialized = true;
- // 设置语言为中文
- int result = mTTS.setLanguage(Locale.CHINESE);
- if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
- Log.e("TTS", "不支持中文语言");
- isInitialized = false;
- }
- } else {
- // Failed to initialize TTS engine.
- Log.e("TTS", "初始化失败,状态码: " + status);
- isInitialized = false;
- }
- }
- });
- }
-
- // 添加语音合成方法
- public void speak(String text) {
- if (mTTS != null && isInitialized) {
- try {
- mTTS.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
- } catch (Exception e) {
- Log.e("TTS", "语音合成失败: " + e.getMessage());
- }
- } else {
- Log.w("TTS", "TTS 尚未初始化完成,无法播放: " + text);
- }
- }
-
- // 添加带回调的语音合成方法
- public void speakWhenReady(String text) {
- if (isInitialized) {
- speak(text);
- } else {
- // 如果尚未初始化完成,等待初始化后再播放
- Thread waitThread = new Thread(() -> {
- int attempts = 0;
- while (!isInitialized && attempts < 50) { // 最多等待5秒
- try {
- Thread.sleep(100);
- attempts++;
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return;
- }
- }
- if (isInitialized) {
- speak(text);
- } else {
- Log.e("TTS", "TTS 初始化超时");
- }
- });
- waitThread.start();
- }
- }
-
- public void shutdown() {
- isInitialized = false;
- if (mTTS != null) {
- mTTS.stop();
- mTTS.shutdown();
- }
- }
-
- // 检查是否已初始化
- public boolean isReady() {
- return isInitialized;
- }
- }
复制代码
同时修改 MainActivity.kt 文件:
- package cn.unicoder.myttstest
- import android.os.Bundle
- import androidx.activity.ComponentActivity
- import androidx.activity.compose.setContent
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.material3.Button
- import androidx.compose.material3.MaterialTheme
- import androidx.compose.material3.Surface
- import androidx.compose.material3.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.tooling.preview.Preview
- import cn.unicoder.myttstest.ui.theme.MyTtsTestTheme
- class MainActivity : ComponentActivity() {
- private var tts: TtsHelper? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- tts = TtsHelper(this)
-
- setContent {
- MyTtsTestTheme {
- Surface(
- modifier = Modifier.fillMaxSize(),
- color = MaterialTheme.colorScheme.background
- ) {
- TtsScreen(tts)
- }
- }
- }
- }
-
- override fun onDestroy() {
- super.onDestroy()
- tts?.shutdown()
- }
- }
- @Composable
- fun TtsScreen(tts: TtsHelper?) {
- Column {
- Greeting("Android")
- Button(onClick = {
- tts?.speakWhenReady("你好, 世界!")
- }) {
- Text("说话")
- }
- }
- }
- @Composable
- fun Greeting(name: String, modifier: Modifier = Modifier) {
- Text(
- text = "Hello $name!",
- modifier = modifier
- )
- }
- @Preview(showBackground = true)
- @Composable
- fun GreetingPreview() {
- MyTtsTestTheme {
- TtsScreen(null)
- }
- }
复制代码
主要改进点
1、添加 isInitialized 标志来跟踪 TTS 是否已完全初始化
2、在 speak 方法中检查初始化状态
3、添加 speakWhenReady 方法,可以等待 TTS 初始化完成后再播放
4、设置语言为中文 (Locale.CHINESE)
5、添加 isReady() 方法检查 TTS 状态
这样修改后,应该不会再出现 "TTS engine connection not fully set up" 的警告了。 |
|