3

我的 Android 应用程序检索 SHOUTcast 元数据并显示它。我遇到了非英语字符集的问题。基本上,元数据显示为乱码。我将如何执行字符编码检测并正确显示文本?抱歉,如果这是一个重要的问题,我对这个话题并不精通。

有问题的流是:http ://skully.hopto.org:8000

4

1 回答 1

8

正如vorrtex在上面的评论中指出的那样,如果您的数据来自格式良好的 HTML 代码,您可以从标签中知道它的编码<meta content="...">,这是最好的情况。您可以使用以下代码将其转换为 Android(或其他 Java 实现)字符串:

// assume you have your input data as byte array buf, and encoding
// something like "windows-1252", "UTF-8" or whatever
String str = new String(buf, encoding);
// now your string will display correctly

如果你不知道编码——你收到的数据是未知格式的原始文本——你仍然可以使用统计语言模型尝试算法来猜测它。我刚刚在http://site.icu-project.org/上找到了 IBM 的ICU - International Components for Unicode项目,具有自由开源许可(商业用途可以)

它们提供 Java 和 C++ 库。我刚刚添加了他们的 Java JAR 版本。51.2 到我的 Android 项目,它就像一个魅力。我用来从文本文件中识别字符编码的代码是:

public static String readFileAsStringGuessEncoding(String filePath)
{
    String s = null;
    try {
        File file = new File(filePath);
        byte [] fileData = new byte[(int)file.length()];
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        dis.readFully(fileData);
        dis.close();

        CharsetMatch match = new CharsetDetector().setText(fileData).detect();

        if (match != null) try {
            Lt.d("For file: " + filePath + " guessed enc: " + match.getName() + " conf: " + match.getConfidence());
            s = new String(fileData, match.getName());
        } catch (UnsupportedEncodingException ue) {
            s = null;
        }
        if (s == null)
            s = new String(fileData);
    } catch (Exception e) {
        Lt.e("Exception in readFileAsStringGuessEncoding(): " + e);
        e.printStackTrace();
    }
    return s;
}

上面的Lt.dLt.e只是我对Log.d(TAG, "blah...")的快捷方式。在我能想出的所有测试文件上工作得很好。我只是有点担心 APK 文件的大小——icu4j-51_2.jar 超过 9 MB 长,而我的整个包在添加之前只有 2.5 MB。但是很容易隔离 CharsetDetector 及其依赖项,所以我最终添加的大小不超过 50 kB。我需要从 ICU 源复制到我的项目的 Java 类都在 core/src/com/ibm/icu/text 目录下,并且是:

CharsetDetector
CharsetMatch
CharsetRecog_2022
CharsetRecog_mbcs
CharsetRecog_sbcs
CharsetRecog_Unicode
CharsetRecog_UTF8
CharsetRecognizer

此外,在 CharsetRecog_sbcs.java 中有一个受保护的“ArabicShaping as;” 成员,它想拉更多的类,但事实证明它不需要字符集识别,所以我把它注释掉了。就这样。希望能帮助到你。

格雷格

于 2013-06-19T23:25:16.260 回答