package com.zxing.scanner; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.widget.RelativeLayout; import com.google.zxing.BarcodeFormat; import com.google.zxing.Result; import com.google.zxing.ResultPoint; import com.zxing.scanner.camera.open.CameraFacing; import com.zxing.scanner.common.Scanner; /** * Created by hupei on 2016/7/1. */ public class ScannerView extends RelativeLayout { private static final String TAG = ScannerView.class.getSimpleName(); private CameraSurfaceView mSurfaceView; private ViewfinderView mViewfinderView; private BeepManager mBeepManager; private OnScannerCompletionListener mScannerCompletionListener; private ScannerOptions mScannerOptions; private ScannerOptions.Builder mScannerOptionsBuilder; public ScannerView(Context context) { this(context, null); } public ScannerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ScannerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs, defStyle); } private void init(Context context, AttributeSet attrs, int defStyle) { mSurfaceView = new CameraSurfaceView(context, this); mSurfaceView.setId(android.R.id.list); addView(mSurfaceView); mViewfinderView = new ViewfinderView(context, attrs); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(context, attrs); layoutParams.addRule(RelativeLayout.ALIGN_TOP, mSurfaceView.getId()); layoutParams.addRule(RelativeLayout.ALIGN_BOTTOM, mSurfaceView.getId()); addView(mViewfinderView, layoutParams); mScannerOptionsBuilder = new ScannerOptions.Builder(); mScannerOptions = mScannerOptionsBuilder.build(); } public void onResume() { mSurfaceView.onResume(mScannerOptions); mViewfinderView.setCameraManager(mSurfaceView.getCameraManager()); mViewfinderView.setScannerOptions(mScannerOptions); mViewfinderView.setVisibility(mScannerOptions.isViewfinderHide() ? View.GONE : View.VISIBLE); if (mBeepManager != null) mBeepManager.updatePrefs(); } public void onPause() { mSurfaceView.onPause(); if (mBeepManager != null) mBeepManager.close(); mViewfinderView.laserLineBitmapRecycle(); } /** * A valid barcode has been found, so give an indication of success and show * the results. * * @param rawResult The contents of the barcode. * @param scaleFactor amount by which thumbnail was scaled * @param barcode A greyscale bitmap of the camera data which was decoded. */ void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) { //扫描成功 if (mScannerCompletionListener != null) { //转换结果 mScannerCompletionListener.onScannerCompletion(rawResult, barcode); } if (mScannerOptions.getMediaResId() != 0) { if (mBeepManager == null) { mBeepManager = new BeepManager(getContext()); mBeepManager.setMediaResId(mScannerOptions.getMediaResId()); } mBeepManager.playBeepSoundAndVibrate(); } if (barcode != null && mScannerOptions.isShowQrThumbnail()) { mViewfinderView.drawResultBitmap(barcode); drawResultPoints(barcode, scaleFactor, rawResult); } } /** * Superimpose a line for 1D or dots for 2D to highlight the key features of * the barcode. * * @param barcode A bitmap of the captured image. * @param scaleFactor amount by which thumbnail was scaled * @param rawResult The decoded results which contains the points to draw. */ private void drawResultPoints(Bitmap barcode, float scaleFactor, Result rawResult) { ResultPoint[] points = rawResult.getResultPoints(); if (points != null && points.length > 0) { Canvas canvas = new Canvas(barcode); Paint paint = new Paint(); paint.setColor(Scanner.color.RESULT_POINTS); if (points.length == 2) { paint.setStrokeWidth(4.0f); drawLine(canvas, paint, points[0], points[1], scaleFactor); } else if (points.length == 4 && (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) { // Hacky special case -- draw two lines, for the barcode and // metadata drawLine(canvas, paint, points[0], points[1], scaleFactor); drawLine(canvas, paint, points[2], points[3], scaleFactor); } else { paint.setStrokeWidth(10.0f); for (ResultPoint point : points) { if (point != null) { canvas.drawPoint(scaleFactor * point.getX(), scaleFactor * point.getY(), paint); } } } } } private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b, float scaleFactor) { if (a != null && b != null) { canvas.drawLine(scaleFactor * a.getX(), scaleFactor * a.getY(), scaleFactor * b.getX(), scaleFactor * b.getY(), paint); } } /** * 设置扫描成功监听器 * * @param listener * @return */ public ScannerView setOnScannerCompletionListener(OnScannerCompletionListener listener) { this.mScannerCompletionListener = listener; return this; } public void setScannerOptions(ScannerOptions scannerOptions) { this.mScannerOptions = scannerOptions; } /** * 切换闪光灯 * * @param mode true开;false关 */ public ScannerView toggleLight(boolean mode) { mSurfaceView.setTorch(mode); return this; } /** * 在经过一段延迟后重置相机以进行下一次扫描。 成功扫描过后可调用此方法立刻准备进行下次扫描 * * @param delayMS 毫秒 */ public void restartPreviewAfterDelay(long delayMS) { mSurfaceView.restartPreviewAfterDelay(delayMS); } /** * 设置扫描线颜色 * * @param color */ @Deprecated public ScannerView setLaserColor(int color) { mScannerOptionsBuilder.setLaserStyle(ScannerOptions.LaserStyle.COLOR_LINE, color); return this; } /** * 设置线形扫描线资源 * * @param resId resId */ @Deprecated public ScannerView setLaserLineResId(int resId) { mScannerOptionsBuilder.setLaserStyle(ScannerOptions.LaserStyle.RES_LINE, resId); return this; } /** * 设置网格扫描线资源 * * @param resId resId */ @Deprecated public ScannerView setLaserGridLineResId(int resId) { mScannerOptionsBuilder.setLaserStyle(ScannerOptions.LaserStyle.RES_GRID, resId); return this; } /** * 设置扫描线高度 * * @param height dp */ @Deprecated public ScannerView setLaserLineHeight(int height) { mScannerOptionsBuilder.setLaserLineHeight(height); return this; } /** * 设置扫描框4角颜色 * * @param color */ @Deprecated public ScannerView setLaserFrameBoundColor(int color) { mScannerOptionsBuilder.setFrameCornerColor(color); return this; } /** * 设置扫描框4角长度 * * @param length dp */ @Deprecated public ScannerView setLaserFrameCornerLength(int length) { mScannerOptionsBuilder.setFrameCornerLength(length); return this; } /** * 设置扫描框4角宽度 * * @param width dp */ @Deprecated public ScannerView setLaserFrameCornerWidth(int width) { mScannerOptionsBuilder.setFrameCornerWidth(width); return this; } /** * 设置文字颜色 * * @param color 文字颜色 */ @Deprecated public ScannerView setDrawTextColor(int color) { mScannerOptionsBuilder.setTipTextColor(color); return this; } /** * 设置文字大小 * * @param size 文字大小 sp */ @Deprecated public ScannerView setDrawTextSize(int size) { mScannerOptionsBuilder.setTipTextSize(size); return this; } /** * 设置文字 * * @param text * @param bottom 是否在扫描框下方 */ @Deprecated public ScannerView setDrawText(String text, boolean bottom) { mScannerOptionsBuilder.setTipText(text); mScannerOptionsBuilder.setTipTextToFrameTop(!bottom); return this; } /** * 设置文字 * * @param text * @param bottom 是否在扫描框下方 * @param margin 离扫描框间距 dp */ @Deprecated public ScannerView setDrawText(String text, boolean bottom, int margin) { mScannerOptionsBuilder.setTipText(text); mScannerOptionsBuilder.setTipTextToFrameTop(!bottom); mScannerOptionsBuilder.setTipTextToFrameMargin(margin); return this; } /** * 设置文字 * * @param text * @param size 文字大小 sp * @param color 文字颜色 * @param bottom 是否在扫描框下方 * @param margin 离扫描框间距 dp */ @Deprecated public ScannerView setDrawText(String text, int size, int color, boolean bottom, int margin) { mScannerOptionsBuilder.setTipText(text); mScannerOptionsBuilder.setTipTextSize(size); mScannerOptionsBuilder.setTipTextColor(color); mScannerOptionsBuilder.setTipTextToFrameTop(!bottom); mScannerOptionsBuilder.setTipTextToFrameMargin(margin); return this; } /** * 设置扫描完成播放声音 * * @param resId */ @Deprecated public ScannerView setMediaResId(int resId) { mScannerOptionsBuilder.setMediaResId(resId); return this; } /** * 设置扫描框大小 * * @param width dp * @param height dp */ @Deprecated public ScannerView setLaserFrameSize(int width, int height) { mScannerOptionsBuilder.setFrameSize(width, height); return this; } /** * 设置扫描框与屏幕距离 * * @param margin */ @Deprecated public ScannerView setLaserFrameTopMargin(int margin) { mScannerOptionsBuilder.setFrameTopMargin(margin); return this; } /** * 设置扫描解码类型(二维码、一维码、商品条码) * * @param scanMode {@linkplain Scanner.ScanMode mode} * @return */ @Deprecated public ScannerView setScanMode(String scanMode) { mScannerOptionsBuilder.setScanMode(scanMode); return this; } /** * 设置扫描解码类型 * * @param barcodeFormat * @return */ @Deprecated public ScannerView setScanMode(BarcodeFormat... barcodeFormat) { mScannerOptionsBuilder.setScanMode(barcodeFormat); return this; } /** * 是否显示扫描结果缩略图 * * @param showResThumbnail * @return */ @Deprecated public ScannerView isShowResThumbnail(boolean showResThumbnail) { mScannerOptionsBuilder.setCreateQrThumbnail(showResThumbnail); return this; } /** * 设置扫描框线移动间距,每毫秒移动 moveSpeed 像素 * * @param moveSpeed px * @return */ @Deprecated public ScannerView setLaserMoveSpeed(int moveSpeed) { mScannerOptionsBuilder.setLaserMoveSpeed(moveSpeed); return this; } /** * 设置扫描摄像头,默认后置 * * @param cameraFacing * @return */ @Deprecated public ScannerView setCameraFacing(CameraFacing cameraFacing) { mScannerOptionsBuilder.setCameraFacing(cameraFacing); return this; } /** * 是否全屏扫描 * * @param scanFullScreen * @return */ @Deprecated public ScannerView isScanFullScreen(boolean scanFullScreen) { mScannerOptionsBuilder.setScanFullScreen(scanFullScreen); return this; } /** * 设置隐藏取景视图,包括文字 * * @param hide * @return */ @Deprecated public ScannerView isHideLaserFrame(boolean hide) { mScannerOptionsBuilder.setViewfinderHide(hide); return this; } /** * 是否扫描反色二维码(黑底白码) * * @param invertScan * @return */ @Deprecated public ScannerView isScanInvert(boolean invertScan) { mScannerOptionsBuilder.setScanInvert(invertScan); return this; } void drawViewfinder() { mViewfinderView.drawViewfinder(); } }