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 是網上抄來的一個工具函式,如下
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
問題解決,
本文來自博客園,作者:鍋叔
轉載請注明原文鏈接:https://www.cnblogs.com/uncleguo/p/15981253.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/440473.html
標籤:其他
