我的 Android 应用程序检索 SHOUTcast 元数据并显示它。我遇到了非英语字符集的问题。基本上,元数据显示为乱码。我将如何执行字符编码检测并正确显示文本?抱歉,如果这是一个重要的问题,我对这个话题并不精通。
1 回答
正如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.d和Lt.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;” 成员,它想拉更多的类,但事实证明它不需要字符集识别,所以我把它注释掉了。就这样。希望能帮助到你。
格雷格