安卓应用中的二维码扫描功能实现

糖果女孩 2021-05-31 ⋅ 18 阅读

二维码扫描功能在现代移动应用中变得越来越常见。它可以用于各种场景,例如支付、登录、分享等。本文将介绍如何在安卓应用中实现二维码扫描功能。

引入依赖库

首先,我们需要在项目的build.gradle文件中添加以下依赖库:

dependencies {
    implementation 'com.google.zxing:core:3.3.0'
    implementation 'com.journeyapps:zxing-android-embedded:4.2.0'
}

这些依赖库包括ZXing核心库和ZXing的安卓嵌入库。ZXing是一个开源的二维码处理库,它提供了一套用于生成和解码二维码的API。

创建布局文件

接下来,我们需要创建一个布局文件来显示相机预览和扫描二维码结果。在res/layout目录下创建一个名为activity_scan_qr_code.xml的文件,并添加以下代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <SurfaceView
        android:id="@+id/camera_preview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/scan_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize="18sp" />

</LinearLayout>

上述布局文件中包含一个SurfaceView用于显示相机预览,以及一个TextView用于显示扫描结果。

创建扫描活动

接下来,我们需要创建一个活动类来处理相机的打开、二维码的扫描等逻辑。创建一个名为ScanQRCodeActivity的Java类,并添加以下代码:

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeEncoder;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.BarcodeScannerView;
import com.journeyapps.barcodescanner.DefaultDecoderFactory;

import java.util.Arrays;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;

public class ScanQRCodeActivity extends AppCompatActivity implements BarcodeCallback {

    private SurfaceView cameraPreview;
    private BarcodeScannerView scannerView;
    private TextView scanResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_qr_code);

        cameraPreview = findViewById(R.id.camera_preview);
        scanResult = findViewById(R.id.scan_result);

        // 动态请求相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
        } else {
            initScanner();
        }
    }

    private void initScanner() {
        scannerView = new BarcodeScannerView(this);
        cameraPreview.addView(scannerView);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (scannerView != null) {
            scannerView.resume();
            scannerView.decodeContinuous(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (scannerView != null) {
            scannerView.pause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (scannerView != null) {
            scannerView.stopDecoding();
        }
    }

    @Override
    public void barcodeResult(BarcodeResult result) {
        if (result != null && result.getText() != null) {
            scanResult.setText(result.getText());
        }
    }

    @Override
    public void possibleResultPoints(Collection<ResultPoint> resultPoints) {
        // 不需要处理
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                initScanner();
            } else {
                Toast.makeText(this, "未授权摄像头权限,无法扫描二维码!", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }
}

上述代码中,我们首先检查相机权限是否已授权,如果没有,则动态请求相机权限。然后,我们通过BarcodeScannerView创建一个相机预览的视图,并将其添加到布局中的SurfaceView上。

onResume方法中,我们启动相机预览并开始持续扫描二维码。在onPause方法中,我们暂停相机预览。在onDestroy方法中,我们停止解码过程。

BarcodeResult对象包含扫描到的二维码的内容,我们将其显示在布局中的TextView上。

BarcodeCallback接口实现了扫描结果的回调方法。我们在barcodeResult方法中处理扫描结果,并将结果显示在界面上。

最后,我们在onRequestPermissionsResult方法中处理相机权限请求的结果。如果权限被授予,我们初始化扫描器,否则,我们提示用户需要摄像头权限才能继续操作并关闭活动。

添加扫描活动到清单文件

最后,我们需要将扫描活动添加到清单文件中。打开AndroidManifest.xml文件,并在<application>标签中添加以下代码:

<activity android:name=".ScanQRCodeActivity" />

现在,我们的安卓应用中就拥有了二维码扫描功能。可以通过调用startActivity方法启动ScanQRCodeActivity

结论

本文介绍了如何在安卓应用中实现二维码扫描功能。我们通过引入ZXing库,并使用ZXing安卓嵌入库来实现相机预览和解码二维码的功能。希望本文能够对你理解和实现二维码扫描有所帮助。

参考资料:


全部评论: 0

    我有话说: