Пример #1
0
 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();
   }
 }
Пример #2
0
  /**
   * 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;
    PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, 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
 protected void onPause() {
   super.onPause();
   if (handler != null) {
     handler.quitSynchronously();
     handler = null;
   }
   CameraManager.get().closeDriver();
 }
Пример #4
0
 @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;
   }
 }
Пример #5
0
  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);
  }
Пример #6
0
  CaptureActivityHandler(
      CaptureActivity activity, Collection<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();
  }
Пример #7
0
 private void initCamera(SurfaceHolder surfaceHolder) {
   try {
     CameraManager.get().openDriver(surfaceHolder);
     // Creating the handler starts the preview, which can also throw a RuntimeException.
     if (handler == null) {
       handler = new CaptureActivityHandler(this, decodeFormats, characterSet);
     }
   } catch (IOException ioe) {
     Log.w(TAG, ioe);
     displayFrameworkBugMessageAndExit();
   } catch (RuntimeException e) {
     // Barcode Scanner has seen crashes in the wild of this variety:
     // java.?lang.?RuntimeException: Fail to connect to camera service
     Log.w(TAG, "Unexpected error initializating camera", e);
     displayFrameworkBugMessageAndExit();
   }
 }
Пример #8
0
  /**
   * 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;

    // XXX 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.zandroid_zxing_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.zandroid_zxing_decode_failed);
      message.sendToTarget();
    }
  }
  @Override
  public void onDraw(Canvas canvas) {
    Rect frame = CameraManager.get().getFramingRect();
    if (frame == null) {
      return;
    }
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // these are modifications to force the
    // view frame to be centered vertically
    frame = new Rect(frame);
    int frameHeight = frame.height();
    frame.top = (height - frame.height()) / 2;
    frame.bottom = frame.top + frameHeight;

    // 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 = 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);
        }
      }

      // 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);
    }
  }