Android基于zxing-android-embedded实现自定义扫码界面,连续扫码

一、相关设置

1、下载zxing-android-embedded

https://github.com/journeyapps/zxing-android-embedded

2、导入到项目中,我是作为模块导入的:file->new->import module,之前直接添加依赖导入无法编辑包里的源代码(比较low)

3、添加依赖:

在项目的build.gradle文件中的dependencies添加

implementation project(':zxing-android-embedded')

二、直接调用这个库

很简单,在你的活动中添加下列代码:

new IntentIntegrator(MainActivity.this)
                        .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)// 扫码的类型,可选:一维码,二维码,一/二维码
                        .setPrompt("请对准二维码")// 设置提示语
                        .setCameraId(0)// 选择摄像头,可使用前置或者后置
                        .setBeepEnabled(true)// 是否开启声音,扫完码之后会"哔"的一声
                        .setBarcodeImageEnabled(true)// 扫完码之后生成二维码的图片
                        .initiateScan();// 初始化扫码

默认的扫码活动是横屏,很多时候我们需要自定义扫码界面才能满足需求

默认扫码界面:(测试手机丢在车里了,不想下去拿了,勉强看一下)

 

三、自定义扫码界面:

默认的扫码界面的activity是CaptureActivity

 

我们需要自己写一个Activity,我写了个MyCaptureActivity,别忘了注册一下

package com.geek66.myzxing;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;

import java.util.ArrayList;

/**
 * @package com.geek66.myzxing
 * @name MyCaptureActivity
 * @date 2019/4/29 20:58
 * @auther Bibi
 * @decribe TODO 扫码活动,用来替代系统默认的CaptureActivity
 **/
public class MyCaptureActivity extends AppCompatActivity {
    private CaptureManager captureManager;
    private DecoratedBarcodeView barcodeView;
    private Button btn_result;
    private ArrayList<String> result_list;//存放连续扫描的结果
    private int i;//计数器,记录重复扫描次数
    private String[] goodsIdList;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mycapture);
        barcodeView = findViewById(R.id.dbv_my);
        btn_result = findViewById(R.id.btn_result);
        result_list = new ArrayList<>();
        captureManager = new CaptureManager(this,barcodeView);
        captureManager.initializeFromIntent(getIntent(),savedInstanceState);
        captureManager.setmResultCallBack(new CaptureManager.ResultCallBack() {
            @Override
            public void callBack(int requestCode, int resultCode, Intent intent) {
                IntentResult result  = IntentIntegrator.parseActivityResult(requestCode,resultCode,intent);
                if(result != null&& result.getContents()!=null){
                    i++;
                    btn_result.setText("已扫描"+i+"点击查看详情");

                    captureManager.onResume();//重新加载扫码界面
                    captureManager.decode();//调用扫码方法
                }
            }
        });
        captureManager.decode();
        btn_result.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(btn_result.getText().equals("点击查看扫描结果")){
                    Toast.makeText(MyCaptureActivity.this, "还未进行扫码操作", Toast.LENGTH_SHORT).show();
                } else {
                    captureManager.onPause();
                    Toast.makeText(MyCaptureActivity.this, "已扫码"+i , Toast.LENGTH_SHORT).show();
                    showListDialog(list2string(result_list));
                }
            }
        });
    }
    //已扫码物品详情列表
    private void showListDialog(String[] goodsIdList) {

        final AlertDialog.Builder listDialog = new AlertDialog.Builder(MyCaptureActivity.this);
        listDialog.setTitle("已扫码列表");
        listDialog.setItems(goodsIdList, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //扩展,增加删除条目功能
            }
        });
        listDialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //确认按钮事件
                Toast.makeText(MyCaptureActivity.this, "确认成功", Toast.LENGTH_SHORT).show();
                captureManager.closeAndFinish();//退出扫码活动

            }
        });
        listDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        listDialog.show();
    }
    //list转数组
    public String[] list2string (ArrayList<String> list){
        goodsIdList = new String[list.size()];
        for(int i=0;i<list.size();i++){
            goodsIdList[i] = list.get(i);
        }
        return goodsIdList;
    }



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

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

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

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

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

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

对应的布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:gravity="center_horizontal"
    android:orientation="vertical">

    <com.journeyapps.barcodescanner.DecoratedBarcodeView
        android:id="@+id/dbv_my"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:zxing_preview_scaling_strategy="fitXY"
        android:layout_weight="10"/>
    <Button
        android:id="@+id/btn_result"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="点击查看扫描结果"
        android:textSize="20sp"/>

</LinearLayout>

对应的界面样式:(很简单,就是一个l线性布局里面加个扫码控件和一个按钮,根据需要自己定义)

 

四、连续扫码,点击按钮-显示扫码结果并结束扫码活动。

这个时候我们需要更改下CaptureManager中的部分代码,首先修改returnResult方法:

//返回结果的方法
    protected void returnResult(BarcodeResult rawResult) {
        Intent intent = resultIntent(rawResult, getBarcodeImagePath(rawResult));
        activity.setResult(Activity.RESULT_OK, intent);
//        closeAndFinish(); 注释掉后扫码结束不会结束扫码活动

        if(barcodeView.getBarcodeView().isCameraClosed()) {
            if(null != mResultCallBack){
                mResultCallBack.callBack(IntentIntegrator.REQUEST_CODE,Activity.RESULT_OK,intent);
            }
        } else {
            finishWhenClosed = true;
        }
//        barcodeView.pause();注释掉后扫码返回结果时扫码view不会暂停,继续可以扫描
        inactivityTimer.cancel();
    }

注释掉的两行很关键,原因已在注释中写明。中间的那几行和下面要增加的接口、属性、方法有关,直接贴出来:

//以下三个是为了在MyCaptureActivity中重写callBack方法
    public interface ResultCallBack {
        void callBack(int requestCode,int resultCode,Intent intent);
    }

    private ResultCallBack mResultCallBack;

    public void setmResultCallBack(ResultCallBack resultCallBack){
        this.mResultCallBack= resultCallBack;
    }

作用写的很清楚了,就是为了在自定义的活动中重写callBack方法。


再贴个主活动代码,需要注意的是,使用自定义的界面时,需要增加

.setCaptureActivity(MyCaptureActivity.class)

MainActivity.java

package com.geek66.myzxing;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

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

public class MainActivity extends AppCompatActivity {
    Button button1;//单次扫码
    Button button2;//持续扫码
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = findViewById(R.id.btn_scan);
        button2 = findViewById(R.id.btn_scan2);
        //调用系统默认扫码界面
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new IntentIntegrator(MainActivity.this)
                        .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)// 扫码的类型,可选:一维码,二维码,一/二维码
                        .setPrompt("请对准二维码")// 设置提示语
                        .setCameraId(0)// 选择摄像头,可使用前置或者后置
                        .setBeepEnabled(true)// 是否开启声音,扫完码之后会"哔"的一声
                        .setBarcodeImageEnabled(true)// 扫完码之后生成二维码的图片
                        .initiateScan();// 初始化扫码
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new IntentIntegrator(MainActivity.this)
                        .setCaptureActivity(MyCaptureActivity.class)
                        .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)// 扫码的类型,可选:一维码,二维码,一/二维码
                        .setPrompt("请对准二维码")// 设置提示语
                        .setCameraId(0)// 选择摄像头,可使用前置或者后置
                        .setBeepEnabled(true)// 是否开启声音,扫完码之后会"哔"的一声
                        .setBarcodeImageEnabled(true)// 扫完码之后生成二维码的图片
                        .initiateScan();// 初始化扫码
            }
        });

    }
}

布局文件:就两个按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_scan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击开始扫描二维码"/>
    <Button
        android:id="@+id/btn_scan2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="自定义界面连续扫码"
        />
</LinearLayout>

我自己做项目用到的,参考了这篇博客(https://blog.csdn.net/u010618194/article/details/77891313),虽然作者针对这两个功能分析了部分代码,但仍然不是很全面。我自己也没有研究透,以后有新的需求再继续研究。

贴个demo的地址,需要自取:

https://github.com/qingDragon/MyZxing

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是Android使用zxing实现扫码功能的示例代码: 1. 首先添加zxing库依赖,在app的build.gradle文件中添加以下代码: ``` implementation 'com.google.zxing:core:3.4.0' implementation 'com.journeyapps:zxing-android-embedded:3.6.0' ``` 2. 在需要使用扫码功能的Activity中添加以下代码: ```java public class ScanActivity extends AppCompatActivity { private static final int REQUEST_CODE_SCAN = 0x0000; // 扫码请求码 private static final String DECODED_CONTENT_KEY = "codedContent"; // 扫码结果key private CaptureManager captureManager; // ZXing扫码管理器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan); // 初始化ZXing扫码管理器 captureManager = new CaptureManager(this, (DecoratedBarcodeView) findViewById(R.id.zxing_barcode_scanner)); captureManager.initializeFromIntent(getIntent(), savedInstanceState); captureManager.decode(); } @Override protected void onResume() { super.onResume(); captureManager.onResume(); } @Override protected void onPause() { super.onPause(); captureManager.onPause(); } @Override protected void onDestroy() { super.onDestroy(); captureManager.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return captureManager.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event); } /** * 扫码结果回调方法 */ public void onScanResult(String result) { Intent intent = new Intent(); intent.putExtra(DECODED_CONTENT_KEY, result); setResult(RESULT_OK, intent); finish(); } /** * 启动扫码界面 */ public static void start(Activity activity) { Intent intent = new Intent(activity, ScanActivity.class); activity.startActivityForResult(intent, REQUEST_CODE_SCAN); } /** * 获取扫码结果 */ public static String getScanResult(Intent data) { return data.getStringExtra(DECODED_CONTENT_KEY); } } ``` 3. 在布局文件中添加zxing扫码控件: ```xml <com.journeyapps.barcodescanner.CaptureDecoratedBarcodeView android:id="@+id/zxing_barcode_scanner" android:layout_width="match_parent" android:layout_height="match_parent" app:zxing_use_texture_view="true" app:zxing_framing_rect_height="240dp" app:zxing_framing_rect_width="240dp" app:zxing_preview_scaling_strategy="fitCenter" /> ``` 4. 在需要使用扫码功能的地方调用`ScanActivity.start(this)`方法启动扫码界面,并在`onActivityResult`方法中获取扫码结果: ```java @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == ScanActivity.REQUEST_CODE_SCAN && resultCode == RESULT_OK && data != null) { String result = ScanActivity.getScanResult(data); // 获取扫码结果 // 处理扫码结果 } } ``` 至此,Android使用zxing实现扫码功能的示例代码就完成了。完整的示例代码可以在以下链接中找到: https://github.com/zxing/zxing/tree/master/android/sample-app

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值