简介
《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有扫码效率问题,可以自己想办法优化一下。
更多关于二维码扫描功能的讲解,参见专栏《Android实现二维码扫描功能》。
源码下载
Github项目地址:
https://github.com/ahuyangdong/QrCodeLib