1. 程式人生 > >Android使用zxing-android-embedded(由zxing開發)實現二維碼生成和掃描

Android使用zxing-android-embedded(由zxing開發)實現二維碼生成和掃描

前言:

目前二維碼(條形碼)的使用非常廣泛,所以啊,就想去實現以下嘛,最簡單的方法就是選擇開源庫了。

在網上一查開源庫還是很多的,介紹使用最多的就是zxing,所以這裡也就是用zxing了。但是由於zxing開源庫太大了,有很多不是Android要用的,所以網上很多都是介紹將zxing庫中Android用到內容重新封裝使用。

但是對於新手來說還是不太好操作的,我看了下,大部分都是拷貝原工程的一部分程式碼,然後再進行一系列的修改,最終成功使用。

我這裡介紹的是直接使用zxing-android-embedded開源庫(其實差不多,但是方便,簡單),對於需要快速實現該功能的專案來說還是很好的。

zxing-android-embedded 官方介紹
zxing

準備工作

首先新增依賴(3.5.0版本,最新的可以取官網查詢)

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

新增許可權

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name
="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />

有些小夥伴就發現了CAMERA是危險許可權,Android6.0以上需要申請執行時許可權
但是該庫已經封裝好了,所以只需要這裡新增就行,還是很方便的,為那些會忘記的同學降低出錯率
FLASHLIGHT許可權是為了掃描時開啟閃光燈,如不需要就刪除

如何生成一個二維碼

/**
* 傳入一個字串,生成一個二維碼
* @param str
* @return
*/
private Bitmap encodeAsBitmap
(String str){ Bitmap bitmap = null; BitMatrix result; MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); try { //可以指定生成二維碼Bitmap的大小 result = multiFormatWriter.encode(str, BarcodeFormat.QR_CODE, 400, 400); BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); bitmap = barcodeEncoder.createBitmap(result); } catch (WriterException e){ e.printStackTrace(); } catch (IllegalArgumentException iae){ return null; } return bitmap; }

掃描二維碼

先自定義一個掃描Activity(Fragment)

public class ScanActivity extends AppCompatActivity implements DecoratedBarcodeView.TorchListener {
    private CaptureManager captureManager;
    private boolean isLightOn = false;
    private DecoratedBarcodeView mDBV;
    private Button swichLight;
    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //隱藏狀態列,因為該activity使用無actionbar主題,所以就是全屏了
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_scan);

    swichLight = findViewById(R.id.btn_switch);
    mDBV = findViewById(R.id.dbv_custom);

    mDBV.setTorchListener(this);
    // 如果沒有閃光燈功能,就去掉相關按鈕
    if(!hasFlash()) {
        swichLight.setVisibility(View.GONE);
    }
    swichLight.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        if(isLightOn){
            mDBV.setTorchOff();
        }else{
            mDBV.setTorchOn();
        }
    }
});

    //重要程式碼,初始化捕獲
    captureManager = new CaptureManager(this,mDBV);
    captureManager.initializeFromIntent(getIntent(),savedInstanceState);
    captureManager.decode();

}

    // 判斷是否有閃光燈功能
    private boolean hasFlash() {
        return getApplicationContext().getPackageManager()
    .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    }

    @Override
    public void onTorchOn() {
        Toast.makeText(this,"torch on", Toast.LENGTH_LONG).show();
        isLightOn = true;
    }

    @Override
    public void onTorchOff() {
        Toast.makeText(this,"torch off",Toast.LENGTH_LONG).show();
        isLightOn = false;
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        captureManager.onSaveInstanceState(outState);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return mDBV.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onPause() {
        super.onPause();
        captureManager.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        captureManager.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        captureManager.onDestroy();
    }
}

一些跟生命週期有關,記得重寫,最核心的就是captureManager。

介面xml部分

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="SwitchLight"
    android:id="@+id/btn_switch"
    android:layout_marginBottom="20dp"
    android:background="#7f383838"
    android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true" />

<!--該控制元件就是掃描view-->
<com.journeyapps.barcodescanner.DecoratedBarcodeView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/dbv_custom"
    app:zxing_framing_rect_width="250dp"
    app:zxing_framing_rect_height="250dp"
    app:zxing_preview_scaling_strategy="fitXY"
    app:zxing_use_texture_view="true">

</com.journeyapps.barcodescanner.DecoratedBarcodeView>

Android清單檔案中scanActivity的配置

<activity
    android:name=".ScanActivity"
    android:screenOrientation="fullSensor"
    android:stateNotNeeded="true"
    android:theme="@style/Theme.AppCompat.NoActionBar"
    android:windowSoftInputMode="stateAlwaysHidden">
</activity>

呼叫該掃描Activity

首先初始化,設定一些配置引數

private void initScan() {
    integrator = new IntentIntegrator(this);
    integrator.setPrompt("請掃描"); //底部的提示文字,設為""可以置空
    integrator.setCameraId(0); //前置或者後置攝像頭
    integrator.setBeepEnabled(false); //掃描成功的「嗶嗶」聲,預設開啟
    integrator.setCaptureActivity(ScanActivity.class); //設定掃描activity,也就是上面寫的Activity
}

設定完就可以在啟動了,一句程式碼就行

integrator.initiateScan();

OK,結束