demo地址:https://github.com/dddjjq/ZxingTest.git
前段时间需要扫描二维码及做一些与服务器通信的动作,所以也了解了一些zxing框架,当前最新的版本是3.3.3
首先需要下载zxing的源码并作为library,Android studio File->New->New Module->Android library,然后将!
这两个文件夹下的源码导入到library中,注意包名要一致,android-core里面只有一个文件,直接按照包名路径拷进去即可。还需要core下的代码,不过这个要打包成Jar包的形式,可以通过网上的教程自己打包,也可以直接下载别人打包好的jar包,导入之后会有R文件报错,删掉之前的引用,重新alt+enter导入最新的R路径即可。
注意
app module里面也会用到这个jar包,最开始的时候library和app都引入了,然后build的时候报错,说是重复引用,这里需要修改library的gradle:
这里的implementation要改成compile,因为implementation只能自己引用自己的jar包,app无法引用
二维码扫描是用的zxing里面的CaptureActivity,但是app里面无法直接调用,所以需要添加到AndroidManifest文件中:
这样就可以直接调用到,进入扫描界面,当前的版本UI是这样:
UI的话,可以自己进行修改,不过一般也只是文字这些修改。
这样直接导入会出现两个问题:
1、扫描会出现拉伸画面,这是因为默认是横屏扫描,而手机屏幕是竖屏的,所以需要修改屏幕方向
2、近距离无法扫描
修改如下:
拉伸问题:
DecodeHandler.java decode方法
新加:
byte[] rotatedData =new byte[data.length];
for(int y =0; y < height; y++) {
for(int x =0; x < width; x++)
rotatedData[x * height + height - y -1] = data[x + y * width];
}
int tmp = width;
width = height;
height = tmp;
data = rotatedData;
CameraConfigurationUtils.java文件->findBestPreviewSizeValue方法、新加getCameraResolution方法
Point screenResolutionForCamera = new Point();
screenResolutionForCamera.x = screenResolution.x;
screenResolutionForCamera.y = screenResolution.y;
// preview size is always something like 480*320, other 320*480
if (screenResolution.x < screenResolution.y) {
screenResolutionForCamera.x = screenResolution.y;
screenResolutionForCamera.y = screenResolution.x;
}
Point cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);
Log.i(TAG, "No suitable preview sizes, using default: " + cameraResolution);
return cameraResolution;
/*Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
return defaultSize;*/ //这里注释掉之前的三行
private static Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) {
String previewSizeValueString = parameters.get("preview-size-values"); // saw this on Xperia
if (previewSizeValueString == null) {
previewSizeValueString = parameters.get("preview-size-value");
}
Point cameraResolution = null;
if (previewSizeValueString != null) {
Log.e(TAG, "preview-size-values parameter: " + previewSizeValueString);
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
}
if (cameraResolution == null) { // Ensure that the camera resolution is a multiple of 8, as the screen may not be.
cameraResolution = new Point((screenResolution.x >> 3) << 3, (screenResolution.y >> 3) << 3);
}
return cameraResolution;
}
近距离无法扫描问题:
CameraManager.java -> getFramingRectInPreview方法
/*rect.left = rect.left * cameraResolution.x / screenResolution.x;
rect.right = rect.right * cameraResolution.x / screenResolution.x;
rect.top = rect.top * cameraResolution.y / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;*/
rect.left = rect.left * cameraResolution.y / screenResolution.x;
rect.right = rect.right * cameraResolution.y / screenResolution.x;
rect.top = rect.top * cameraResolution.x / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
到这里,发现扫描界面可以正常工作,只是扫描成功之后,URL会体现在屏幕上,而且扫描activity不会消失,这里需要修改一下:
intent启动CaptureActivity时使用startActivityForResult方法,并修改CaptureActivity.java文件,在handleDecode方法的后面setResult之前把rawResult.getText()作为结果传递给之前的activity:
然后在源activity的onActivityResult的方法中做UI显示等操作。
自此,扫描二维码的工作也差不多做完了,不过也只是一些很基本的调用操作,更深层次的使用待后面研究了(用到了再研究了)