【问题标题】:Text to speech returns a different non-existant Locale after setting an existing one文本到语音在设置现有区域后返回不同的不存在的区域设置
【发布时间】:2014-01-31 13:53:39
【问题描述】:

原始问题

我有一个标准的文本语音,android.speech.tts.TextToSpeech

我初始化它并使用tts.setLanguage(Locale.getDefault())设置语言

默认区域设置是 de_DE(对于德国,正确)。 设置好之后,我要求 tts 给我它的语言tts.getLanguage()

现在它告诉我它设置为“deu_DEU”

该设置没有区域设置。所以我什至无法检查它是否设置为正确的语言,因为我找不到具有匹配值的 Locale 对象。

问题可能与 Android 4.3 有关,但我没有找到任何信息。

背景是,我需要用相同的十进制符号显示值,但 tts 需要正确的符号,或者它用德语说“点”,这根本没有意义。

结论:

区域设置是一个容器,其中包含由语言、国家和可选字符串组成的字符串。每个文本转语音引擎都可以返回自定义区域设置,例如“eng_USA_texas”。

此外,tts 引擎返回的区域设置只能是与所需区域设置的“紧密匹配”。所以“en_US”而不是“en_UK”。

然而,Locale 有一个名为getLanguage() 的方法,它返回上述字符串的第一部分。 “en”或“eng”。这些语言代码由 ISO 规范,希望每个人都遵守它。 (请参阅已接受答案中的链接)

因此,如果 tts.getLanguage().getLanguage().startsWith("en") 的某种形式的英语语言设置和 ISO 标准得到满足,那么检查它应该始终为真。

值得一提的是,Locales 不应与 locale_a == locale_b 进行比较,因为两者可以是不同的对象但具有相同的内容,它们是排序的容器。
总是与locale_a.equals(locale_b)比较

我希望这可以帮助人们解决 tts 和语言方面的一些问题

【问题讨论】:

  • 编辑了我的答案,以防您没有看到链接中的措辞

标签: android text-to-speech


【解决方案1】:

您说得对,令人沮丧的是,TTS 对象使用的语言环境代码与设备语言环境的代码不同。我不明白为什么会做出这个决定。

更复杂的是,TTS 引擎can supply all kinds of different locales,例如 eng_US_sarah 或 en-US-female 等。这取决于 TTS 引擎如何存储和显示这些内容。

我不得不编写额外的代码来遍历返回的语言环境,并尝试将它们与系统可以使用的语言环境相匹配,反之亦然。

首先,看看你是如何安装引擎的are returning their locale information。然后,您可以开始在您的代码中整理一个列表,以将“deu_DEU”与“de_De”相关联。

这通常使用split("_")startsWith(String) 来简化,但不幸的是并非适用于所有语言环境。

这是我用来分析已安装 TTS 引擎的语言环境结构的一些基本代码。

private void getEngines() {

    final Intent ttsIntent = new Intent();
    ttsIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

    final PackageManager pm = getActivity().getPackageManager();

    final List<ResolveInfo> list = pm.queryIntentActivities(ttsIntent, PackageManager.GET_META_DATA);

    final ArrayList<Intent> intentArray = new ArrayList<Intent>(list.size());

    for (int i = 0; i < list.size(); i++) {

        final Intent getIntent = new Intent();
        getIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);

        getIntent.setPackage(list.get(i).activityInfo.applicationInfo.packageName);
        getIntent.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);

        intentArray.add(getIntent);

    }

    for (int i = 0; i < intentArray.size(); i++) {
        startActivityForResult(intentArray.get(i), i);
    }
}

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {

    try {

        if (data != null) {             
            System.out.print(data.getStringArrayListExtra("availableVoices").toString());
        }

    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

从上面的ISO-3 codesdevice locale format,您应该能够为您所关心的语言环境提出一些建议。

一段时间以来,我一直打算向 AOSP 提交增强请求,因为所有 TTS 引擎都需要使用常量值,并且需要添加诸如性别等extras 才能充分利用 TTS 引擎的功能。

编辑:在您的编辑之后,note the wording 关于setLanguage()。单个 TTS 引擎将尝试匹配尽可能接近请求的语言环境,但应用的语言环境可能完全错误,这取决于引擎提供者in their code and their response 的宽松程度。

【讨论】:

  • 感谢您的链接和信息,用其中的一些写了一个结论
  • 我假设 tts 引擎始终以标准格式 (xx_XX) 接受、理解和存储区域设置,但不一定根据该格式表示区域设置...大概是因为他们希望它更具人类可读性?这是错的吗?
  • PS @brandall 你在这里看起来很像文字转语音专家......如果你觉得无聊,我最近发布了大量的 TTS 问题! :)
【解决方案2】:

创建TextToSpeech 类的对象后,您应该将其配置(或检查它的可用状态/值)到TextToSpeech.OnInitListeneronInit() 回调中。您将在那里获得有关您的 TextToSpeech 对象的可靠信息。

在这里查看我的答案: https://stackoverflow.com/a/65620221/7835969

【讨论】:

    猜你喜欢
    • 2011-06-19
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多