使用 GitHub 上 LivotovLabs/zxscanlib 的 v0.9.0 版,目前上面有更新的版本,不過我那時候用的時候最新的就到這版
假如直接使用這個 library ,手機在掃到 QR code 的時候會震動,然後離開掃描的相機畫面回到前一個畫面,另外,它開相機的時候會把畫面變成橫的(landscape)。所以要達到我的要求的話就需要改一下裡面的 code,這邊分享一下把這個 library 應用到可以連續掃描多個 QR code 的經驗 (使用eclipse),可以搭配該 project 的 GitHub 頁面說明一起看
目標:可以連續掃描多個 QR code,當掃到目標 QR code 的時候跳回原畫面,並使用取得的資料做下一步應用 Dependency Issue 把 project clone 下來之後,照著 GitHub 頁面上的說明,將它當作一個 library project 使用,此時假如原本的 project 有用到 android-support-v4.jar,就會產生衝突(因為此 library project 也有用),我的解決方式是把原本 project 的 android-support-v4.jar 從 libs 裡刪掉
此 library 的運作模式 在想要掃 QR code 的時候使用 ZXScanHelper.scan() 方法,此時 DecodeHandler.handleMessage() 會不斷地被呼叫,decode成功了之後會呼叫 CaptureActivity.handleDecode(),可以在這邊對 decode 之後的結果做篩選,最後可以在我們自己 override 的 onActivityResult() 裡取得解碼後的結果
解決問題:掃描時相機畫面會變成橫的 第一步:刪掉強制轉為 landscape 的 code
CaptureActivity.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Override public void onCreate (Bundle icicle) { super .onCreate(icicle); Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(ZXScanHelper.getCustomScanLayout() > 0 ? ZXScanHelper.getCustomScanLayout() : R.layout.capture); hasSurface = false ; inactivityTimer = new InactivityTimer(this ); beepManager = new BeepManager(this ); if (ZXScanHelper.getUserCallback() != null ) { ZXScanHelper.getUserCallback().onScannerActivityCreated(this ); } }
第二步:設定 camera 的 orientation,不然在 CaptureActivity 為 portrait 的情況下 camera 會是 landscape
CameraManager.java - 加上 forceSetCameraOrientation() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public synchronized void openDriver (SurfaceHolder holder) throws IOException { try { configManager.setDesiredCameraParameters(theCamera); forceSetCameraOrientation(); } catch (RuntimeException re) { } }
小提醒:GitHub上的說明在 android:configChanges 少了 screenSize,記得加上 (target API level >= 13的話要加,所以應該幾乎都需要加吧)
AndroidManifest.xml 1 2 3 4 5 6 7 <activity android:name="com.google.zxing.client.android.CaptureActivity" android:clearTaskOnLaunch="true" android:stateNotNeeded="true" android:configChanges="orientation|keyboardHidden|screenSize" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden" > </activity>
解決問題:改為可以連續掃描多個 QR code 第一步:設定 ZXUserCallback,實作 onCodeRead() 方法 如 GitHub 頁面所說,呼叫 ZXScanHelper.scan() 之前先呼叫ZXScanHelper.setUserCallback(ZXUserCallback cb),把過濾邏輯寫在 onCodeRead() 裡
第二步:在 CaptureActivity.handleDecode() 裡增加判斷邏輯,掃到不合格的 QR code 之後要 callrestartPreviewAfterDelay(long delayMS) 重新掃描
CaptureActivity.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public void handleDecode (Result rawResult, Bitmap barcode) { boolean accept = rawResult != null ; if (accept && ZXScanHelper.getUserCallback() != null ) { accept = ZXScanHelper.getUserCallback().onCodeRead(rawResult.getText()); } if (accept) { handleDecodeExternally(rawResult, barcode); } else { restartPreviewAfterDelay(300L ); } }
這樣就大功告成囉!