Android中的字符集检测

Android中的字符集检测,android,character-encoding,metadata,Android,Character Encoding,Metadata,我的Android应用程序检索并显示SHOUTcast元数据。我没有英文字符集。基本上,元数据显示为胡言乱语。如何执行字符编码检测并正确显示文本?很抱歉,如果这是一个非常重要的问题,我对这个话题不太熟悉 所讨论的流是:正如Vortex在上面的评论中指出的,如果您的数据来自格式良好的HTML代码,您可以从标记中了解其编码,这是最好的方案。您可以使用以下代码将其转换为Android(或其他Java实现)字符串: // assume you have your input data as byte a

我的Android应用程序检索并显示SHOUTcast元数据。我没有英文字符集。基本上,元数据显示为胡言乱语。如何执行字符编码检测并正确显示文本?很抱歉,如果这是一个非常重要的问题,我对这个话题不太熟悉

所讨论的流是:

正如Vortex在上面的评论中指出的,如果您的数据来自格式良好的HTML代码,您可以从
标记中了解其编码,这是最好的方案。您可以使用以下代码将其转换为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
如果你不知道编码——你收到的数据是未知格式的原始文本——你仍然可以尝试使用统计语言模型的算法来猜测它。我刚刚找到IBM的ICU-International Components for Unicode项目,该项目具有开放源码许可(商业使用许可),位于

它们同时提供java和C++库。我刚刚添加了他们的javajar版本。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.d和Lt.e只是我对Log.d的快捷方式(标记“blah…”)。在我能想到的所有测试文件上都工作得很好。我只是有点担心APK文件的大小——icu4j-51_2.jar的长度超过9MB,在添加它之前,我的整个包只有2.5MB。但是很容易分离CharsetDetector及其依赖项,因此我最终添加的内存不超过50KB。我需要从ICU源代码复制到项目中的Java类都位于core/src/com/ibm/ICU/text目录下,它们是:

CharsetDetector
CharsetMatch
CharsetRecog_2022
CharsetRecog_mbcs
CharsetRecog_sbcs
CharsetRecog_Unicode
CharsetRecog_UTF8
CharsetRecognizer
此外,在CharsetRecog_sbcs.java中还有一个受保护的“arabicshapping as;”成员,它想拉更多的类,但结果表明,字符集识别不需要它,所以我对它进行了注释。这就是全部。希望能有帮助


Greg

这取决于数据来源。对于yout链接,您可以打开页面的HTML代码,您将看到行
。这意味着编码是Windows-1252,如果你只使用这个站点,你可以硬编码这个编码名称并一直使用它。同时,我应该将我还不知道的编码值传递给inputstreamreader。由于编码错误,字节信息完全丢失。尽管我以后可以从meta标记中获得正确的编码,但如何将其转换回正确的编码呢?我上面讨论的使用ICU库的方法适用于字节数组,不需要先转换为字符串。或者具有创造性,例如,将字节数组视为ASCII字符串来搜索标记,因为它们都是ASCII字符。我确实这样做了,但是JNI C++代码。谢谢ICU图书馆的好提示。看起来ArabicShaping成员在最近发布的Java库中不再制造任何问题。顺便说一句:注意到来自ICU库的子集将包含在Android N中。