Android解决Zxing识别GBK类型二维码出现乱码的问题(效果图对比)
最近在研究二维码识别,用了Zxing的开源代码,但识别GBK类型老是出现乱码。折腾了两天,今天终于解决了,小记一下,。
我是在Zxing-1.6基础上开发的,因为zxing1.6对竖屏要支持好一些。
首先要搭建编译core.jar的环境,这个我就不多说了,不会的话可以参考
主要是改源码部分
修改core\src\com\google\zxing\common StringUtils.java文件
1、 在private static final String ISO88591 = "ISO8859_1";下面一行添加
[html]
private static final String GBK = "GB2312";
2、在boolean canBeUTF8 = true;下面添加
[html]
boolean canBeGBK = true;
2、在 int value = bytes[i] & 0xFF;下面开始添加
[html]
//GBK stuff
if (value > 0x7F)// 如果大于127,则可能是GB2312,就开始判断该字节,和下一个字节
{
if (value > 0xB0 && value <= 0xF7)// 第一个字节再此范围内,则开始判断第二个自己
{
int value2 = bytes[i + 1] & 0xFF;
if (value2 > 0xA0 && value2 <= 0xF7)
{
canBeGBK = true;
}
}
}
3、在 if (canBeShiftJIS && (maybeDoubleByteCount >= 3 || 20 * maybeSingleByteKatakanaCount > length)) {
return SHIFT_JIS;
}下面添加
[html]
if(canBeGBK){
return GBK;
}
再ant生产core.jar替换之前的就可以了,基本都是依葫芦画瓢,大家应该看得懂,
最后我把完整的StringUtils.java代码放上来,可以对比着看
[html]
/*
* Copyright (C) 2010 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.common;
import java.util.Hashtable;
import com.google.zxing.DecodeHintType;
/**
* Common string-related functions.
*
* @author Sean Owen
*/
public final class StringUtils {
private static final String PLATFORM_DEFAULT_ENCODING =
System.getProperty("file.encoding");
public static final String SHIFT_JIS = "SJIS";
private static final String EUC_JP = "EUC_JP";
private static final String UTF8 = "UTF8";
private static final String ISO88591 = "ISO8859_1";
private static final String GBK = "GB2312";
private static final boolean ASSUME_SHIFT_JIS =
SHIFT_JIS.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING) ||
EUC_JP.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING);
private StringUtils() {}
/**
* @param bytes bytes encoding a string, whose encoding should be guessed
* @param hints decode hints if applicable
* @return name of guessed encoding; at the moment will only guess one of:
* {@link #SHIFT_JIS}, {@link #UTF8}, {@link #ISO88591}, or the platform
* default encoding if none of these can possibly be correct
*/
public static String guessEncoding(byte[] bytes, Hashtable hints) {
if (hints != null) {
String characterSet = (String) hints.get(DecodeHintType.CHARACTER_SET);
if (characterSet != null) {
return characterSet;
}
}
// Does it start with the UTF-8 byte order mark? then guess it's UTF-8
if (bytes.length > 3 &&
bytes[0] == (byte) 0xEF &&
bytes[1] == (byte) 0xBB &&
bytes[2] == (byte) 0xBF) {
return UTF8;
}
// For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,
// which should be by far the most common encodings. ISO-8859-1
// should not have bytes in the 0x80 - 0x9F range, while Shift_JIS
// uses this as a first byte of a two-byte character. If we see this
// followed by a valid second byte in Shift_JIS, assume it is Shift_JIS.
// If we see something else in that second byte, we'll make the risky guess
// that it's UTF-8.
int length = bytes.length;
boolean canBeISO88591 = true;
boolean canBeShiftJIS = true;
boolean canBeUTF8 = true;
boolean canBeGBK = true;
int utf8BytesLeft = 0;
int maybeDoubleByteCount = 0;
int maybeSingleByteKatakanaCount = 0;
boolean sawLatin1Supplement = false;
boolean sawUTF8Start = false;
boolean lastWasPossibleDoubleByteStart = false;
for (int i = 0;
i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8 || canBeGBK);
i++) {
int value = bytes[i] & 0xFF;
//GBK stuff
if (value > 0x7F)// 如果大于127,则可能是GB2312,就开始判断该字节,和下一个字节
{
if (value > 0xB0 && value <= 0xF7)// 第一个字节再此范围内,则开始判断第二个自己
{
int value2 = bytes[i + 1] & 0xFF;
if
补充:移动开发 , Android ,