1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 二维码的扫描和生成(zxing-android-embedded)的基础使用

二维码的扫描和生成(zxing-android-embedded)的基础使用

时间:2020-12-26 00:47:49

相关推荐

二维码的扫描和生成(zxing-android-embedded)的基础使用

简述:这个博客主要记载zxing-android-embedded的简单使用,如何替换相机的布局,如何去掉生成二维码的空白等等一系列问题.

zxing-android-embedded的使用

1.首先添加依赖

implementation 'com.android.support:appcompat-v7:26.1.0'implementation 'com.journeyapps:zxing-android-embedded:3.6.0'

2.生成二维码

private void createQrCode(){BarcodeEncoder barcodeEncoder = new BarcodeEncoder();try {BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400);bitMatrix =deleteWhite(bitMatrix); //删除二维码周边的空白处 qrCodeBitmap=barcodeEncoder.createBitmap(bitMatrix);qrCodeImg.setImageBitmap(qrCodeBitmap);} catch (WriterException e) {e.printStackTrace();}}

3.扫描二维码

/*** 扫描二维码*/private void scanQrCode(){IntentIntegrator intentIntegrator = new IntentIntegrator(this);intentIntegrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE); //设置扫描的类型intentIntegrator.setOrientationLocked(false); //方向锁定intentIntegrator.setCaptureActivity(CustomCaptureActivity.class);intentIntegrator.setCameraId(0); //前置相机还是后置相机intentIntegrator.setBeepEnabled(false); //是否发出成功的声音intentIntegrator.setBarcodeImageEnabled(true);intentIntegrator.initiateScan();}

方向锁定的话,你还需要设置CaptureActivity,假如你是按依赖添加的而不是导入源码,那么需要

public class CustomCaptureActivity extends CaptureActivity {

}

在AndroidManifest里面设置

<activity android:name=".custom.CustomCaptureActivity"android:screenOrientation="fullSensor"tools:replace="screenOrientation"/>

在扫描完成之后,他会自动返回到onActivityResult()函数里面

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);if(result != null) {if(result.getContents() == null) {Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();} else {Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();}} else {super.onActivityResult(requestCode, resultCode, data);}}

这里的result.getContents()就是二维码内含的值

删除二维码生成时候的周围的空白

zing-android-embedde原始生成的二维码周围会有很多的空白,所以自己需要删除空白

/*** 删除二维码的空白区域* @param matrix* @return*/private static BitMatrix deleteWhite(BitMatrix matrix){int[] rec = matrix.getEnclosingRectangle();//数字7 代表了留的空白区域的大小int resWidth = rec[2] + 10;int resHeight = rec[3] + 10;BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);resMatrix.clear();for (int i = 10; i < resWidth; i++){for (int j = 10; j < resHeight; j++){if(matrix.get(i+rec[0],j+rec[1]))resMatrix.set(i,j);}}return resMatrix;}

自定义二维码扫描时候扫描的大小

因为zxing-android-embedded生成的界面比较难看,所以一般需要修改原生的界面。一般是修改源码或者是继承

本文因为是采用依赖导成jar进来的,所以采用的是继承的方式。

public class CustomCaptureActivity extends CaptureActivity {private ImageView oldBackImg;private CustomDecoratedBarcodeView customDecoratedBarcodeView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);oldBackImg = findViewById(R.id.oldBackImg);oldBackImg.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {finish();}});}@Overrideprotected DecoratedBarcodeView initializeContent(){setContentView(R.layout.custom_activity_zxing_capture);customDecoratedBarcodeView= findViewById(R.id.zxing_custom_barcode_scanner);return customDecoratedBarcodeView;}

}

最主要的是inittializeContent()方法,这个方法可以设置除了扫描以外的界面,比如加一个标题栏等等

DecoratedBarcodeView 就是扫描最重要的组成部分,他由两个View组成,第一个BarcodeView就是扫描的窗口,

第二个Viewfinder有效果。 所以我们如果想绘制扫描的界面可以重写Viewfineder的onDraw()方法

package .wingbackup.custom;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import com.journeyapps.barcodescanner.ViewfinderView;import .wingbackup.R;/*** Created by xiongbo on /11/14.*/public class CustomViewfinderView extends ViewfinderView {private static final String TAG = "CustomViewfinderView";/*** 画相机四个角落的值*/private Paint customPaint;/*** 获取相机的区域*/private Rect frame;/*** 修改这个值 可以修改角落绘制的颜色*/private int color;/*** 四个角落的宽度*/private int cornerWidth;/*** 四个角落的厚度*/private int cornerHeight;/*** 你需要在相机下面显示的文字*/private String text;/*** 中间横线竖直的位置*/private int direction;/*** 代表了第一次绘制*/private boolean isFirst;/*** 是否获取二维码的结果*/private boolean isResult;/*** 是否退出线程*/private boolean isExit;private Thread thread;public CustomViewfinderView(Context context, AttributeSet attrs) {super(context, attrs);customPaint = new Paint();customPaint.setStyle(Paint.Style.FILL);color=getResources().getColor(R.color.colorPrimary);customPaint.setAntiAlias(true);cornerWidth=50;cornerHeight=8;text="Scan the QR code from new phone";isFirst = true;isResult=false;isExit=false;thread = new Thread(new Runnable() {@Overridepublic void run() {while(!isExit){setDirection(direction+2);try {thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}});thread.start();}@Overridepublic void onDraw(Canvas canvas) {super.refreshSizes();if (framingRect == null || previewFramingRect == null) {return;}frame = framingRect;if(isFirst){isFirst=false;direction=frame.top+10;}customPaint.setColor(color);customPaint.setStrokeWidth((float) 1.5);/*** 绘制四条边框*/canvas.drawLine(frame.left,frame.top,frame.right,frame.top,customPaint);canvas.drawLine(frame.left,frame.top,frame.left,frame.bottom,customPaint);canvas.drawLine(frame.right,frame.top,frame.right,frame.bottom,customPaint);canvas.drawLine(frame.right,frame.bottom,frame.left,frame.bottom,customPaint);final int width = canvas.getWidth();final int height = canvas.getHeight();// Draw the exterior (i.e. outside the framing rect) darkenedpaint.setColor(resultBitmap != null ? resultColor : maskColor);canvas.drawRect(0, 0, width, frame.top, paint);canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);canvas.drawRect(0, frame.bottom + 1, width, height, paint);if (resultBitmap != null) {// Draw the opaque result bitmap over the scanning rectanglepaint.setAlpha(CURRENT_POINT_OPACITY);canvas.drawBitmap(resultBitmap, null, frame, paint);isResult=true;} else {customPaint.setAlpha(100);Rect rect = new Rect(frame.left,frame.top,frame.right, direction);canvas.drawRect(rect,customPaint);customPaint.setAlpha(255);customPaint.setStrokeWidth(3);canvas.drawLine(frame.left,direction,frame.right,direction,customPaint);if(direction>=frame.bottom){direction=frame.top;}}if(isResult){isExit=true;}else{isExit=false;}drawCorner(1,canvas);drawCorner(2,canvas);drawCorner(3,canvas);drawCorner(4,canvas);drawText(text,canvas);}public void setColor(int color){this.color=color;invalidate();}/*** 绘制四个角落 type: 1--左上 2--右上 3--左下 4--右下*/private void drawCorner(int type,Canvas canvas){Rect verticalRect=null;Rect horizontalRect =null;if(type==1){horizontalRect = new Rect(frame.left,frame.top,frame.left+cornerWidth,frame.top+cornerHeight);verticalRect = new Rect(frame.left,frame.top,frame.left+cornerHeight,frame.top+cornerWidth);}else if(type==2){horizontalRect = new Rect(frame.right-cornerWidth,frame.top,frame.right,frame.top+cornerHeight);verticalRect = new Rect(frame.right-cornerHeight,frame.top,frame.right,frame.top+cornerWidth);}else if(type==3){horizontalRect = new Rect(frame.left,frame.bottom-cornerWidth,frame.left+cornerHeight,frame.bottom);verticalRect = new Rect(frame.left,frame.bottom-cornerHeight,frame.left+cornerWidth,frame.bottom);}else{horizontalRect = new Rect(frame.right-cornerWidth,frame.bottom-cornerHeight,frame.right,frame.bottom);verticalRect = new Rect(frame.right-cornerHeight,frame.bottom-cornerWidth,frame.right,frame.bottom);}canvas.drawRect(horizontalRect,customPaint);canvas.drawRect(verticalRect,customPaint);}public void setText(String text){this.text=text;}private void drawText(String text,Canvas canvas){customPaint.setColor(getResources().getColor(R.color.colorWhite));customPaint.setTextSize(50);canvas.drawText(text,frame.left-30,frame.bottom+100,customPaint);}private void setDirection(int direction){this.direction=direction;invalidate();}public void stopThread(){isExit=true;if(thread!=null){thread=null;}}}

首先我们的framingRect 代表了窗口区域,我们绘制的时候不能绘制在窗口的区域里面,要不然会拦住窗口,因为Viewfinder是绘制在BarcodeView的上方的.修改窗口的大小,其实是有属性的,他们自定义View的style如下

<?xml version="1.0" encoding="UTF-8"?><resources><declare-styleable name="zxing_view"><attr name="zxing_scanner_layout" format="reference"/></declare-styleable><declare-styleable name="zxing_camera_preview"><attr name="zxing_framing_rect_width" format="dimension" /> //窗口大小<attr name="zxing_framing_rect_height" format="dimension" /><attr name="zxing_use_texture_view" format="boolean" /><attr name="zxing_preview_scaling_strategy" format="enum"><enum name="centerCrop" value="1" /><enum name="fitCenter" value="2" /><enum name="fitXY" value="3" /></attr></declare-styleable><declare-styleable name="zxing_finder"><attr name="zxing_possible_result_points" format="color"/><attr name="zxing_result_view" format="color"/><attr name="zxing_viewfinder_laser" format="color"/><attr name="zxing_viewfinder_mask" format="color"/> //绘制背景的颜色</declare-styleable></resources>

我们自定义的话,可以把这个style复制到自己项目里面。也可以直接用;只要在BarcodeView设置属性就好了

<.wingbackup.custom.CustomBarcodeViewandroid:id="@+id/zxing_custom_barcode_surface"android:layout_width="match_parent"android:layout_height="match_parent"app:zxing_framing_rect_height="240dp"app:zxing_framing_rect_width="240dp" /><.wingbackup.custom.CustomViewfinderViewandroid:id="@+id/zxing_custom_viewfinder_view"android:layout_width="match_parent"android:layout_height="match_parent"app:zxing_viewfinder_mask="#757575" />

这样就完成效果了。而且原生的话,关闭会有一定的延时效果,所以我们可以把这个延时关闭掉,影响用户体验

/*** 造成了延时效果* 本来为 2000000000 修改成了 10000000*/@Overridepublic void pauseAndWait() {CameraInstance instance = getCameraInstance();pause();long startTime = System.nanoTime();while(instance != null && !instance.isCameraClosed()) {if(System.nanoTime() - startTime > 10000000) {// Don't wait for longer than 2 secondsbreak;}try {Thread.sleep(1);} catch (InterruptedException e) {break;}}}

这需要在CustomBarcodeView里面修改的,因为原生的BarcodeView在退出的时候会阻塞主线程2s钟。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。