最近几年二维码是越来越火了,特别是随着移动端的便利性,走到哪里都是扫一扫。二维码支付、二维码扫描登录、二维码扫描关注加好友.....越来越多的应用也都加上了二维码扫描的功能,作为移动开发者,对这些新奇的东西当然要尝试一下了。在查阅了一下网上的资料后,自己算是对二维码的扫描和生生成有了个初步的了解,写个笔记,以后想集成进项目时,也会方便很多。
首先,什么是二维码?
“二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。 ”
百科的解释如此。既然有二维码,那么肯定有一维码。相信你们对一维码认识的更早,因为一维码。最为常见的就是各种包装商品或者书籍后面的条码。当然本项目也是支持一维码的识别的。
二维码在不同的语言和平台下有不同的支持库,Android当然是选择java支持库了,这个项目是google的大神开发的ZXing库。github地址是:https://github.com/zxing/zxing。
相信大家都和我一样,下载后,都在考虑那怎么样集成进去项目里试一试了?因为这个库文件还是很大的。我们选择自己想要的即可。
首先你得找到zxing.jar包,并添加到项目库中,其次你需要这几个包和里面的文件,包名我改了点。然后将对应的资源也引进去,注意其是放在values文件夹下的。
其中carmera包,是对相机的初始化和一些配置处理;decoding是对相机扫描回的结果的分析处理;view是扫描框和接口处理回调。
项目里还有其他2个包,里面结构如下:
其中MainActivity是程序主入口,CustomScanViewActivity是自定义扫描窗口的FragmentActivity,CaptureFragment是自定义扫描窗口的view,在这进行相机的初始化,和处理扫描结果。扫描成功后将扫描的结果和二维码当作参数传递到handleDecode方法里进行处理,这里采用的是接口回调的方式,进行处理:
/**
* 处理扫描结果
*
* @param result
* @param barcode
*/
public void handleDecode(Result result, Bitmap barcode) {
inactivityTimer.onActivity();
playBeepSoundAndVibrate();
if (result == null || TextUtils.isEmpty(result.getText())) {
if (analyzeCallback != null) {
analyzeCallback.onAnalyzeFailed();
}
} else {
if (analyzeCallback != null) {
analyzeCallback.onAnalyzeSuccess(barcode, result.getText());
}
}
}
接口函数
/**
* 解析二维码结果接口函数
*/
public interface AnalyticCallback{
public void onAnalyzeSuccess(Bitmap mBitmap, String result);
public void onAnalyzeFailed();
}
解析方法
/**
* 解析二维码图片方法
* @param mBitmap
* @param analyzeCallback
*/
public static void analyticBitmap(Bitmap mBitmap, AnalyticCallback analyzeCallback) {
MultiFormatReader multiFormatReader = new MultiFormatReader();
// 解码的参数
Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(2);
// 可以解析的编码类型
Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>();
if (decodeFormats == null || decodeFormats.isEmpty()) {
decodeFormats = new Vector<BarcodeFormat>();
// 这里设置可扫描的类型
decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);//条形码
decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);//二维码
decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);//其他码
}
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
// 设置解析配置参数
multiFormatReader.setHints(hints);
// 开始对图像资源解码
Result rawResult = null;
try {
int width = mBitmap.getWidth();
int height = mBitmap.getHeight();
int[] pixels = new int[width * height];
mBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
rawResult = multiFormatReader.decode(new BinaryBitmap(new HybridBinarizer(source)));
} catch (Exception e) {
e.printStackTrace();
}
if (rawResult != null) {
if (analyzeCallback != null) {
analyzeCallback.onAnalyzeSuccess(mBitmap, rawResult.getText());
}
} else {
if (analyzeCallback != null) {
analyzeCallback.onAnalyzeFailed();
}
}
}
由上面可以看出,我把一维码也添加进去了,也就支持扫条形码了。当然还可以扫描本地的二维码图片,首先我们要打开本地的图库,这里有2个方法,但是有个方法有点小bug,他打不开我自己的截图,因为他打开的是手机里的图库(相册)应用,而截图不在图库里,所以不能添加(我华为荣耀手机是这样的,不知道其他型号手机是否是这样),为此我采用了另外一个方法,列出系统图片文件夹表,让用户自己选择。
方法一:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.set