您的位置:首页 > 移动开发 > Android开发

教你移植Zxing二维码,兼容Android6.0

2016-07-12 20:12 387 查看
几天的移植历程,以下是不断完善的过程

好多图片啊



解压出来文件目录如下,其中core为zxing的解码库,可以单独导入eclipse生成jar;android文件夹是整个安卓的核心,打开摄像头之类的都在此进行,android-core内面只有一个java文件,用来配置摄像头。

我并没有把core的文件都生成jar,因为直接放入Android studo也是毫无问题的,我把文件做成了一个库。在库中资源文件的id号不能用(反正不让我编译),直接换成静态int值算了。还有菜单都会报一些错的,不过没关系,后面都是要删的,按照Android studio的提示弄就可以了。



Android的东西在client目录下,我们动也只是动这里的代码,core的代码没必要搞。其中想wifi、share、history等的代码是没用的,因为我最想得到的只有两样东西,第一:扫描结果,第二:生成二维码。其他删除好了。



原来库是支持动态识别旋转的,但是这样的功能我觉得是没意义的,在扫码的时候转来转区更蛋疼,删掉好了,直接在manifest配置好了,万事大吉



下面我首先精简目录先,此时的摄像头数据在识别的时候还是横屏的,还需要改的,不过,不急,后面再搞它,现在目录太臃肿了,算,还是把core做成jar好了。。



直接把core的代码丢进去。工程编译不要选择jdk1.8,会出错的。。。选1.7,反正选1.8 Android studio不给我编译,我的版本是2.1.2是最新的。。。



直接导出所有,简单粗暴



然后放进Android studio的libs就可以了。



瞬间就只剩下安卓的东西了。现在,先把生成二维码搞出来先。



定位到是这个ShareActiviy就是跳转到生成二维码activity



二维码展示页面,剩下就开始删除了



像这么多隐式的条件是没有必要的,删除些,剩下生成二维码的隐式就行



最终确定下来就剩下三个页面:

第一个摄像头,第二个输入文字,第三个显示二维码

下一步,开始删除目录中多余的功能代码

Wifi目录直接删除,history(记录历史行为吧,没细看)也是直接删,clipboard剪切板,book(应该是搜索的,没细看)也不需要cut!,result中的supplement什么补充xxx貌似不需要,删!



第一次精简,费了很大的力气,删除了好多东西,终于能把所有东西显示了,后面还会再次精简!

现在着手解决下面图片的问题:

原来APP是横屏的,现在变成了竖屏,好像都挺正常,但是扫描就。。。





可以看出,数据还是横屏的,我们要做的是把竖屏的窗口映射到横屏上



先说一下整体流程:

1、初始化surfaceView,音频,扫描超时定时,手机震动

2、在surfaceCreated回调中初始化(打开硬件摄像头、计算分辨率、设置摄像头参数、计算分析二维码框的矩阵大小、设置摄像头预览数据回调、开启预览)

3、onPreviewFrame把摄像头的预览数据(数据是横屏的)通过sendmessage发送到DecodeThread

4、DecodeThread开启一个handler不断处理发送过来的数据(提取二维码矩形的数据,变黑白,识别) 处理后通过sendmessage发送到住UI线程处理

5、CaptureActivityHandler(UI的handler)的接收到正确的扫描结果,手机震动一下,“滴”一声,并通过setResult把数据返回

6、主应用程序收到相应数据进行显示

下面进入代码分析:

PreviewCallback是图片数据的获取回调,其中,onPreviewFrame()这个方法是就是直接得到byte的图片数据,通过这个方法,数据被发送到DecodeThread解码线程,不断的loop,这个解码线程是处理handler的线程,最终在DecodeHandler这个类中解码

PreviewCallback:



DecodeThread:



DecodeHandler:



里面重点的核心:private void decode(byte[] data, int width, int height)这就是解码函数



如果把传进来的数据一起解码的话,很浪费时间,所有红色框那条方法是用一个矩形,框住数据,解码只在矩形里面解,所以扫描的时候要对准那个框就是这样了。

所有现在需要解决映射问题就从那个函数入手了。



红色框就是 确定数据的矩形框。这中映射关系只是适合摄像头旋转90度的情况。





修改完毕!



虽然旋转了(横屏嘛),但是矩形计算正常。算是可以了



调整显示的矩形大小,位置,这里我修改了高度,与宽度一致



解码管理(由于可以解条形码等),我这里把多余的删除了,我不需要一维码,二维码就足够了。

但是还是不完美。如果我不想全屏,需要状态栏,如果改成有标题的,细心就发现原来1080*1920的数据挤压到1080*17xx(具体17多少忘了)的空间里,图形竖向被挤压了,如下图。



我就想,能不能不被挤压呢,因为这样看起啦不好看(我是完美主义),于是我想了一个简单方法,能不能只显示一部分呢,因为扫码根本不需要看到全部,于是就这样,把surfaceView强制设置高度,这样虽然图像少了一些,但是起码是不会被拉伸了。(有更好的方法求支招)



后面研究研究,又发现了两个致命问题。代码是根据横屏来写的,在寻找最合适了分辨率上是不对了,需要改一改,主要是把x与y交换,因为横屏 x比y长,竖屏y比x长。







修改的就是这个方法下面的两处地方。

第二个问题就是,摄像头的旋转问题,我的手机一部是旋转90度,一部是旋转270度的,在识别的时候就需要判断,不然会出现奇葩问题的。0度与180没实测过,没手机。



最后,基本把问题解决啦,把它做成了一个包,把填写二维码的页面也删除了,剩下一个扫描activity跟一个二维码展示activity。

下面就效果:



连续改了很久,很累,代码肯定有冗余,凑合看吧

<重点>工程代码:http://download.csdn.net/detail/a756213932/9574643
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: