private void restartPreviewAndDecode() {
   if (state == State.SUCCESS) {
     state = State.PREVIEW;
     CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
     CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
     activity.drawViewfinder();
   }
 }
  @Override
  public void handleMessage(Message message) {
    switch (message.what) {
      case R.id.auto_focus:
        // Log.d(TAG, "Got auto-focus message");
        // When one auto focus pass finishes, start another. This is the
        // closest thing to
        // continuous AF. It does seem to hunt a bit, but I'm not sure what
        // else to do.
        if (state == State.PREVIEW) {
          CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
        }
        break;
      case R.id.restart_preview:
        Log.d(TAG, "Got restart preview message");
        restartPreviewAndDecode();
        break;
      case R.id.decode_succeeded:
        Log.d(TAG, "Got decode succeeded message");
        state = State.SUCCESS;
        Bundle bundle = message.getData();

        /** ******************************************************************** */
        Bitmap barcode =
            bundle == null
                ? null
                : (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP); // ���ñ����߳�

        activity.handleDecode((Result) message.obj, barcode); // ���ؽ��
        /** ******************************************************************** */
        break;
      case R.id.decode_failed:
        // We're decoding as fast as possible, so when one decode fails,
        // start another.
        state = State.PREVIEW;
        CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
        break;
      case R.id.return_scan_result:
        Log.d(TAG, "Got return scan result message");
        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
        activity.finish();
        break;
      case R.id.launch_product_query:
        Log.d(TAG, "Got product query message");
        String url = (String) message.obj;
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        activity.startActivity(intent);
        break;
    }
  }
 @Override
 protected void onPause() {
   super.onPause();
   if (handler != null) {
     handler.quitSynchronously();
     handler = null;
   }
   CameraManager.get().closeDriver();
 }
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.zxing_camera);
   // ViewUtil.addTopView(getApplicationContext(), this, R.string.scan_card);
   CameraManager.init(getApplication());
   viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
   cancelScanButton = (Button) this.findViewById(R.id.btn_cancel_scan);
   hasSurface = false;
   inactivityTimer = new InactivityTimer(this);
 }
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.scan_main);
   // 初始化 CameraManager
   CameraManager.init(getApplication());
   viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
   txtResult = (TextView) findViewById(R.id.txtResult);
   hasSurface = false;
   inactivityTimer = new InactivityTimer(this);
 }
 private void initCamera(SurfaceHolder surfaceHolder) {
   try {
     CameraManager.get().openDriver(surfaceHolder);
   } catch (IOException ioe) {
     return;
   } catch (RuntimeException e) {
     return;
   }
   if (handler == null) {
     handler = new CaptureActivityHandler(this, decodeFormats, characterSet);
   }
 }
 public CaptureActivityHandler(
     CaptureActivity activity, Vector<BarcodeFormat> decodeFormats, String characterSet) {
   this.activity = activity;
   decodeThread =
       new DecodeThread(
           activity,
           decodeFormats,
           characterSet,
           new ViewfinderResultPointCallback(activity.getViewfinderView()));
   decodeThread.start();
   state = State.SUCCESS;
   // Start ourselves capturing previews and decoding.
   CameraManager.get().startPreview();
   restartPreviewAndDecode();
 }
  public void quitSynchronously() {
    state = State.DONE;
    CameraManager.get().stopPreview();
    Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
    quit.sendToTarget();
    try {
      decodeThread.join();
    } catch (InterruptedException e) {
      // continue
    }

    // Be absolutely sure we don't send any queued up messages
    removeMessages(R.id.decode_succeeded);
    removeMessages(R.id.decode_failed);
  }
  /**
   * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
   * reuse the same reader objects from one decode to the next.
   *
   * @param data The YUV preview frame.
   * @param width The width of the preview frame.
   * @param height The height of the preview frame.
   */
  private void decode(byte[] data, int width, int height) {
    long start = System.currentTimeMillis();
    Result rawResult = null;

    // modify here
    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; // Here we are swapping, that's the difference to #11
    width = height;
    height = tmp;

    PlanarYUVLuminanceSource source =
        CameraManager.get().buildLuminanceSource(rotatedData, width, height);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    try {
      rawResult = multiFormatReader.decodeWithState(bitmap);
    } catch (ReaderException re) {
      // continue
    } finally {
      multiFormatReader.reset();
    }

    if (rawResult != null) {
      long end = System.currentTimeMillis();
      Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
      Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
      Bundle bundle = new Bundle();
      bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
      message.setData(bundle);
      // Log.d(TAG, "Sending decode succeeded message...");
      message.sendToTarget();
    } else {
      Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
      message.sendToTarget();
    }
  }
  @Override
  public void onDraw(Canvas canvas) {
    // 中间的扫描框,你要修改扫描框的大小,去CameraManager里面修改
    Rect frame = CameraManager.get().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(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 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;
      }
      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.create("System", Typeface.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);
    }
  }
Exemple #11
0
  @Override
  public void onDraw(Canvas canvas) {
    Rect frame = CameraManager.get().getFramingRect();
    if (frame == null) {
      return;
    }
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // Draw the exterior (i.e. outside the framing rect) darkened
    paint.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 rectangle
      paint.setAlpha(OPAQUE);
      canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
    } else {

      // Draw a two pixel solid black border inside the framing rect
      paint.setColor(frameColor);
      canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint);
      canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint);
      canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint);
      canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);

      // Draw a red "laser scanner" line through the middle to show
      // decoding is active
      paint.setColor(laserColor);
      paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
      scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
      int middle = frame.height() / 2 + frame.top;
      canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);

      Collection<ResultPoint> currentPossible = possibleResultPoints;
      Collection<ResultPoint> currentLast = lastPossibleResultPoints;
      if (currentPossible.isEmpty()) {
        lastPossibleResultPoints = null;
      } else {
        possibleResultPoints.clear();
        ;
        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);
        }
      }

      // Request another update at the animation interval, but only
      // repaint the laser line,
      // not the entire viewfinder mask.
      postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
    }
  }