项目需要一个二维码扫描功能

image

关于二维码的扫描,我之前就听说过ZXing了(虽然从来没用过)

所以既然这次要用它了,自然是得搜索一番资料咯。

在开始介绍之前,我先说一下我的使用情况吧,网上的博客里面基本上都把Zxing框架自己封装了,或者在教程中需要添加library然后修改源文件。否则你就无法自定义ZXing,并且你还会遇到某些问题——比如二维码扫描图片是横屏的。

幸运的是这些问题我都遇到了!!!

image

还好,我花了几个小时,终于是解决了上面这些问题,不用更改源码,也是可以对二维码扫描页面自定义的。

首先,贴上ZXing的android端GitHub地址:

zxing-android-embedded

好吧,接下来就开始介绍如何使用了。

一、ZXing框架的集成

在你的项目的根目录下的build.gradle中需要配置这个:

repositories {jcenter()
}

然后是app目录下的build.gradle,配置如下:

dependencies {compile('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }compile 'com.android.support:appcompat-v7:25.3.1'   //如果V7已经配置过,那就不要重复添加了compile 'com.google.zxing:core:3.3.0'
}

下面在AndroidManifest.xml中添加,表示开启硬件加速,其实没必要,因为一般硬件加速都是默认开启的

  <application android:hardwareAccelerated="true" ... >

二、ZXing框架的使用

配置完成后就可以使用了。

使用的方式非常简单,在github的说明文档中,仅仅需要一行代码就可以打开二维码的扫描界面了:

new IntentIntegrator(this).initiateScan();

可以在一个Button的点击事件中添加这行代码,然后你只需要在当前的Activity中重写onActivityResult去获取结果就ok了。

不过。。。

image

如果你以为事情真的那么简单那你就大错特错了,下面我们看一下扫码的页面:

看完以上页面你会冒出两个问题:

1.要如何去自定义扫码界面?
2.怎么把界面竖过来?

好了,接下来就着手去准备解决这两个问题!

1、自定义扫码界面

在ZXing的github说明文档有提到过如何去自定义界面:

官方的建议是看例子,然后看源码。

下面是介绍如何去自定义扫描界面的文档地址:

DecoratedBarcodeView

之前有提到过ZXing配置好后一行代码就可以开启二维码扫描页面,在知道如何自定义界面之前我们可以了解一下这一行代码是怎么打开扫描页面的。

new IntentIntegrator(this).initiateScan();

上面的代码中,this就是当前Activity的引用,而IntentIntegrator类中的initiateScan()方法其实就是调用了startActivityForResult()方法:

    public final void initiateScan() {startActivityForResult(createScanIntent(), requestCode);}

上面方法中的createScanIntent()返回一个从当前Activity跳转到另外一个Activity的Intent

    public Intent createScanIntent() {Intent intentScan = new Intent(activity, getCaptureActivity());...return intentScan;}

而要跳转的Activity也就是二维码的扫描界面了,它实际上就是CaptureActivity:

    public Class<?> getCaptureActivity() {if (captureActivity == null) {captureActivity = getDefaultCaptureActivity();}return captureActivity;}protected Class<?> getDefaultCaptureActivity() {return CaptureActivity.class;}

所以我们想自定义二维码扫描界面,就需要从CaptureActivity入手,接下来就是自定义界面的重点了!

CaptureActivity的代码非常少,连一百行都不到,之前看过的许多博客都是写一个类继承CaptureActivity,但其实这样也不够方便,我的做法是直接创建一个Activity,将CaptureActivity中的代码复制过来,然后稍作改动即可,接下来我创建一个活动ScanQRCodeActivity:

public class ScanQRCodeActivity extends AppCompatActivity {private CaptureManager capture;private DecoratedBarcodeView bv_barcode;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scan_qrcode);bv_barcode = (DecoratedBarcodeView) findViewById(R.id.bv_barcode);capture = new CaptureManager(this, bv_barcode);capture.initializeFromIntent(getIntent(), savedInstanceState);capture.decode();}@Overrideprotected void onResume() {super.onResume();capture.onResume();}@Overrideprotected void onPause() {super.onPause();capture.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();capture.onDestroy();}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);capture.onSaveInstanceState(outState);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {capture.onRequestPermissionsResult(requestCode, permissions, grantResults);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {return bv_barcode.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);}}

上面的代码与CaptureActivity相差无几,只不过把布局界面替换了一下,下面是布局界面R.layout.activity_scan_qrcode:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".Activity.ScanQRCodeActivity"><com.journeyapps.barcodescanner.DecoratedBarcodeView        android:id="@+id/bv_barcode"app:zxing_use_texture_view="false"app:zxing_preview_scaling_strategy="centerCrop"android:layout_width="match_parent"android:layout_height="match_parent"/></android.support.constraint.ConstraintLayout>

在这个活动的布局界面中,我们只添加了一个DecoratedBarcodeView,它就是扫描界面的核心,之后如果想自定义布局,从这个活动的layout入手即可。

然后,我们就可以用我们自己创建的这个活动去代替CaptureActivity了,开心的是启动二维码扫描界面依旧是一行,不过现在它变成这样了:

new IntentIntegrator(this).setCaptureActivity(ScanQRCodeActivity.class).initiateScan();

上面的方法中多了一个setCaptureActivity()方法,这个方法看源码非常简单了,调用这个方法可以把默认的CaptureActivity替换为我们自定义的ScanQRCodeActivity。

接下来你只需要重写当前活动的onActivityResult()方法,即可正常使用扫码工具了,具体用法就是:

    @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);if(result != null) {if(result.getContents() == null) {Log.d(getClass().getName(), "Cancelled");Toast.makeText(this, "扫描结果为空", Toast.LENGTH_LONG).show();} else {Log.d(getClass().getName(), "Scanned: " + result.getContents());Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();}}}

这样,自定义问题就解决了,接下来就是如何做到竖屏扫描

2、竖屏显示扫码界面

这个问题的解决方案其实在github的说明文档中也有,不过存在一点小问题,下面是完善做法:

由于之前我们自定义了一个活动ScanQRCodeActivity,将其在AndroidManifest中配置改为:

 <activity android:name=".Activity.ScanQRCodeActivity"android:screenOrientation="fullSensor"xmlns:tools="http://schemas.android.com/tools"tools:replace="screenOrientation"/>

接下来看一下效果即可:

大功告成!

接下来,就可以使用Zxing扫码了!

But。。。

实际使用的时候需求不会是这么简单的,下面有两个主要的需要,看一下如何不更改源码去实现它们:

需求一:扫码结束后依旧停留在当前页面

从上面的情况来看,扫码返回的结果是在上一个Activity中获得的,所以每次扫码结束后就会退出扫码界面,那么,如何解决这个问题呢?

其实很简单

我们已经知道了,实现扫码的View是DecoratedBarcodeView,在这个视图的方法中,有一个回调方法——BarcodeCallback

重点来啦,BarcodeCallback回调方法其实就是获取扫描结果的核心,只需要给DecoratedBarcodeView设置该回调就可以在当前Activity获取扫描结果:

    private BarcodeCallback barcodeCallback = new BarcodeCallback() {@Overridepublic void barcodeResult(BarcodeResult result) {if (result != null){Log.e(getClass().getName(), "获取到的扫描结果是:" + result.getText());}}@Overridepublic void possibleResultPoints(List<ResultPoint> resultPoints) {}};

设置回调:

bv_barcode.decodeSingle(barcodeCallback);

上面的decodeSingle()方法表示只扫描一次,也就是获取到结果后就不再进行扫描。

到这里,第二个需求就来了

需求二:在当前页面进行多次扫描

DecoratedBarcodeView的设置回调方法里共有两种方法去设置回调,分别是:

  • bv_barcode.decodeSingle(barcodeCallback);

  • bv_barcode.decodeContinuous(barcodeCallback);

其实想要连续扫描,使用第二个方法即可,不过万万没想到,如果你使用了decodeContinuous()去设置回调的话,那你扫描成功的一瞬间,你会获得重复N次的扫描结果,显然,这种体验是蛋疼的,接下来又是亮点,要怎么去处理这个问题呢?

解决问题的方法依旧很简单,你只需要注意到我之前在Activity生命周期中有写到的这两个方法:

bv_barcode.resume();bv_barcode.pause();

看到这里,想必你已经知道接下来该怎么做了

没错,在获取扫码结果回调的方法中调用:

bv_barcode.pause();

然后再你处理结果后再调用:

bv_barcode.resume();

比如我这样写:

    private BarcodeCallback barcodeCallback = new BarcodeCallback() {@Overridepublic void barcodeResult(BarcodeResult result) {bv_barcode.pause();if (result != null){Log.e(getClass().getName(), "获取到的扫描结果是:" + result.getText());//可以对result进行一些判断,比如说扫描结果不符合就再进行一次扫描if (result.getText().contains("符合我的结果")){//符合的可以不在扫描了,当然你想继续扫描也是可以的} else {bv_barcode.resume();}}}@Overridepublic void possibleResultPoints(List<ResultPoint> resultPoints) {}};

接下来看一看最终简易版的实现代码吧:

public class MainActivity extends AppCompatActivity{private DecoratedBarcodeView bv_barcode;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bv_barcode = findViewById(R.id.bv_barcode);bv_barcode.decodeContinuous(barcodeCallback);}@Overrideprotected void onResume() {super.onResume();bv_barcode.resume();}@Overrideprotected void onPause() {super.onPause();bv_barcode.pause();}private BarcodeCallback barcodeCallback = new BarcodeCallback() {@Overridepublic void barcodeResult(BarcodeResult result) {bv_barcode.pause();if (result != null){Log.e(getClass().getName(), "获取到的扫描结果是:" + result.getText());//可以对result进行一些判断,比如说扫描结果不符合就再进行一次扫描if (result.getText().contains("符合我的结果")){//符合的可以不在扫描了,当然你想继续扫描也是可以的} else {bv_barcode.resume();}}}@Overridepublic void possibleResultPoints(List<ResultPoint> resultPoints) {}};
}

好的,不修改源码实现自定义Zxing二维码扫描的学习就到此结束了,有什么问题请留言交流。

image

二维码框架Zxing的使用及自定义相关推荐

  1. maven项目引入Google二维码框架zxing实现二维码(支持logo图)

    pom依赖: <!--二维码--> <dependency><groupId>com.google.zxing</groupId><artifac ...

  2. 安卓框架之二维码框架zxing的快速上手

    Zxing的使用 导入依赖: compile 'cn.yipianfengye.android:zxing-library:2.2' 申请权限: <!--震动权限--><uses-p ...

  3. 生成和扫描二维码(ZXing库)

    生成和扫描二维码(ZXing库) 一.ZXing概述 ZXing是谷歌自己推出的一个开源源码的二维码框架,可以实现使用手机的摄像头完成条形码的扫描和解码. 二.整合ZXing框架 将预先获取的core ...

  4. 技术解读 一维码,二维码,zxing

    一维码,二维码,zxing 什么是一维码.二维码?一维码就是商品包装盒上的条形码,例如:书本后面的条形码,在真维斯或者其他等品牌店的衣服标签上都可以看到,一维码的应用已经很广泛了:而二维码就是.... ...

  5. 鸿蒙二维码开发Zxing

    鸿蒙二维码开发Zxing 一,概述 鸿蒙中目前选用开源三方库Zxing进行二次封装开发来完成二维码扫描和生成,Zxing目前已经相当的成熟和稳定,是纯Java库,所以可以直接在鸿蒙工程中引用. 首先简 ...

  6. Java简单的生成/解析二维码(zxing qrcode)

    Hi I'm Shendi Java简单的生成/解析二维码(zxing qrcode) 在之前使用 qrcode.js 方式生成二维码,但在不同设备上难免会有一些兼容问题,于是改为后端(Java)生成 ...

  7. Unity二维码插件 ZXing

    1.二维码常见的生成与识别途径 1.草料二维码 https://cli.im/text 2.在软件中实现生成和扫描二维码 使用zxing实现 zxing是一个用java写的开源项目,zxing.net ...

  8. 解决Android二维码扫描ZXing竖屏拉伸变长闪退扫描区域小等问题

    Android 基于google Zxing实现二维码.条形码扫描,仿微信二维码扫描效果 这篇文章写的不错,但是按照这篇文章使用二维码的话会出现竖屏扫描图像拉伸变长的问题(有一个地方计算错误),解决拉 ...

  9. 二维码扫描ZXing简化

    最近项目中有需要用到二维码扫描功能,于是查了相关资料,也没有过多地研究ZXing源码,只是有了最简单的功能,因为下载大牛的demo已经完全实现了功能,只是对其中的扫描线做了更改,需要的朋友可以直接使用 ...

最新文章

  1. 建议收藏!从零开始学PyTorch
  2. 代理详解 静态代理+JDK/CGLIB 动态代理实战
  3. jzoj3085. 图的计数
  4. 对 Session 的深入探讨
  5. 谷歌浏览器同步功能无法加载_谷歌浏览器Chrome 86正式发布,全新重磅功能上线——密码检查...
  6. https无法访问 宝塔_宝塔面板快速开启ssl(https)的方法
  7. 神奇的Gamma函数(scipy)
  8. 【CCCC】PAT : 团体程序设计天梯赛-练习集 L2 答案,题解,附代码
  9. 零信任嵌入式安全沙箱技术,企业应用软件的技术底座
  10. 多指标评价方法-变异系数法的pathon实现
  11. 豆瓣读书TOP250书籍信息爬虫脚本
  12. 关于Android手机拍照预览、剪裁界面出现照片九十度旋转的问题
  13. URI中有关@符号的一些猥琐idea
  14. 物质模拟器3.0版,变得彩色
  15. android 头像高斯模糊,Android 高斯模糊头像
  16. docker启动和关闭命令
  17. python--pyecharts地图、地图标记可视化实现《四》--地图可视化[视觉盛宴]
  18. 四大运营商频段最新划分情况
  19. Matlab代码生成之SIL/PIL测试
  20. 【上传文件】基于阿里云的视频点播VOD、对象存储OSS实现音视频图片等文件上传

热门文章

  1. 字节旗下火山引擎违规分发SkyWalking,更改所有包名、删除Apache基金会抬头
  2. 微信公众号文章复制到服务器后台,微信个人公众号开发-打通后台服务器任督二脉...
  3. Python音频信号处理库函数librosa介绍
  4. 瓦罐香沸快餐 特色盈利项目
  5. bm25算法Java代码_搜索引擎相关度算法 -BM25 JAVA实现
  6. 算法训练 2的次幂表示
  7. 17 类蓝图实现灯光开关效果
  8. oracle 查看索引大小_技术分享|简述Oracle统计信息
  9. 第二章 SQL聚合函数 AVG
  10. CCF(中国计算机协会) A会 B会 C会 全部会议汇总