android - Android TextToSpeech 行为不规则
问题描述
更新:经过一番挖掘,我设法在 Logcat 中找到了一些信息。见底部。
编辑 2:我现在从头开始创建了一个新活动来减少问题。它仍然无法正常工作。这是代码:
public class MainActivity extends AppCompatActivity {
private TextToSpeech textToSpeech;
private boolean isInitialized = false;
private MainActivity mainActivity;
int ctr = 0;
private String words[] = {"ord", "kula", "fotboll"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mainActivity = this;
textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS){
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
System.out.println("---onStart");
}
@Override
public void onDone(String utteranceId) {
System.out.println("-----onDone");
}
@Override
public void onError(String utteranceId) {
System.out.println("-----onError");
}
@Override
public void onError(String utteranceId, int errorCode){
onError(utteranceId);
System.out.println("Error with code: " + errorCode);
}
});
isInitialized = true;
Locale locale = new Locale("swe");
textToSpeech.setLanguage(locale);
}
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isInitialized){
System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
textToSpeech.speak(words[ctr], TextToSpeech.QUEUE_FLUSH, null, "SpeakTest");
ctr++;
ctr %= words.length;
} else {
Snackbar.make(view, "Speaker not ready", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
}
}
非常令人惊讶的是,只有“ord”和“fotboll”这两个词被说出来,而没有“kula”。如果我改变words
并{"kula", "kula", "kula"}
尝试足够长的时间,它会突然开始工作。据我了解文档应该在这里使用标签。我试过se
, swe
, sv
, 结果都是一样的。此外,该命令System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
给出了svenska
正确的。
如果我改成en
它一直有效。我也System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
= engelska
再次正确。
到底是怎么回事?
编辑:
我添加了一个UtteranceProgressListener
,根据这个,方法
onError(String id)
已弃用,应替换为onError(String id, int errorCode)
. 但是,我已经扩展了我的类,UtteranceProgressListener
它迫使我实现旧onError
方法。这总是被调用,所以出了点问题,但我不知道是什么。
这是因为另一个onError(String id, int code)
从未被调用过。
我已经更新了代码。
我有一个函数,它应该在调用该函数时以特定语言说出一个单词。
直到几天前,它在我的 Sony Compact XZ2 上运行良好,但现在不正常了。有时会说出这个词,有时则不会。命令textToSpeech.getEngines()
返回com.google.android.tts
例如对于瑞典语,在创建对象setLanguage
时,我尝试了“sv”和“sv-SV” 。Locale
那没有帮助。
我只是注意到,当我按下playWord(text)
多次调用(> 40)的按钮时,它会起作用,有时它会直接起作用。似乎有些奇怪的延迟。
该函数speakText
是从 my 中的此函数调用的Fragment
:
private void playWord(){
if (text2Speech.isReady()) {
text2Speech.checkSpeaking();
text2Speech.setLanguage(getAcronym(mTraining.getCurrentSrc()));
text2Speech.speakText(front);
} else {
Toast.makeText(getContext(),"Speaker not ready yet", Toast.LENGTH_SHORT).show();
}
}
这是处理口语的类。我没有收到任何错误信息。当扬声器工作时,它似乎是随机的。
public class Text2Speech extends UtteranceProgressListener {
private Context mContext;
private TextToSpeech textToSpeech;
private boolean isReady = false;
public Text2Speech(Context context, final String src){
mContext = context;
System.out.println("text2Speech created");
textToSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
isReady = true;
Locale locale = new Locale(src);
int ttsLang = textToSpeech.setLanguage(locale);
if (ttsLang == TextToSpeech.LANG_MISSING_DATA
|| ttsLang == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "The Language is not supported!");
} else {
Log.i("TTS", "Language Supported.");
}
Log.i("TTS", "Initialization success.");
} else {
Toast.makeText(mContext, "TTS Initialization failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
public boolean isReady(){
return isReady;
}
public void checkSpeaking(){
if (textToSpeech.isSpeaking()){
textToSpeech.stop();
}
}
public void showMessage(String msg){
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
public void speakText(String text){
int speechStatus = textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
switch (speechStatus){
case TextToSpeech.ERROR_INVALID_REQUEST:
showMessage("Invalid Request");
break;
case TextToSpeech.ERROR_NETWORK:
showMessage("Network Error");
break;
case TextToSpeech.ERROR_NETWORK_TIMEOUT:
showMessage("Network Timeout");
break;
case TextToSpeech.ERROR_NOT_INSTALLED_YET:
showMessage("Error Not Yet Downloaded");
break;
case TextToSpeech.ERROR_OUTPUT:
showMessage("Output Error");
break;
case TextToSpeech.ERROR_SERVICE:
showMessage("Error of TTS service");
break;
case TextToSpeech.ERROR_SYNTHESIS:
showMessage("Error synthesizing");
break;
case TextToSpeech.LANG_NOT_SUPPORTED:
showMessage("Language nor supported");
break;
}
if (speechStatus == TextToSpeech.ERROR) {
Log.e("TTS", "Error in converting Text to Speech!");
}
System.out.println("speech status - text " + speechStatus + " - " + text);
}
public void setLanguage(String src){
Locale locale = new Locale(src);
int tts = textToSpeech.setLanguage(locale);
System.out.println(tts + " " + src);
if (tts == TextToSpeech.LANG_MISSING_DATA
|| tts == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(mContext, "Language not yet supported.", Toast.LENGTH_LONG).show();
}
}
public void stop(){
textToSpeech.stop();
textToSpeech.shutdown();
}
@Override
public void onStart(String utteranceId) {
Log.e("START", "start speaking");
}
@Override
public void onDone(String utteranceId) {
Log.e("DONE", "done speaking");
}
@Override
public void onError(String utteranceID){
Log.e("Error", "Not infromative");
}
// This is not called!
@Override
public void onError(String utteranceId, int errorCode) {
Log.e("Error", "Error speaking");
}
}
这是 Logcat 中的错误消息:
NetworkSynthesizer: ExecutionException during NetworkFetchTask
java.util.concurrent.ExecutionException: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
at java.util.concurrent.FutureTask.report(FutureTask.java:123)
at java.util.concurrent.FutureTask.get(FutureTask.java:207)
at avf.a(PG:37)
at avf.a(PG:154)
at com.google.android.tts.service.GoogleTTSService.onSynthesizeText(PG:250)
at android.speech.tts.TextToSpeechService$SynthesisSpeechItem.playImpl(TextToSpeechService.java:1033)
at android.speech.tts.TextToSpeechService$SpeechItem.play(TextToSpeechService.java:819)
at android.speech.tts.TextToSpeechService$SynthHandler$1.run(TextToSpeechService.java:583)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:280)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
at cze.a(PG:58)
at cze.a(PG:29)
at dao.a(PG:21)
at ave.a(PG:36)
at ave.call(PG:80)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
2019-03-16 21:35:46.917 1356-5238/? E/ActivityManager: Sending non-protected broadcast com.sonymobile.intent.action.POWER_BACK_OFF_FACTOR_CHANGED from system 2179:com.android.phone/1001 pkg com.android.phone
java.lang.Throwable
at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:21814)
at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:22423)
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:22565)
at android.app.IActivityManager$Stub.onTransact$broadcastIntent$(IActivityManager.java:10171)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:167)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3416)
at android.os.Binder.execTransact(Binder.java:731)
2019-03-16 21:35:46.917 12061-13318/? E/TTS.GoogleTTSServiceImp: Synthesis failure with error status code: -4
2019-03-16 21:35:46.918 12061-13318/? W/PlaybackSynthesisRequest: done() was called before start() call
2019-03-16 21:35:46.919 6468-6489/com.erikbylow.tailoreddictfire D/SPEECH: Error
当我打开 WiFi 时,它可以工作。
推测:会不会是我没有使用WiFi时语言丢失了,没有下载?当我打开WiFi时,语言被下载了?
对我来说这个错误:clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric...
看起来总是有网络请求,但打开 WiFi 后,我可以在飞行模式下使用 TextToSpeach。
另一方面,我在飞行模式下尝试了俄语,但没有奏效。我在没有WiFi的情况下打开了互联网,然后它工作了。再次打开WiFi,然后俄语也正常工作。至少这表明需要下载一些东西?
我想找出导致问题的原因以及如何解决它,因为它是 Google Play 上的一个应用程序。(虽然我目前只有 0 个活跃用户在我身边……):)。
解决方案
推荐阅读
- javascript - CSS 或 jQuery:如何获得可见的顶部
- sql-server - 数据库设计 - 从多个表中多次引用一个表
- visual-studio-2017 - Visual Studio 2017 未固定的选项卡不断返回
- google-app-engine - IAP 签名标头和 AppEngine 标准 Python 3.7 运行时
- android - 如何通过滑动打开另一个活动
- clearcase - 按月和用户需要的 Clearcase 报告
- ruby-on-rails - Rspec-mocks 不会引发异常
- sublimetext3 - 无法使用 apt-get 命令在 Ubuntu 16.04 中安装 Sublime Text 3
- ajax - 如何在 yii2 的删除操作中忽略 ajaxValidation?
- bash - 将计算命令传递给集群作业