Android中的字符集检测
我的Android应用程序检索并显示SHOUTcast元数据。我没有英文字符集。基本上,元数据显示为胡言乱语。如何执行字符编码检测并正确显示文本?很抱歉,如果这是一个非常重要的问题,我对这个话题不太熟悉 所讨论的流是:正如Vortex在上面的评论中指出的,如果您的数据来自格式良好的HTML代码,您可以从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(或其他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中。