|
@@ -1,7 +1,6 @@
|
|
|
package me.yoqi.qrcode;
|
|
|
|
|
|
import android.Manifest;
|
|
|
-import android.app.Activity;
|
|
|
import android.content.Intent;
|
|
|
import android.content.pm.PackageManager;
|
|
|
import android.graphics.Bitmap;
|
|
@@ -22,6 +21,8 @@ import android.view.WindowManager;
|
|
|
import android.widget.ImageView;
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
+import androidx.appcompat.app.AppCompatActivity;
|
|
|
+
|
|
|
import com.google.zxing.BarcodeFormat;
|
|
|
import com.google.zxing.Result;
|
|
|
import com.google.zxing.ResultPoint;
|
|
@@ -40,122 +41,121 @@ import java.util.Collection;
|
|
|
* 识别二维码 CaptureActivity
|
|
|
*
|
|
|
* @author liuyuqi
|
|
|
- *
|
|
|
*/
|
|
|
-public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
|
|
|
-
|
|
|
- private static final String TAG = CaptureActivity.class.getSimpleName();
|
|
|
-
|
|
|
- private CameraManager cameraManager;
|
|
|
- private CaptureActivityHandler handler;
|
|
|
- private Result savedResultToShow;
|
|
|
- private ViewfinderView viewfinderView;
|
|
|
- private boolean hasSurface;
|
|
|
- private Collection<BarcodeFormat> decodeFormats;
|
|
|
- private InactivityTimer inactivityTimer;
|
|
|
- private String characterSet;
|
|
|
- private BeepManager beepManager;
|
|
|
-
|
|
|
- ImageView opreateView;
|
|
|
-
|
|
|
- ViewfinderView getViewfinderView() {
|
|
|
- return viewfinderView;
|
|
|
- }
|
|
|
-
|
|
|
- public Handler getHandler() {
|
|
|
- return handler;
|
|
|
- }
|
|
|
-
|
|
|
- public CameraManager getCameraManager() {
|
|
|
- return cameraManager;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onCreate(Bundle icicle) {
|
|
|
- super.onCreate(icicle);
|
|
|
-
|
|
|
- Window window = getWindow();
|
|
|
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
- setContentView(R.layout.capture);
|
|
|
-
|
|
|
- hasSurface = false;
|
|
|
- inactivityTimer = new InactivityTimer(this);
|
|
|
- beepManager = new BeepManager(this);
|
|
|
- opreateView = (ImageView) findViewById(R.id.button_openorcloseClick);
|
|
|
-
|
|
|
- opreateView.setOnClickListener(new OnClickListener() {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onClick(View v) {
|
|
|
- if (cameraManager != null) {
|
|
|
- Config.KEY_FRONT_LIGHT = !Config.KEY_FRONT_LIGHT;
|
|
|
- if (Config.KEY_FRONT_LIGHT == true) {
|
|
|
- opreateView
|
|
|
- .setImageResource(R.drawable.mzw_camera_close);
|
|
|
- } else {
|
|
|
- opreateView
|
|
|
- .setImageResource(R.drawable.mzw_camera_open);
|
|
|
- }
|
|
|
- cameraManager.getConfigManager().initializeTorch(
|
|
|
- cameraManager.getCamera().getParameters(), false);
|
|
|
- onPause();
|
|
|
- onResume();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onResume() {
|
|
|
- super.onResume();
|
|
|
-
|
|
|
- // CameraManager must be initialized here, not in onCreate(). This is
|
|
|
- // necessary because we don't
|
|
|
- // want to open the camera driver and measure the screen size if we're
|
|
|
- // going to show the help on
|
|
|
- // first launch. That led to bugs where the scanning rectangle was the
|
|
|
- // wrong size and partially
|
|
|
- // off screen.
|
|
|
- cameraManager = new CameraManager(getApplication());
|
|
|
-
|
|
|
- viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
|
|
|
- viewfinderView.setCameraManager(cameraManager);
|
|
|
-
|
|
|
- handler = null;
|
|
|
- SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
|
|
|
- SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
|
|
- if (hasSurface) {
|
|
|
- // The activity was paused but not stopped, so the surface still
|
|
|
- // exists. Therefore
|
|
|
- // surfaceCreated() won't be called, so init the camera here.
|
|
|
- initCamera(surfaceHolder);
|
|
|
- } else {
|
|
|
- // Install the callback and wait for surfaceCreated() to init the
|
|
|
- // camera.
|
|
|
- surfaceHolder.addCallback(this);
|
|
|
- surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
|
|
- }
|
|
|
-
|
|
|
- beepManager.updatePrefs();
|
|
|
-
|
|
|
- inactivityTimer.onResume();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onPause() {
|
|
|
- if (handler != null) {
|
|
|
- handler.quitSynchronously();
|
|
|
- handler = null;
|
|
|
- }
|
|
|
- inactivityTimer.onPause();
|
|
|
- cameraManager.closeDriver();
|
|
|
- if (!hasSurface) {
|
|
|
- SurfaceView surfaceView = findViewById(R.id.preview_view);
|
|
|
- SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
|
|
- surfaceHolder.removeCallback(this);
|
|
|
- }
|
|
|
- super.onPause();
|
|
|
- }
|
|
|
+public final class CaptureActivity extends AppCompatActivity implements SurfaceHolder.Callback {
|
|
|
+
|
|
|
+ private static final String TAG = CaptureActivity.class.getSimpleName();
|
|
|
+
|
|
|
+ private CameraManager cameraManager;
|
|
|
+ private CaptureActivityHandler handler;
|
|
|
+ private Result savedResultToShow;
|
|
|
+ private ViewfinderView viewfinderView;
|
|
|
+ private boolean hasSurface;
|
|
|
+ private Collection<BarcodeFormat> decodeFormats;
|
|
|
+ private InactivityTimer inactivityTimer;
|
|
|
+ private String characterSet;
|
|
|
+ private BeepManager beepManager;
|
|
|
+
|
|
|
+ ImageView opreateView;
|
|
|
+
|
|
|
+ ViewfinderView getViewfinderView() {
|
|
|
+ return viewfinderView;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Handler getHandler() {
|
|
|
+ return handler;
|
|
|
+ }
|
|
|
+
|
|
|
+ public CameraManager getCameraManager() {
|
|
|
+ return cameraManager;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCreate(Bundle icicle) {
|
|
|
+ super.onCreate(icicle);
|
|
|
+
|
|
|
+ Window window = getWindow();
|
|
|
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
|
+ setContentView(R.layout.capture);
|
|
|
+
|
|
|
+ hasSurface = false;
|
|
|
+ inactivityTimer = new InactivityTimer(this);
|
|
|
+ beepManager = new BeepManager(this);
|
|
|
+ opreateView = findViewById(R.id.button_openorcloseClick);
|
|
|
+
|
|
|
+ opreateView.setOnClickListener(new OnClickListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (cameraManager != null) {
|
|
|
+ Config.KEY_FRONT_LIGHT = !Config.KEY_FRONT_LIGHT;
|
|
|
+ if (Config.KEY_FRONT_LIGHT == true) {
|
|
|
+ opreateView
|
|
|
+ .setImageResource(R.drawable.mzw_camera_close);
|
|
|
+ } else {
|
|
|
+ opreateView
|
|
|
+ .setImageResource(R.drawable.mzw_camera_open);
|
|
|
+ }
|
|
|
+ cameraManager.getConfigManager().initializeTorch(
|
|
|
+ cameraManager.getCamera().getParameters(), false);
|
|
|
+ onPause();
|
|
|
+ onResume();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onResume() {
|
|
|
+ super.onResume();
|
|
|
+
|
|
|
+ // CameraManager must be initialized here, not in onCreate(). This is
|
|
|
+ // necessary because we don't
|
|
|
+ // want to open the camera driver and measure the screen size if we're
|
|
|
+ // going to show the help on
|
|
|
+ // first launch. That led to bugs where the scanning rectangle was the
|
|
|
+ // wrong size and partially
|
|
|
+ // off screen.
|
|
|
+ cameraManager = new CameraManager(getApplication());
|
|
|
+
|
|
|
+ viewfinderView = findViewById(R.id.viewfinder_view);
|
|
|
+ viewfinderView.setCameraManager(cameraManager);
|
|
|
+
|
|
|
+ handler = null;
|
|
|
+ SurfaceView surfaceView = findViewById(R.id.preview_view);
|
|
|
+ SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
|
|
+ if (hasSurface) {
|
|
|
+ // The activity was paused but not stopped, so the surface still
|
|
|
+ // exists. Therefore
|
|
|
+ // surfaceCreated() won't be called, so init the camera here.
|
|
|
+ initCamera(surfaceHolder);
|
|
|
+ } else {
|
|
|
+ // Install the callback and wait for surfaceCreated() to init the
|
|
|
+ // camera.
|
|
|
+ surfaceHolder.addCallback(this);
|
|
|
+ surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
|
|
+ }
|
|
|
+
|
|
|
+ beepManager.updatePrefs();
|
|
|
+
|
|
|
+ inactivityTimer.onResume();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onPause() {
|
|
|
+ if (handler != null) {
|
|
|
+ handler.quitSynchronously();
|
|
|
+ handler = null;
|
|
|
+ }
|
|
|
+ inactivityTimer.onPause();
|
|
|
+ cameraManager.closeDriver();
|
|
|
+ if (!hasSurface) {
|
|
|
+ SurfaceView surfaceView = findViewById(R.id.preview_view);
|
|
|
+ SurfaceHolder surfaceHolder = surfaceView.getHolder();
|
|
|
+ surfaceHolder.removeCallback(this);
|
|
|
+ }
|
|
|
+ super.onPause();
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
protected void onStop() {
|
|
@@ -173,186 +173,182 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- protected void onDestroy() {
|
|
|
- inactivityTimer.shutdown();
|
|
|
- super.onDestroy();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
|
- switch (keyCode) {
|
|
|
- case KeyEvent.KEYCODE_BACK:
|
|
|
- // restartPreviewAfterDelay(0L);
|
|
|
- return super.onKeyDown(keyCode, event);
|
|
|
- case KeyEvent.KEYCODE_FOCUS:
|
|
|
- case KeyEvent.KEYCODE_CAMERA:
|
|
|
- // Handle these events so they don't launch the Camera app
|
|
|
- return true;
|
|
|
- // Use volume up/down to turn on light
|
|
|
- case KeyEvent.KEYCODE_VOLUME_DOWN:
|
|
|
- cameraManager.setTorch(false);
|
|
|
- return true;
|
|
|
- case KeyEvent.KEYCODE_VOLUME_UP:
|
|
|
- cameraManager.setTorch(true);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return super.onKeyDown(keyCode, event);
|
|
|
- }
|
|
|
-
|
|
|
- private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
|
|
|
- // Bitmap isn't used yet -- will be used soon
|
|
|
- if (handler == null) {
|
|
|
- savedResultToShow = result;
|
|
|
- } else {
|
|
|
- if (result != null) {
|
|
|
- savedResultToShow = result;
|
|
|
- }
|
|
|
- if (savedResultToShow != null) {
|
|
|
- Message message = Message.obtain(handler,
|
|
|
- R.id.decode_succeeded, savedResultToShow);
|
|
|
- handler.sendMessage(message);
|
|
|
- }
|
|
|
- savedResultToShow = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceCreated(SurfaceHolder holder) {
|
|
|
- if (holder == null) {
|
|
|
- Log.e(TAG,
|
|
|
- "*** WARNING *** surfaceCreated() gave us a null surface!");
|
|
|
- }
|
|
|
- if (!hasSurface) {
|
|
|
- hasSurface = true;
|
|
|
- initCamera(holder);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
- hasSurface = false;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
|
|
- int height) {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * A valid barcode has been found, so give an indication of success and show
|
|
|
- * the results.
|
|
|
- *
|
|
|
- * @param rawResult
|
|
|
- * The contents of the barcode.
|
|
|
- * @param barcode
|
|
|
- * A greyscale bitmap of the camera data which was decoded.
|
|
|
- */
|
|
|
- public void handleDecode(Result rawResult, Bitmap barcode) {
|
|
|
- inactivityTimer.onActivity();
|
|
|
- ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(
|
|
|
- this, rawResult);
|
|
|
-
|
|
|
- boolean fromLiveScan = barcode != null;
|
|
|
- if (fromLiveScan) {
|
|
|
- // Then not from history, so beep/vibrate and we have an image to
|
|
|
- // draw on
|
|
|
- beepManager.playBeepSoundAndVibrate();
|
|
|
- // drawResultPoints(barcode, rawResult);
|
|
|
- viewfinderView.drawResultBitmap(barcode);
|
|
|
- }
|
|
|
-
|
|
|
- String text = rawResult.getText();
|
|
|
- Intent intent = new Intent(this, ResultActivity.class);
|
|
|
- intent.putExtra("text", text);
|
|
|
- startActivity(intent);
|
|
|
+ protected void onDestroy() {
|
|
|
+ inactivityTimer.shutdown();
|
|
|
+ super.onDestroy();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
|
+ switch (keyCode) {
|
|
|
+ case KeyEvent.KEYCODE_BACK:
|
|
|
+ // restartPreviewAfterDelay(0L);
|
|
|
+ return super.onKeyDown(keyCode, event);
|
|
|
+ case KeyEvent.KEYCODE_FOCUS:
|
|
|
+ case KeyEvent.KEYCODE_CAMERA:
|
|
|
+ // Handle these events so they don't launch the Camera app
|
|
|
+ return true;
|
|
|
+ // Use volume up/down to turn on light
|
|
|
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
|
|
|
+ cameraManager.setTorch(false);
|
|
|
+ return true;
|
|
|
+ case KeyEvent.KEYCODE_VOLUME_UP:
|
|
|
+ cameraManager.setTorch(true);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return super.onKeyDown(keyCode, event);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
|
|
|
+ // Bitmap isn't used yet -- will be used soon
|
|
|
+ if (handler == null) {
|
|
|
+ savedResultToShow = result;
|
|
|
+ } else {
|
|
|
+ if (result != null) {
|
|
|
+ savedResultToShow = result;
|
|
|
+ }
|
|
|
+ if (savedResultToShow != null) {
|
|
|
+ Message message = Message.obtain(handler,
|
|
|
+ R.id.decode_succeeded, savedResultToShow);
|
|
|
+ handler.sendMessage(message);
|
|
|
+ }
|
|
|
+ savedResultToShow = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void surfaceCreated(SurfaceHolder holder) {
|
|
|
+ if (holder == null) {
|
|
|
+ Log.e(TAG,
|
|
|
+ "*** WARNING *** surfaceCreated() gave us a null surface!");
|
|
|
+ }
|
|
|
+ if (!hasSurface) {
|
|
|
+ hasSurface = true;
|
|
|
+ initCamera(holder);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void surfaceDestroyed(SurfaceHolder holder) {
|
|
|
+ hasSurface = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
|
|
+ int height) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A valid barcode has been found, so give an indication of success and show
|
|
|
+ * the results.
|
|
|
+ *
|
|
|
+ * @param rawResult The contents of the barcode.
|
|
|
+ * @param barcode A greyscale bitmap of the camera data which was decoded.
|
|
|
+ */
|
|
|
+ public void handleDecode(Result rawResult, Bitmap barcode) {
|
|
|
+ inactivityTimer.onActivity();
|
|
|
+ ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(
|
|
|
+ this, rawResult);
|
|
|
+
|
|
|
+ boolean fromLiveScan = barcode != null;
|
|
|
+ if (fromLiveScan) {
|
|
|
+ // Then not from history, so beep/vibrate and we have an image to
|
|
|
+ // draw on
|
|
|
+ beepManager.playBeepSoundAndVibrate();
|
|
|
+ // drawResultPoints(barcode, rawResult);
|
|
|
+ viewfinderView.drawResultBitmap(barcode);
|
|
|
+ }
|
|
|
+
|
|
|
+ String text = rawResult.getText();
|
|
|
+ Intent intent = new Intent(this, ResultActivity.class);
|
|
|
+ intent.putExtra("text", text);
|
|
|
+ startActivity(intent);
|
|
|
cameraManager.closeDriver();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 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 rawResult
|
|
|
- * The decoded results which contains the points to draw.
|
|
|
- */
|
|
|
- private void drawResultPoints(Bitmap barcode, Result rawResult) {
|
|
|
- ResultPoint[] points = rawResult.getResultPoints();
|
|
|
- if (points != null && points.length > 0) {
|
|
|
- Canvas canvas = new Canvas(barcode);
|
|
|
- Paint paint = new Paint();
|
|
|
- paint.setColor(getResources().getColor(R.color.result_points));
|
|
|
- if (points.length == 2) {
|
|
|
- paint.setStrokeWidth(4.0f);
|
|
|
- drawLine(canvas, paint, points[0], points[1]);
|
|
|
- } 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]);
|
|
|
- drawLine(canvas, paint, points[2], points[3]);
|
|
|
- } else {
|
|
|
- paint.setStrokeWidth(10.0f);
|
|
|
- for (ResultPoint point : points) {
|
|
|
- canvas.drawPoint(point.getX(), point.getY(), paint);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static void drawLine(Canvas canvas, Paint paint, ResultPoint a,
|
|
|
- ResultPoint b) {
|
|
|
- canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
|
|
|
- }
|
|
|
-
|
|
|
- private void initCamera(SurfaceHolder surfaceHolder) {
|
|
|
- // 权限检测
|
|
|
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
- if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
|
|
- requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
|
|
|
- }
|
|
|
- }
|
|
|
- if (surfaceHolder == null) {
|
|
|
- throw new IllegalStateException("No SurfaceHolder provided");
|
|
|
- }
|
|
|
- if (cameraManager.isOpen()) {
|
|
|
- Log.w(TAG,
|
|
|
- "initCamera() while already open -- late SurfaceView callback?");
|
|
|
- return;
|
|
|
- }
|
|
|
- try {
|
|
|
- cameraManager.openDriver(surfaceHolder);
|
|
|
- // Creating the handler starts the preview, which can also throw a
|
|
|
- // RuntimeException.
|
|
|
- if (handler == null) {
|
|
|
- handler = new CaptureActivityHandler(this, viewfinderView,
|
|
|
- decodeFormats, characterSet, cameraManager);
|
|
|
- }
|
|
|
- decodeOrStoreSavedBitmap(null, null);
|
|
|
- } catch (IOException ioe) {
|
|
|
- Log.w(TAG, ioe);
|
|
|
- Toast.makeText(this, R.string.camera_problem, Toast.LENGTH_SHORT)
|
|
|
- .show();
|
|
|
- finish();
|
|
|
- } 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 initializing camera", e);
|
|
|
- Toast.makeText(this, R.string.framwork_problem, Toast.LENGTH_SHORT)
|
|
|
- .show();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void restartPreviewAfterDelay(long delayMS) {
|
|
|
- if (handler != null) {
|
|
|
- handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public void drawViewfinder() {
|
|
|
- viewfinderView.drawViewfinder();
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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 rawResult The decoded results which contains the points to draw.
|
|
|
+ */
|
|
|
+ private void drawResultPoints(Bitmap barcode, Result rawResult) {
|
|
|
+ ResultPoint[] points = rawResult.getResultPoints();
|
|
|
+ if (points != null && points.length > 0) {
|
|
|
+ Canvas canvas = new Canvas(barcode);
|
|
|
+ Paint paint = new Paint();
|
|
|
+ paint.setColor(getResources().getColor(R.color.result_points));
|
|
|
+ if (points.length == 2) {
|
|
|
+ paint.setStrokeWidth(4.0f);
|
|
|
+ drawLine(canvas, paint, points[0], points[1]);
|
|
|
+ } 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]);
|
|
|
+ drawLine(canvas, paint, points[2], points[3]);
|
|
|
+ } else {
|
|
|
+ paint.setStrokeWidth(10.0f);
|
|
|
+ for (ResultPoint point : points) {
|
|
|
+ canvas.drawPoint(point.getX(), point.getY(), paint);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void drawLine(Canvas canvas, Paint paint, ResultPoint a,
|
|
|
+ ResultPoint b) {
|
|
|
+ canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initCamera(SurfaceHolder surfaceHolder) {
|
|
|
+ // 权限检测
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
|
|
+ requestPermissions(new String[]{Manifest.permission.CAMERA}, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (surfaceHolder == null) {
|
|
|
+ throw new IllegalStateException("No SurfaceHolder provided");
|
|
|
+ }
|
|
|
+ if (cameraManager.isOpen()) {
|
|
|
+ Log.w(TAG,
|
|
|
+ "initCamera() while already open -- late SurfaceView callback?");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ cameraManager.openDriver(surfaceHolder);
|
|
|
+ // Creating the handler starts the preview, which can also throw a
|
|
|
+ // RuntimeException.
|
|
|
+ if (handler == null) {
|
|
|
+ handler = new CaptureActivityHandler(this, viewfinderView,
|
|
|
+ decodeFormats, characterSet, cameraManager);
|
|
|
+ }
|
|
|
+ decodeOrStoreSavedBitmap(null, null);
|
|
|
+ } catch (IOException ioe) {
|
|
|
+ Log.w(TAG, ioe);
|
|
|
+ Toast.makeText(this, R.string.camera_problem, Toast.LENGTH_SHORT)
|
|
|
+ .show();
|
|
|
+ finish();
|
|
|
+ } 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 initializing camera", e);
|
|
|
+ Toast.makeText(this, R.string.framwork_problem, Toast.LENGTH_SHORT)
|
|
|
+ .show();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void restartPreviewAfterDelay(long delayMS) {
|
|
|
+ if (handler != null) {
|
|
|
+ handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void drawViewfinder() {
|
|
|
+ viewfinderView.drawViewfinder();
|
|
|
+ }
|
|
|
}
|