Android 中二维码扫码功能集成zxing注意事项 自定义扫码取景区

    xiaoxiao2021-03-25  123

    Android二维码扫码集成:https://github.com/zxing/zxing

    1.下载下来之后解压,在你的项目中file → new → import module 将该文件夹导入项目,并将app依赖于这个module(如下图),下面开始使用【开发工具:Android studio】

    2.扫码功能:你可以定义个按钮,点击按钮时调用下面的方法(checkCameraPermission())

    //检查是否开启了相机权限【Android 6.0之后必须添加】       private void checkCameraPermission() {           if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {               //如果没有授权,则请求授权               ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_CALL_CAMERA);           } else {               //有授权,直接开启摄像头扫描               callCapture("UTF-8");//打开扫码签到           }       }       private void callCapture(String characterSet) {           /**           * 获取屏幕的宽度,并将宽度的2/3作为扫码区宽度           */           int width = Tools.getScreenW(getContext()) * 2 / 3;           Intent intent = new Intent();           intent.setAction(Intents.Scan.ACTION);           // intent.putExtra(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE);           intent.putExtra(Intents.Scan.CHARACTER_SET, characterSet);           /**           * WIDTH==HEIGHT 设置方形扫码取景区           * 取景区的总宽度是屏幕宽度的2/3——适配所有机型           * */           intent.putExtra(Intents.Scan.WIDTH, width);           intent.putExtra(Intents.Scan.HEIGHT, width);//           // intent.putExtra(Intents.Scan.PROMPT_MESSAGE, "type your prompt message");           intent.setClass(getContext(), CaptureActivity.class);//进入zxing模块中的CaptureActivity           startActivityForResult(intent, REQUEST_CODE);       }          @Override       public void onActivityResult(int requestCode, int resultCode, Intent data) {           //获取扫描结果           if (null != data && requestCode == REQUEST_CODE) {               switch (resultCode) {                   case Activity.RESULT_OK:                       LogD.d("扫描返回RESULT:\n" + data.getStringExtra(Intents.Scan.RESULT));                       LogD.d("扫描返回RESULT_FORMAT:\n" + data.getStringExtra(Intents.Scan.RESULT_FORMAT));                       LogD.d("扫描返回URI:\n" + data.toUri(data.getFlags()));                       getResult(data.getStringExtra(Intents.Scan.RESULT));//获取扫码结果                       break;                   default:                       break;               }           }       } 【如果你不需要设置取景区域的话,上面的代码,已够用。】

    3.设置取景区样式【主要调整zxing模块中的CaptureActivity,CameraManager,ViewfinderView】

    第一步:调整扫码界面的样式——扫码界面的顶部添加返回按钮和标题

    布局代码如下:

    CaptureActivity布局代码

    <?xml version="1.0" encoding="utf-8"?>   <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="match_parent"       android:layout_height="match_parent">          <RelativeLayout           android:layout_width="match_parent"           android:layout_height="match_parent">           <SurfaceView               android:id="@+id/preview_view"               android:layout_width="match_parent"               android:layout_height="match_parent" />              <com.google.zxing.client.android.ViewfinderView               android:id="@+id/viewfinder_view"               android:layout_width="match_parent"               android:layout_height="match_parent" />              <include layout="@layout/layout_capture_header"               android:layout_width="match_parent"               android:layout_height="wrap_content"/>       </RelativeLayout>   </FrameLayout>  

    layout_capture_header.xml代码:

    <?xml version="1.0" encoding="utf-8"?>   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:padding="5dp"       android:background="@color/viewfinder_mask"       >       <ImageButton           android:id="@+id/button_back"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:background="@drawable/back" />          <TextView           android:id="@+id/textview_title"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_centerInParent="true"           android:gravity="center_vertical"           android:text="二维码扫描"           android:textColor="@android:color/white"           android:textSize="18sp" />      </RelativeLayout>   第二步:添加返回事件(在 CaptureActivity的onResume方法中添加以下代码段 )【完成了扫码界面的调整】

    第三步:调整扫码取景区的相对位置【上面已经传了相对宽度和高度进入CaptureActivity,取景区已经按照这个设置去设置了】【在CameraManager中调整如下——实现扫码取景区位置在偏上】

    第四步:调整取景区的四个角,扫码线,取景区下发的提示文字【用以下代码段区替换ViewfinderView】(注释已经很清楚的说明了具体用法,有兴趣的自己去研究哈)

    public final class ViewfinderView extends View {       private static final String TAG = "log";       /**       * 刷新界面的时间       */       private static final long ANIMATION_DELAY = 10L;       private static final int OPAQUE = 0xFF;          /**       * 四个绿色边角对应的长度       */       private int ScreenRate;          /**       * 四个绿色边角对应的宽度       */       private static final int CORNER_WIDTH = 5;       /**       * 扫描框中的中间线的宽度       */       private static final int MIDDLE_LINE_WIDTH = 4;          /**       * 扫描框中的中间线的与扫描框左右的间隙       */       private static final int MIDDLE_LINE_PADDING = 6;          /**       * 中间那条线每次刷新移动的距离       */       private static final int SPEEN_DISTANCE = 5;          /**       * 手机的屏幕密度       */       private static float density;       /**       * 字体大小       */       private static final int TEXT_SIZE = 16;       /**       * 字体距离扫描框下面的距离       */       private static final int TEXT_PADDING_TOP = 60;          /**       * 画笔对象的引用       */       private Paint paint;          /**       * 中间滑动线的最顶端位置       */       private int slideTop;          /**       * 中间滑动线的最底端位置       */       private int slideBottom;          private Bitmap resultBitmap;       private final int maskColor;       private final int resultColor;          private final int resultPointColor;       private Collection<ResultPoint> possibleResultPoints;       private Collection<ResultPoint> lastPossibleResultPoints;       private CameraManager cameraManager;       private boolean isFirst;          public ViewfinderView(Context context, AttributeSet attrs) {           super(context, attrs);              density = context.getResources().getDisplayMetrics().density;           //将像素转换成dp           ScreenRate = (int) (10 * density);              paint = new Paint();           Resources resources = getResources();           maskColor = resources.getColor(R.color.viewfinder_mask);           resultColor = resources.getColor(R.color.result_view);              resultPointColor = resources.getColor(R.color.possible_result_points);           possibleResultPoints = new HashSet<ResultPoint>(5);       }          public void setCameraManager(CameraManager cameraManager) {           this.cameraManager = cameraManager;       }          @Override       public void onDraw(Canvas canvas) {           if (cameraManager == nullreturn;           //中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改           Rect frame = cameraManager.getFramingRect();           if (frame == null) {               return;           }              //初始化中间线滑动的最上边和最下边           if (!isFirst) {               isFirst = true;               slideTop = frame.top;               slideBottom = frame.bottom;           }              //获取屏幕的宽和高           int width = canvas.getWidth();           int height = canvas.getHeight();              paint.setColor(resultBitmap != null ? resultColor : maskColor);              //画出扫描框外面的阴影部分,共四个部分,扫描框的上面到屏幕上面,扫描框的下面到屏幕下面           //扫描框的左边面到屏幕左边,扫描框的右边到屏幕右边           canvas.drawRect(00, 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 rectangle               paint.setAlpha(OPAQUE);               canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);           } else {                  //画扫描框边上的角,总共8个部分               paint.setColor(Color.GREEN);               canvas.drawRect(frame.left, frame.top, frame.left + ScreenRate,                       frame.top + CORNER_WIDTH, paint);               canvas.drawRect(frame.left, frame.top, frame.left + CORNER_WIDTH, frame.top                       + ScreenRate, paint);               canvas.drawRect(frame.right - ScreenRate, frame.top, frame.right,                       frame.top + CORNER_WIDTH, paint);               canvas.drawRect(frame.right - CORNER_WIDTH, frame.top, frame.right, frame.top                       + ScreenRate, paint);               canvas.drawRect(frame.left, frame.bottom - CORNER_WIDTH, frame.left                       + ScreenRate, frame.bottom, paint);               canvas.drawRect(frame.left, frame.bottom - ScreenRate,                       frame.left + CORNER_WIDTH, frame.bottom, paint);               canvas.drawRect(frame.right - ScreenRate, frame.bottom - CORNER_WIDTH,                       frame.right, frame.bottom, paint);               canvas.drawRect(frame.right - CORNER_WIDTH, frame.bottom - ScreenRate,                       frame.right, frame.bottom, paint);                     //绘制中间的线,每次刷新界面,中间的线往下移动SPEEN_DISTANCE               slideTop += SPEEN_DISTANCE;               if (slideTop >= frame.bottom) {                   slideTop = frame.top;               }   //            canvas.drawRect(frame.left + MIDDLE_LINE_PADDING, slideTop - MIDDLE_LINE_WIDTH / 2,   //                    frame.right - MIDDLE_LINE_PADDING, slideTop + MIDDLE_LINE_WIDTH / 2, paint);               Rect lineRect = new Rect();               lineRect.left = frame.left;               lineRect.right = frame.right;               lineRect.top = slideTop;               lineRect.bottom = slideTop + 18;               canvas.drawBitmap(((BitmapDrawable) (getResources().getDrawable(R.drawable.qrcode_scan_line))).getBitmap(), null, lineRect, paint);                  //画扫描框下面的字()               paint.setColor(Color.WHITE);               paint.setTextSize(TEXT_SIZE * density);               paint.setAlpha(0x40);               paint.setTypeface(Typeface.DEFAULT_BOLD);               String text = getResources().getString(R.string.scan_text);               float textWidth = paint.measureText(text);               canvas.drawText(text, (width - textWidth) / 2, (float) (frame.bottom + (float) TEXT_PADDING_TOP * density), paint);                  Collection<ResultPoint> currentPossible = possibleResultPoints;               Collection<ResultPoint> currentLast = lastPossibleResultPoints;               if (currentPossible.isEmpty()) {                   lastPossibleResultPoints = null;               } else {                   possibleResultPoints = new HashSet<ResultPoint>(5);                   lastPossibleResultPoints = currentPossible;                   paint.setAlpha(OPAQUE);                   paint.setColor(resultPointColor);                   for (ResultPoint point : currentPossible) {                       canvas.drawCircle(frame.left + point.getX(), frame.top                               + point.getY(), 6.0f, paint);                   }               }               if (currentLast != null) {                   paint.setAlpha(OPAQUE / 2);                   paint.setColor(resultPointColor);                   for (ResultPoint point : currentLast) {                       canvas.drawCircle(frame.left + point.getX(), frame.top                               + point.getY(), 3.0f, paint);                   }               }                     //只刷新扫描框的内容,其他地方不刷新               postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top,                       frame.right, frame.bottom);              }       }          public void drawViewfinder() {           resultBitmap = null;           invalidate();       }          /**       * Draw a bitmap with the result points highlighted instead of the live       * scanning display.       *       * @param barcode An image of the decoded barcode.       */       public void drawResultBitmap(Bitmap barcode) {           resultBitmap = barcode;           invalidate();       }          public void addPossibleResultPoint(ResultPoint point) {           possibleResultPoints.add(point);       }   效果图:

    转载请注明原文地址: https://ju.6miu.com/read-11097.html

    最新回复(0)