【android】Android实现二维码扫描功能(五)-封装与接入ZXing扫码库

简介
《Android实现二维码扫描功能》系列文章陆续收到不少开发者的反馈,看到大家这么关注这个专栏,最近抽空对ZXing扫码和生成二维码又做了优化,封装了一个Android library:zxing-lib,这样在接入应用的过程中会更加方便。

预览
在zxing-lib库的基础上做了新版的demo,新添加了生成二维码功能,预览效果如下:(由于录像的mp4转换gif过程中存在失真,色彩有点奇怪,不影响预览)

 

 集成步骤
1、拷贝library至个人项目中
Clone或者Download示例项目:QrCodeLib,把项目中的zxing-lib拷贝至个人项目中,如示例项目QrCodeLib的目录结构。

 

 

2、添加库依赖。

1)在settings.gradle中添加library依赖:

 include ':app', ':zxing-lib'

2)在自己的项目module中添加project依赖,如在app模块的build.gradle中添加:

dependencies {
       ...
    implementation project(':zxing-lib')
    ...
}

3、在app模块中的AndroidManifest.xml文件中注册相关权限、注册zxing-lib库中的CaptureActivity:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dommy.qrcodelib">
 
    <uses-permission android:name="android.permission.INTERNET" /> <!-- 网络权限 -->
    <uses-permission android:name="android.permission.VIBRATE" /> <!-- 震动权限 -->
    <uses-permission android:name="android.permission.CAMERA" /> <!-- 摄像头权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 自动聚焦权限 -->
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity android:name="com.google.zxing.activity.CaptureActivity" />
    </application>
 
</manifest>

接入使用
扫码
扫码需要用到摄像头权限,如果有读图解码的还有文件读写权限,这些按需注册与申请(注意Android6.0以上的动态权限),权限这块demo里面有示例,前面的文章也有讲解。

封装成库以后,对CaptureActivity的修改需要到zxing-lib中去改,这样把二维码相关的核心代码都整合在一起,方便拷贝与使用,比之前零散的整合进入项目要省心的多。

打开扫码界面:

// 二维码扫码
Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
startActivityForResult(intent, Constant.REQ_QR_CODE);

接收扫码返回值:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //扫描结果回调
    if (requestCode == Constant.REQ_QR_CODE && resultCode == RESULT_OK) {
        Bundle bundle = data.getExtras();
        String scanResult = bundle.getString(Constant.INTENT_EXTRA_KEY_QR_SCAN);
        //将扫描出的信息显示出来
        tvResult.setText(scanResult);
    }
}

生成二维码
本次新增了生成二维码的功能,比较简单,在页面中添加一个ImageView控件,然后使用zxing库提供的生成二维码Bitmap的方法,就可以得到bitmap,塞入ImageView显示即可。

Bitmap bitmap = QrCodeGenerator.getQrCodeImage(etContent.getText().toString(), imgQrcode.getWidth(), imgQrcode.getHeight());
if (bitmap == null) {
     Toast.makeText(this, "生成二维码出错", Toast.LENGTH_SHORT).show();
     imgQrcode.setImageBitmap(null);
 } else {
     imgQrcode.setImageBitmap(bitmap);
 }

QrCodeGenerator.java是基于ZXing核心库的一层封装:

package com.google.zxing.util;
 
import android.graphics.Bitmap;
import android.graphics.Color;
 
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 
import java.util.HashMap;
import java.util.Map;
 
public class QrCodeGenerator {
 
    public static Bitmap getQrCodeImage(String data, int width, int height) {
        if (data == null || data.length() == 0) {
            return null;
        }
        Map<EncodeHintType, Object> hintsMap = new HashMap<>(3);
        hintsMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hintsMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hintsMap.put(EncodeHintType.MARGIN, 0);
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(data, BarcodeFormat.QR_CODE, width, height, hintsMap);
            Bitmap bitmap = bitMatrix2Bitmap(bitMatrix);
            return bitmap;
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    private static Bitmap bitMatrix2Bitmap(BitMatrix matrix) {
        int w = matrix.getWidth();
        int h = matrix.getHeight();
        int[] rawData = new int[w * h];
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                int color = Color.WHITE;
                if (matrix.get(i, j)) {
                    color = Color.BLACK;
                }
                rawData[i + (j * w)] = color;
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
        bitmap.setPixels(rawData, 0, w, 0, 0, w, h);
        return bitmap;
    }
 
}

建议的可调参数:

EncodeHintType.ERROR_CORRECTION:这个是二维码容错等级,需要容错搞的可以设置高一些,生成的图片像素点会更多、更密集;
EncodeHintType.MARGIN:调整生成图片的外边距,调整以后边缘部分填充白边,demo中没有留白边,设置的是0。
结语
本次将原先的QrCodeDemo进行改进,让开发者能更加方便的接入ZXing库来进行二维码相关功能开发,也方便了二维码库后期的维护。关于库依赖的方式,有几点说明:

没有将zxing-lib上传至jcenter仓库,所以使用的时候需要做源码的拷贝,没有办法直接通过jcenter依赖的方式构建;
使用源码的优势是方便根据自己业务定制和修改,里面的文字标识、图片素材,都可以根据项目情况灵活修改。
如果开发者觉得当前的zxing-lib有扫码效率问题,可以自己想办法优化一下。

源码下载

Github项目地址:
https://github.com/ahuyangdong/QrCodeLib

Android实现二维码扫描功能(一)-ZXing插件接入

 

posted @ 2023-02-03 15:36  opensmarty  阅读(570)  评论(0编辑  收藏  举报