评论

收藏

[Android] 真·Android Zxing 扫码中文乱码解决

移动开发 移动开发 发布于:2022-03-09 10:21 | 阅读数:400 | 评论:0

Zxing3.2.1 之前遇到过Android Zxing扫码乱码的问题,网上搜了下解决了下。 今天又遇到了问题。 依然会乱码。
研究总结如下:
Zxing 可以在Hints中添加默认编码格式。这个编码格式是用于解读Byte数据时,
1.如果码中没有指定编码集则,默认使用该编码格式。
2.如果制定了编码集,则使用编码指定的字符集。
并非强制,而中文的主要编码格式有两种,GBKUTF-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记录了原始二进制数据,直接判断二进制数据格式即可。
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 是网上抄来的一个工具函数,如下

DSC0000.gif DSC0001.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;
  }
View Code问题解决。

本文来自博客园,作者:Uncle锅
转载请注明原文链接:https://www.cnblogs.com/uncleguo/p/15981253.html


   
   
   
                        

关注下面的标签,发现更多相似文章