使用zxing3.4.1框架添加二维码扫描功能

一、添加zxing引入依赖项

在build.gradle(module)中添加:

implementation 'com.google.zxing:core:3.4.1'
implementation 'com.journeyapps:zxing-android-embedded:4.2.0'

由于我们要使用摄像头资源,所以还要在AndroidManifest.xml 文件的 <manifest> 标签内添加下面三个权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

第一个是 CAMERA 权限,用于允许应用程序访问设备的摄像头。第二个和第三个是对摄像头自动对焦的要求声明。通常情况下,第二个和第三个权限声明是作为使用摄像头权限的前提条件来添加的。

二、使用zxing框架

在需要进行扫描操作的Activity.java中导入资源包:

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

然后在Activity.java中重写onActivityResult()扫描回调方法

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if(result != null) {
            if(result.getContents() == null) {
                textview.setText("Cancelled");
            } else {
                //将扫描结果放到textview中
                textview.setText(result.getContents());
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

textview只是把扫描的数据显示出来,如果有其它操作可以在这里实现。

接下来我们要实现打开摄像头扫描界面,一般情况下都是按键触发。所以我们可以在Activity.java视图中创建一个按钮并监听按钮的消息,在监听方法中实现打开扫描界面:

scanbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IntentIntegrator integrator = new IntentIntegrator(Activity.this);
                integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
                integrator.setPrompt("请对准二维码");
                integrator.setCameraId(0);
                integrator.setOrientationLocked(false);
                integrator.setBeepEnabled(true);
                integrator.setBarcodeImageEnabled(true);
                integrator.initiateScan();
            }
        });
Activity是Activity.java当前的类名。现在IntentIntegrator等对象因为没有添加进来会报红,暂时不需要管,直接编译即可,在编译过程中会自动下载相关依赖包。编译完成后就可以实现扫描功能了。如果编译过程中下载失败,可以重新编译几次。如果下载都成功了还报错,需要同步一下工程,在执行编译即可。

三、自定义扫描界面

打开扫描后发现,跟经常见到的扫描不太一样,该框架默认的扫描是横向全屏扫描,我们在大多情况下需要竖屏扫描并且有一些类似“取消”、“开灯”等按键操作,所以我们需要自己定义扫描界面,下面我简单的写了一个带有取消扫描的界面并把扫描方式改为竖屏。

首先我们要了解到扫描的创建过程:

integrator.initiateScan();是打开扫描的开始,我们进入到该方法内发现该方法只有一句话:
  public final void initiateScan() {
        startActivityForResult(createScanIntent(), requestCode);
    }

创建了一个扫描Intent,我们继续看一下是怎么创建的,获取的界面又是哪一个

   public Intent createScanIntent() {
        Intent intentScan = new Intent(activity, getCaptureActivity());
        intentScan.setAction(Intents.Scan.ACTION);

        // check which types of codes to scan for
        if (desiredBarcodeFormats != null) {
            // set the desired barcode types
            StringBuilder joinedByComma = new StringBuilder();
            for (String format : desiredBarcodeFormats) {
                if (joinedByComma.length() > 0) {
                    joinedByComma.append(',');
                }
                joinedByComma.append(format);
            }
            intentScan.putExtra(Intents.Scan.FORMATS, joinedByComma.toString());
        }

        intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        attachMoreExtras(intentScan);
        return intentScan;
    }
Intent intentScan = new Intent(activity, getCaptureActivity()); 原来我们要跳转到的界面是getCaptureActivity()。一步一步深入进去,最终会来到CaptureActivity.java里,这就是扫描的活动页面。如果我们想实现自己定义的界面只要重写CaptureActivity类就可以。

在这里我直接创建了一个新的EmptyActivity,在布局xml里创建了一个DecoratedBarcodeView和一个按键:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".scanf_dev">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/bv_barcode"
        android:layout_width="420dp"
        android:layout_height="530dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.555"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.497"
        app:zxing_preview_scaling_strategy="centerCrop"
        app:zxing_use_texture_view="false" />

    <Button
        android:id="@+id/button_scan_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="53dp"
        android:text="取消"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/bv_barcode" />

</androidx.constraintlayout.widget.ConstraintLayout>

然后把CaptureActivity.java 复制到新建的java文件里,然后只需要改动initializeContent()方法里的控件ID与xml布局文件一致即可。然后在创建添加的button监听事件实现取消返回上一个活动页面全部代码如下:

package com.example.uitest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;

import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;

public class scanf_dev extends AppCompatActivity {
    private CaptureManager capture;
    private DecoratedBarcodeView barcodeScannerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        barcodeScannerView = initializeContent();
        capture = new CaptureManager(this, barcodeScannerView);
        capture.initializeFromIntent(getIntent(), savedInstanceState);
        capture.decode();
        Button btn = findViewById(R.id.button_scan_back);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(scanf_dev.this,AddDevice.class);
                startActivity(intent);
            }
        });
    }
    /**
     * Override to use a different layout.
     *
     * @return the DecoratedBarcodeView
     */
    protected DecoratedBarcodeView initializeContent() {
        setContentView(R.layout.activity_scanf_dev);
        return (DecoratedBarcodeView)findViewById(R.id.bv_barcode);
    }

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

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

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

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        capture.onSaveInstanceState(outState);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

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

扫描界面就算是做完了,接下来就是引用。在IntentIntegrator类中提供 了引用自定义扫描界面的方法,setCaptureActivity(CustomView.class);我们只需要在扫描按钮的监听事件中添加该方法就可以把我们新建的界面替换成扫描界面,改完后是下面这样:

scanbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IntentIntegrator integrator = new IntentIntegrator(AddDevice.this);
                integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
                integrator.setPrompt("请对准二维码");
                integrator.setCameraId(0);
                integrator.setOrientationLocked(false);
                integrator.setBeepEnabled(true);
                integrator.setBarcodeImageEnabled(true);
                integrator.setCaptureActivity(scanf_dev.class);
                integrator.initiateScan();
            }
        });

现在就可以实现竖屏扫描并且带有取消按钮了。如果需要更多功能都可以在自定义的界面里完成。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在Android应用中使用ZXing库来实现扫描二维码功能,您可以按照以下步骤操作: 1. 在您的项目中添加ZXing库的依赖。您可以在build.gradle文件中添加以下依赖: ```gradle implementation 'com.google.zxing:core:3.4.0' implementation 'com.journeyapps:zxing-android-embedded:3.6.0' ``` 2. 在您的布局文件中添加一个用于显示摄像头预览的SurfaceView: ```xml <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 在您的代码中创建一个ZXing库的核心对象和一个用于处理扫描结果的回调函数: ```java private CaptureManager capture; private ZXingScannerView scannerView; private void initScanner() { scannerView = new ZXingScannerView(this); setContentView(scannerView); capture = new CaptureManager(this, scannerView); capture.initializeFromIntent(getIntent(), null); capture.decode(); scannerView.setResultHandler(new ResultHandler()); } private class ResultHandler implements ZXingScannerView.ResultHandler { @Override public void handleResult(Result rawResult) { // 处理扫描结果 String result = rawResult.getText(); // 在此处添加您的处理逻辑 // ... // 重新开始扫描 scannerView.resumeCameraPreview(this); } } ``` 4. 在您的Activity的onCreate方法中调用initScanner()方法来初始化扫描器: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initScanner(); } ``` 5. 在您的Activity的onResume方法中调用capture.onResume()和scannerView.onResume()方法来恢复扫描器: ```java @Override protected void onResume() { super.onResume(); capture.onResume(); scannerView.onResume(); } ``` 6. 在您的Activity的onPause方法中调用capture.onPause()和scannerView.onPause()方法来暂停扫描器: ```java @Override protected void onPause() { super.onPause(); capture.onPause(); scannerView.onPause(); } ``` 7. (可选)您可以在您的Activity的onDestroy方法中调用capture.onDestroy()方法来释放扫描器: ```java @Override protected void onDestroy() { super.onDestroy(); capture.onDestroy(); } ``` 现在您的应用已经可以使用ZXing库来扫描二维码了。在您的应用中启动这个Activity,您将看到一个用于扫描二维码的摄像头预览界面。当您扫描到一个二维码时,它的内容将会传递给您在第3步中创建的ResultHandler对象的handleResult方法中。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值