1. 程式人生 > >Android二維碼掃描庫zxing的使用

Android二維碼掃描庫zxing的使用

Android二維碼的使用:

1.匯入依賴:

 compile 'com.journeyapps:zxing-android-embedded:3.3.0'

2.建立ScannerAcvitity,在佈局中使用以下控制元件:

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
                android:id="@+id/scanner"
                android:layout_width="match_parent"
                android:
layout_height
="match_parent" app:zxing_framing_rect_height="@dimen/qr_code_scanner_size" app:zxing_framing_rect_width="@dimen/qr_code_scanner_size" app:zxing_scanner_layout="@layout/layout_qrcode_view" />

DecoratedBarcodeView是整個相機影象填充的部分,一般填充全屏。

掃碼有效區

: app:zxing_framing_rect_height和app:zxing_framing_rect_width兩個屬性分別限定一個透明區域,即掃碼有效區,只有當二維碼在有效區內時二維碼才會被識別,且有效區不會被ViewfinderView中設定的背景陰影著色;有效區位置恰好在DecoratedBarcodeView範圍的正中央。

自定義DecoratedBarcodeView佈局:DecoratedBarcodeView有預設的layout來進行佈局,也可以通過app:zxing_scanner_layout屬性來進行自定義佈局,方法是在layout中新建一個xml佈局檔案,佈局檔案中主要包含兩個重要控制元件:

3.DecoratedBarcodeView中包括兩個重要的部分:

       public class DecoratedBarcodeView extends FrameLayout {
            private BarcodeView barcodeView;
            private ViewfinderView viewFinder;
        }

BarcodeView控制元件負責展示相機捕獲到的影象,一般為填充全屏

ViewfinderView 控制元件負責繪製陰影,陰影色不會渲染有效區,一般也設定為填充全屏

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     
     <com.journeyapps.barcodescanner.BarcodeView
         android:id="@+id/zxing_barcode_surface"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginTop="@dimen/qr_code_scanner_view_finder_margin_top" />
         
     <com.tplink.omada.cloud.ui.addcloudkey.TPScannerView
         android:id="@+id/zxing_viewfinder_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginTop="@dimen/qr_code_scanner_view_finder_margin_top"
         app:zxing_viewfinder_mask="@color/black_46" />
 </FrameLayout>

ViewfinderView繪製的陰影顏色由app:zxing_viewfinder_mask屬性來控制

4.具體使用方法:

1)動態申請相機許可權

 private boolean checkPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PERMISSION_GRANTED) {
                isSystemPermissionDialogShow = true;
                ActivityCompat.requestPermissions(ScannerActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
                return false;
        }
            return true;
 }

2)建立一個CaptureManager

 public class TPCaptureManager extends CaptureManager {
        private QRCodeCallBack callBack;
        public TPCaptureManager(Activity activity, DecoratedBarcodeView barcodeView) {
            super(activity, barcodeView);
        }
        @Override
        protected void returnResult(BarcodeResult rawResult) {
            if (callBack != null) {
                callBack.handle(rawResult.getText());
            }
        }
        public void setCallBack(QRCodeCallBack callBack) {
            this.callBack = callBack;
        }
        public interface QRCodeCallBack {
            void handle(String result);
        }
    }

3)新增對掃碼結果的回撥

captureManager = new TPCaptureManager(this, binding.scanner);
        captureManager.setCallBack(
                    qrCode -> {});

其中qrCode就是掃碼得到的字串,通過回撥對掃碼結果進行處理。
4)掃描結果的處理:
如果要求掃描得到的結果要在ScannerActivity處理掃描結果,會發現掃描一個二維碼之後相機影象會停止重新整理,掃碼有效區也會失效,即掃碼框預設是一次性使用的,所以要實現一個掃碼框多次使用要在每次掃碼結束後呼叫:

	decoratedBarcodeView.resume();
   	captureManager.decode();

此外,在ScannerActivity的onResume中也要加入:

 	if (captureManager != null) {
          	captureManager.onResume();
          	captureManager.decode();
          	decoratedBarcodeView.resume();
	}

captureManager的生命週期跟隨Activity的生命週期,即Activity執行onPause(),captrueManager也要顯示的手動執行onPause()

  protected void onPause() {
        	super.onPause();
        	if (captureManager != null) {
             	captureManager.onPause();
        	}
    }

5.其他使用方法:

掃碼後立即返回上一頁面,並向上一頁面報告掃碼得到的字串:

開啟ScannerActivity:

private void startQrCode() {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 1);
                return;
            }
            new IntentIntegrator(this)
                    .setOrientationLocked(false)
                    .setCaptureActivity(ScannerActivity.class) // 設定自定義的activity是ScanActivity
                    .initiateScan(); // 初始化掃描
    }

處理掃描結果:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
            if (result != null) {
                if (result.getContents() == null) {
                    Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
                }
            } else {
                super.onActivityResult(requestCode, resultCode, data);
            }
   	}