二維碼掃描開源庫ZXing定制化

jopen 9年前發布 | 39K 次閱讀 條形碼/二維碼開發包 zxing


最近在用ZXing這個開源庫做二維碼的掃描模塊,開發過程的一些代碼修改和裁剪的經驗和大家分享一下。

我的代碼庫:

https://github.com/SickWorm/ZXingDialog

代碼沒有在github維護,所以沒有log。但是所有修改的地方我都加上了“@ch”的注釋,以方便定位

官方源碼:

https://github.com/zxing/zxing

實現功能:

1、功能裁剪(只保留QRCode二維碼掃描功能,去掉條形碼等其他碼掃描功能)

2、移除資源依賴,提供Dialog形式的掃碼功能

3、API兼容(源碼只兼容4.0以上,現兼容至2.1)

4、轉換為豎屏(源碼為橫屏)

5、掃碼速度優化(主要分三點,現只完成了一點)

6、設備兼容(針對低分辨率設備)

本文還會提到:

7、自定義界面

8、優化調試方法

1、建立工程

ZXing源碼并沒有提供一個完整的實例工程給我們使用,構建一個工程我們需要源碼下的三個文件夾的文件:

core/

android-core/

android/

大概步驟如下:

1、創建一個新工程

2、把android目錄下的所有文件覆蓋到新工程(內含有資源文件和AndroidManifest.xml等構建app所需的文件)

3、把android-core所有Java文件拷入到src目錄下(注意!android-core中的src文件夾需要進行一些改動,原來路 徑是android-core\src\main\java\com\google\zxing\client\android\camera,我們要把 中間的main\java兩層文件夾去掉,不然在Eclipse中無法識別包路徑)

4、把core目錄下的所有Java文件拷入到src目錄下(注意!和步驟3一樣需要去掉main\java兩層文件夾)。這樣ZXing已經可以運行了,我的src目錄是這樣的:

二維碼掃描開源庫ZXing定制化

可以直接運行,效果還不錯。如果你遇到一些錯誤,有可能是編譯的JDK版本低于1.7導致的。源碼里使用了ArrayList<>這樣的寫法,1.7以前是不支持的。你可以選擇修改源碼或者提高編譯JDK版本。

但你可能不滿足于這個界面,掃描框太大了,而且是橫屏全屏的,還要求API 15(Android 4.0.3)。下面我們會對這些需求進行修改。

2、代碼優化

1、功能裁剪(只保留QRCode二維碼掃描功能,去掉條形碼等其他碼掃描功能)

我的目標是只保留二維碼識別,不需要其他多余的功能。這一部分的步驟我不打算詳細說明,因為我已經不記得了。。大家可以直接看我的代碼的結果。

可以直接刪掉的是:

com.google.zxing.aztec.** aztec格式的二維碼

com.google.zxing.client.android.book.* Google 圖書相關的功能

com.google.zxing.client.android.clickboard.* 不清楚,復制黏貼?

com.google.zxing.client.android.encode.*  用于生成各種碼

com.google.zxing.client.android.history.* 保存掃碼記錄

com.google.zxing.client.android.result.** 掃碼應用功能相關的功能性代碼

com.google.zxing.client.android.share.* 分享功能

com.google.zxing.client.android.wifi.* WiFi相關,不清楚具體用途

com.google.zxing.datamatrix.** datamatrix格式二維碼

com.google.zxing.maxicode.** maxicode格式二維碼

com.google.zxing.multi.** 貌似是用于多格式支持的?我沒有用到這個包,如果有了解的麻煩告知

com.google.zxing.oned.** one dimension一維碼,也就是條形碼(你去百度搜oned會發現奇怪的東西。。)

com.google.zxing.pdf417.** PDF417格式條形碼

需要修改的是:

com.google.zxing.client.android.CaptureActivity:去掉其他功能的相關代碼,只保留核心功能,即掃碼功 能。界面為一個FrameLayout里面包含一個SurfaceView。代碼移除就不詳細說了,直接看上傳的代碼吧,這個文件我參考了 http://www.cnblogs.com/keyindex/archive/2011/06/08/2074900.html 這個鏈接里的CaptureActivity的修改。

com.google.zxing.MultiFormatReader:這個是指定支持解碼的格式,需要把除QR_CODE以外的格式全部去掉,否則會因為刪掉了解碼包而報錯。具體也請看上傳的代碼。

com.google.zxing.client.result.ProductResultParser:parse函數中,同上。

com.google.zxing.client.android.DecodeThread:構造器中,同上。

另外:

com.google.zxing.client.result 我沒有刪減這個包的代碼,應該也是能優化的

2、移除資源依賴,提供Dialog形式的掃碼功能

經過了第1步的精簡,其實只剩下了2個地方需要修改:

1.掃描界面

2.掃描成功時播放的beep聲音文件

1:去除了其余功能后,對于核心功能我們只需要一個SurfaceView和一個畫界面的View就可以了。代碼如下:

/**
 * use Java code to build layout instead of xml file
 * @ch
 */
private void buildLayout() {
  requestWindowFeature(Window.FEATURE_NO_TITLE); 
  FrameLayout layout = new FrameLayout(this);
  LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
  layout.setLayoutParams(params);
  surfaceView = new SurfaceView(this);
  surfaceView.setLayoutParams(params);
  layout.addView(surfaceView);
  viewfinderView = new ViewfinderView(this, null);
  layout.addView(viewfinderView);
  setContentView(layout);
}

ViewfinderView是ZXing自帶的View,如果要修改界面,直接修改它就可以了,我們第7點會提到。

2:由于我最終的目的是能打包成jar包,所以beep文件不能放在res里,而是放在assets里。

//待補充

3、API兼容(源碼只兼容4.0以上,現兼容至2.1)

這部分修改在源碼中標記為//@ch api compatible。

CaptureActivity.java:
    //@ch api compatible
    if (VERSION.SDK_INT < 11) {
      //surfaceview will push buffer automatically
      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
//API 11之前需要手動設置,否則會無法顯示。API11之后為默認設置。

CameraConfigurationManager.java:
  //@ch api compatible
  if (VERSION.SDK_INT < 13) {
    theScreenResolution.x = display.getWidth();
    theScreenResolution.y = display.getHeight();
  } else {
    display.getSize(theScreenResolution);
  }
//getSize是API 13之后的新API,之前需要用getWidth和getHeight。

AutoFocusManager.java
    //@ch api compatible
    if (VERSION.SDK_INT > 11) {
    newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    } else {
      newTask.execute();
    }
//源碼中這里設置了多線程的模式,THREAD_POOL_EXECUTOR表示這個task最多只有5個線程同時運行,超過5個的就要等待。在低于API 11的版本中,此為默認選項。其實這里只有單線程,所以隨便執行吧。

OpenCameraInterface.java:
  //@ch api compatible
  if (VERSION.SDK_INT < 9) {
    return openWithLowApi();
  }
......
  /**
   * for lower than API 9
   * @ch api compatible
   */
  public static Camera openWithLowApi() {
    //If the device does not have a back-facing camera, this returns null
    Camera camera = Camera.open();
    return camera;
  }
//源碼的打開攝像頭是能區分前后攝像頭的,然而API 9之前并沒有前置攝像頭這個概念,所以做了一下處理

就幾個地方,不過也找了我個把小時了。

4、轉換為豎屏(源碼為橫屏)

ZXing默認是橫屏,但是我們一般的APP都會做成豎屏,如果掃碼的時候強制切換成橫屏那樣體驗就不好了。在修改ZXing的豎屏的時候,我按 照的是一般APP的豎屏設置方法,結果發現沒有源碼的效果好,需要把碼放到很小才能完成。后面在調試過程中發現掃碼解析的區域和屏幕畫出來的區域不一樣, 才知道這部分的修改出了問題。然后我搜索找到一篇前輩的文章,參考了一下發現沒有改完全。

5、掃碼速度優化(主要分三點,現只完成了一點)

6、設備兼容(針對低分辨率設備)

本文還會提到:

7、自定義界面

8、優化調試方法

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!