天天看點

Android二維碼掃描之SimpleZXing中文亂碼問題的解決

最近公司的項目中需要Android端做一個掃描二維碼的應用,網上推薦的文章中在github上找到一個叫做SimpleZXing的開源項目,本來呢谷歌是有提供官方的demo的,也是開源的,那個項目叫ZXing。我找的這個SimpleZXing是基于ZXing的基礎上,去掉了不必要的部分,隻保留了掃描二維碼識别的功能,有需要的朋友可以去找一下:點選打開連結下載下傳完後導入AndroidStudio就可以了,我的是直接就可以運作了,也沒報錯,如果各位導入項目的時候有報錯,看一下你們的AS版本和相關的配置。導入後安裝到手機上使用,發現正常二維碼的是可以掃出來的,但是當二維碼中有文字的時候,識别出來是亂碼的,當時也蒙了,然後就一步一步分析識别的流程,我覺得肯定是解碼的時候出問題了,但是看了一天的代碼也沒找問題出在哪了。然後在網上找解決方法,試了很多但是都不行,自己就又開始研究,終于第二天晚上的時候在結合網上的解決方法和自己的改造後解決了這個問題!

這個問題的解決主要有以下幾個步驟:

1.在CaptureActivity中的onResume方法中添加如下:

decodeFormats = null;
characterSet = "ISO-8859-1";
           

這個2個變量是在 CaptureActivity中定義的:

private String characterSet;
private Collection<BarcodeFormat>
decodeFormats;
           

2.找到CaputreActivity中的initCemare方法,将該方法下的new  CaputreActivityHandler()裡面的參數改為:

new CaptureActivityHandler(this,decodeFormats, decodeHints, characterSet,  cameraManager)
           

3.去 CaputreActivityHandler類裡面的構造方法改為相應的:

CaptureActivityHandler(CaptureActivity activity,
                           Collection<BarcodeFormat> decodeFormats,
                           Map<DecodeHintType,?> baseHints,
                           String characterSet,
                           CameraManager cameraManager)
           

4.緊接着将上述構造方法下面的new DecodeThread方法的參數改為:

new DecodeThread(activity, decodeFormats, baseHints, characterSet,new ViewfinderResultPointCallback(activity.getViewfinderView()));
           

5.将new DecodeThread類中的構造方法參數改為:

public DecodeThread(CaptureActivity activity,
                        Collection<BarcodeFormat> decodeFormats,
                        Map<DecodeHintType,?> baseHints,
                        String characterSet,
                        ResultPointCallback resultPointCallback)
           

6.在hints = new EnumMap<>(DecodeHintType.class)的下面加多一段:

if (baseHints != null) {
            hints.putAll(baseHints);
        }
           

7.在

hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
        hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
           

後面加多一段:

if (characterSet != null) {
            hints.put(DecodeHintType.CHARACTER_SET, characterSet);
        }
           

8.回到你接收最終結果的Activity,有的人是ResultActivity,我的是ManActivity裡面,在接收到資料的後面加,如:

String resultData = data.getStringExtra(CaptureActivity.EXTRA_SCAN_RESULT);
           

加多一段如下:

String UTF_Str = "";
                        String GB_Str = "";
                        boolean is_cN = false;
                        try {
                            UTF_Str = new String(resultData.getBytes("ISO-8859-1"), "UTF-8");
                            is_cN = IsChineseOrNot.isChineseCharacter(UTF_Str);
                            //防止有人特意使用亂碼來生成二維碼來判斷的情況
                            boolean b = IsChineseOrNot.isSpecialCharacter(resultData);
                            if (b) {
                                is_cN = true;
                            }
//                            System.out.println("是為:"+is_cN);
                            if (!is_cN) {
                                GB_Str = new String(resultData.getBytes("ISO-8859-1"), "GB2312");
//                                System.out.println("這是轉了GB2312的"+GB_Str);
                            }
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }

                        if(is_cN){
                            tvResult.setText(UTF_Str);
                        }else{
                            tvResult.setText(GB_Str);
                        }
           

這段代碼就加到resultData那行後面就好了

9.ok,運作一把,亂碼問題解決了,給我高興的呀!這個問題雖然不算難,但是第一次遇到,也耗了我2天的時間才解決,如果是有下載下傳github上的SimpleZXing(github排第一個的)的同學(其他的沒試過),在遇到中文識别亂碼的時候,可以參照我上面給出的流程去試一下,已經寫的很詳細啦!如果還有什麼不懂的地方或者改進的建議,都可以互相 交流學習哦!