Android 上的 TextToSpeech 初始化——如果失败怎么办?

TextToSpeech initialization on Android -- what if it fails?

在Android中,如果一个TextToSpeech实例初始化失败(调用的回调表示TextToSpeech引擎初始化完成returnsTextToSpeech.ERROR),是否意味着后续尝试的方法对该实例的调用将导致空指针异常?

示例...

我们初始化对象:

t1 = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == TextToSpeech.ERROR) {
                    Log.i("XXX", "There was an error initializing the TTS");
                }
            }
        });

... 假设 init 失败了,但我们会继续执行以下操作:

t1.speak("hello");

这会崩溃……还是什么都不说?我问的原因是,如果它真的崩溃了,那么显然我将不得不在所有地方进行空检查。

另外,我无法自己找出原因是我不知道如何模拟错误。

感谢您提供任何先验知识。

您可以尝试使用此代码。

使用 https://www.w3schools.com/tags/ref_language_codes.asp 中的 language_codes

mLanguage = new Locale(language_codes);

tts = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status != TextToSpeech.ERROR) {
                int result = tts.setLanguage(mLanguage);
                if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                    Log.e("Text2SpeechWidget", result + " is not supported");
                }
            }
        }
    });

对于您的主要问题,请阅读 speak() 方法 (here) 的文档:

This method is asynchronous, i.e. the method just adds the request to the queue of TTS requests and then returns.

因此,除非您的 tts 实例是 null,否则它不应抛出任何异常或使应用程序崩溃,而只是 return 错误代码。

Also, the reason I can't just find out for myself is that I don't know how to simulate the error.

尝试使用期望作为第三个参数 String engine 的构造函数 (see docs) 并将无效的包名称放在那里。那么它应该可能会导致错误。 (或 disable/uninstall 您 device/emulator 上的所有 TTS 引擎)

关于构造函数需要注意的重要事项是:

In a case of a failure the listener may be called immediately, before TextToSpeech instance is fully constructed.

所以除非状态是SUCCESS,否则你不应该在监听器中触摸你的tts(当然你可以使用tts 之后就像你的例子一样)因为它甚至可能还没有被分配/初始化。

我遇到了这个问题,然后我注意到在某些设备上 TTS 可能被停用。所以我刚刚完成了以下操作

try {
        Intent intent = new Intent();
        intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(intent, 0);
    } catch(ActivityNotFoundException exception) {
        Uri uri = Uri.parse("market://details?id=" + "com.google.android.tts&hl=fr");
        Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
        goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        try {
            startActivity(goToMarket);
        } catch (ActivityNotFoundException e) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + "com.google.android.tts&hl=fr")));
        }
    }