当前位置:操作系统 > 安卓/Android >>

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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,