真·Android Zxing 扫码中文乱码解决
Zxing3.2.1 之前遇到过Android Zxing扫码乱码的问题,网上搜了下解决了下。 今天又遇到了问题。 依然会乱码。
研究总结如下:
Zxing 可以在Hints中添加默认编码格式。这个编码格式是用于解读Byte数据时,
1.如果码中没有指定编码集则,默认使用该编码格式。
2.如果制定了编码集,则使用编码指定的字符集。
并非强制,而中文的主要编码格式有两种,GBK和UTF-8。
注意,网上有很多提到“ISO-8859-1”这个编码集的,这个编码集是个简单编码集,每个字节一个字符。并不是一个能表示中文的编码集。
有些情况可以利用他的单字节字符特性,进行字节和字符的互转。
但因为上面规则2的存在,使用这个编码集做byte取得的多多少少都有点问题。(如指明UTF-8编码的,则返回结果已经是utf8,用ISO8859取得bytes反儿会乱码,因为ISO无法表示UTF-8的字符,会替换为?号)。
因为,码生成不同,会包含是否指明编码格式两种情况,而编码本身又可能是Utf8或者GBK,而进行String转换的过程中,二进制信息会丢失。
因此思路上,如果可以取得原始的byte数组,就可以判断用正确的字符集显示了。应避免通过String转换取得。
解决也比较简单,看了下源码,发现其实扫码结果中本来就包含了这些信息。
//源码 QRCodeReader public final Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)方法中
//向Result Metadata中放了一些额外信息。这是一个Map
…… result.putMetadata(ResultMetadataType.BYTE_SEGMENTS,byteSegments); ……
这个result就是扫码结果result。 在实例中会在MipcaActivityCapture的扫码结果回调
public void handleDecode(Result result, Bitmap barcode)
byteSegments记录了原始二进制数据,直接判断二进制数据格式即可。注意判空,例如如果同时支持扫描条形码,是没有Metadata信息的。
List<byte[]> byteSegments = (List<byte[]>) result.getResultMetadata().get(ResultMetadataType.BYTE_SEGMENTS); StringBuffer buffer1 =new StringBuffer(); for (int i = 0; i < byteSegments.size(); i++) { byte[] buffer =byteSegments.get(i); String tempStr = ""; //猜一下编码格式 if(isUtf8(buffer)){ tempStr = new String(buffer, "utf-8"); }else{ tempStr = new String(buffer, "GBK"); } buffer1.append(tempStr); } resultString = buffer1.toString();
isUtf8 是网上抄来的一个工具函数,如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static Boolean isUtf8(byte[] buffer) { boolean isUtf8 = true; int end = buffer.length; for (int i = 0; i < end; i++) { byte temp = buffer[i]; if ((temp & 0x80) == 0) {// 0xxxxxxx continue; } else if ((temp & 0xC0) == 0xC0 && (temp & 0x20) == 0) {// 110xxxxx 10xxxxxx if (i + 1 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0) { i = i + 1; continue; } } else if ((temp & 0xE0) == 0xE0 && (temp & 0x10) == 0) {// 1110xxxx 10xxxxxx 10xxxxxx if (i + 2 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0 && (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0) { i = i + 2; continue; } } else if ((temp & 0xF0) == 0xF0 && (temp & 0x08) == 0) {// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx if (i + 3 < end && (buffer[i + 1] & 0x80) == 0x80 && (buffer[i + 1] & 0x40) == 0 && (buffer[i + 2] & 0x80) == 0x80 && (buffer[i + 2] & 0x40) == 0 && (buffer[i + 3] & 0x80) == 0x80 && (buffer[i + 3] & 0x40) == 0) { i = i + 3; continue; } } isUtf8 = false; break; } return isUtf8; }
问题解决。
本文来自博客园,作者:锅叔
转载请注明原文链接:https://www.cnblogs.com/uncleguo/p/15981253.html