首页 > 解决方案 > 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 个活跃用户在我身边……):)。

标签: androidtext-to-speechgoogle-text-to-speech

解决方案


推荐阅读