1. 程式人生 > >Android記錄貼:使用ZXing來實現二維碼掃描

Android記錄貼:使用ZXing來實現二維碼掃描

參考資料

前言

最近一個專案需要用到掃描二維碼的功能,在網上查了一下,都是使用google的ZXing開源庫來實現的

第一步:匯入依賴

匯入依賴包,目前最新的是3.3.2,可以通過這裡來檢視最新版本

  implementation 'com.google.zxing:core:3.3.2'

新增許可權

<uses-permission android:name="android.permission.INTERNET" /> <!-- 網路許可權 -->
<uses-permission android:name="android.permission.VIBRATE"
/>
<!-- 震動許可權 --> <uses-permission android:name="android.permission.CAMERA" /> <!-- 攝像頭許可權 --> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 自動聚焦許可權 -->

第二步:添加個性化程式碼

新增這裡面的程式碼github
我已經上傳到github上面了那麼問題來了,為什麼我添加里依賴還是需要用這裡面的程式碼?
因為我們在使用ZXing的時候掃描二維碼的頁面是用zxing裡面的activity的,那麼如果我們對掃碼頁面有其他個性化的需求呢,所以我們需要把這裡面我們可能會更改到的程式碼拷貝到我們的程式碼中,以實現自己個性化的需求

第三步:匯入資原始檔

這裡寫圖片描述
raw裡面是掃碼成功的聲音,和其它顏色等等,在mipmap有返回icon,這裡不貼圖了

第四步: 匯入XML檔案

這裡寫圖片描述
這裡就是二維碼掃描activity的頁面了,另一個是toolbar

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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" android:fitsSystemWindows="true" >
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/scanner_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" /> <com.nongyan.teastore.zxing.view.ViewfinderView android:id="@+id/viewfinder_content" android:layout_width="wrap_content" android:layout_height="wrap_content" app:corner_color="@color/corner_color" app:frame_color="@color/viewfinder_frame" app:label_text="二維碼/條形碼掃描" app:label_text_color="@color/colorAccent" app:laser_color="@color/laser_color" app:mask_color="@color/viewfinder_mask" app:result_color="@color/result_view" app:result_point_color="@color/result_point_color" /> </FrameLayout> <include layout="@layout/toolbar_scanner" /> </RelativeLayout>

注意ViewfinderView指的就是我們拷貝的程式碼中的activity,所以要把路徑給改正確

要匯入的東西就這麼多,接下來要看如何呼叫的程式碼了

第五步:在myActivity中啟動掃描二維碼頁面

//    @Override
    public void init() {
        setToolbar();
        bt_scan.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.fragment_bt_scan:
            startQrCode();
            break;
        }
    }

    private void startQrCode() {
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            // android 6.0以上需要動態申請許可權
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, Constants.REQ_PERM_CAMERA);
            return;
        }
        // 二維碼掃碼
        Intent intent = new Intent(getActivity(), CaptureActivity.class);
        startActivityForResult(intent, Constants.REQ_QR_CODE);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //掃描結果回撥
        Toast.makeText(getActivity(),"掃描成功",Toast.LENGTH_SHORT).show();
        if (requestCode == Constants.REQ_QR_CODE && resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();
            String scanResult = bundle.getString(Constants.INTENT_EXTRA_KEY_QR_SCAN);
            //將掃描出的資訊顯示出來
            textView.setText(scanResult);
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case Constants.REQ_PERM_CAMERA:
                // 攝像頭許可權申請
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 獲得授權
                    startQrCode();
                } else {
                    // 被禁止授權
                    Toast.makeText(getActivity(), "請至許可權中心開啟本應用的相機訪問許可權", Toast.LENGTH_LONG).show();
                }
                break;
        }
    }
}

另外值得一看的

瀏覽第二篇部落格,發現大佬連相簿和散光燈都實現了,那就直接把程式碼貼上來,以後直接用豈不是美滋滋

  • 在原有的掃二維碼頁面中加上開啟相簿和散光燈按鈕
 <LinearLayout
        android:orientation="vertical"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:gravity="center">

        <Button
            android:id="@+id/photo_btn"
            android:layout_width="65dp"
            android:layout_height="67dp"
            android:layout_centerVertical="true"
            android:background="@drawable/photo_drawable_btn" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/photo_btn"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:text="相簿"
            android:textColor="#ffffff"
            android:textSize="18sp" />
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:gravity="center">


        <Button
            android:id="@+id/flash_btn"
            android:layout_width="65dp"
            android:layout_height="67dp"
            android:layout_centerInParent="true"
            android:background="@drawable/flash_drawable_btn" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/flash_btn"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:text="開燈"
            android:textColor="#ffffff"
            android:textSize="18sp" />
    </LinearLayout>

首先是開啟相簿的

在CaptureActivity中,監聽按鈕呼叫選擇圖片

/**
     * 相簿選擇圖片
     */
    private void selectPhoto() {
        Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"

        innerIntent.setType("image/*");

        Intent wrapperIntent = Intent.createChooser(innerIntent, "選擇二維碼圖片");

        startActivityForResult(wrapperIntent,
                REQUEST_CODE);
    }

並在Constants中加上

public static final int REQUEST_CODE = 234;// 相簿選擇code

閃光燈

首先在點選時判斷是關燈還是開燈

                if (isTorchOn) {
                    isTorchOn = false;
                    flash_btn.setText("關燈");
                    CameraManager.start();
                } else {
                    isTorchOn = true;
                    flash_btn.setText("開燈");
                    CameraManager.stop();
                }

然後呼叫CameraManager類來控制燈光,start()和stop()方法如下

  private static Camera camera;
 private static Camera.Parameters parameter;
    public static void start() {

        if (camera != null) {
            parameter = camera.getParameters();
            parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(parameter);
        }

    }

    public static void stop() {
        if (camera != null) {
            parameter = camera.getParameters();
            parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(parameter);
        }

    }

靜態方法,所以camera也用上靜態修飾。呼叫,開燈,搞定收工。

最後說兩句

用了ZXing庫,是不是發現原來我們也可以對庫裡面的原始碼魔改一下的。所以說閱讀一下原始碼,還是很棒的嘛,所以要不要一起閱讀一下其他庫的原始碼呢(滑稽臉)