123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- package me.yoqi.qrcode;
- import android.Manifest;
- import android.app.Activity;
- import android.content.Intent;
- import android.content.pm.PackageManager;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.os.Build;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.view.WindowManager;
- import android.widget.ImageView;
- import android.widget.Toast;
- import com.google.zxing.BarcodeFormat;
- import com.google.zxing.Result;
- import com.google.zxing.ResultPoint;
- import com.google.zxing.client.android.camera.CameraManager;
- import com.google.zxing.client.android.decode.BeepManager;
- import com.google.zxing.client.android.decode.CaptureActivityHandler;
- import com.google.zxing.client.android.decode.InactivityTimer;
- import com.google.zxing.client.android.decode.ViewfinderView;
- import com.google.zxing.client.android.result.ResultHandler;
- import com.google.zxing.client.android.result.ResultHandlerFactory;
- import java.io.IOException;
- 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();
- }
- @Override
- protected void onStop() {
- if (handler != null) {
- handler.quitSynchronously();
- handler = null;
- }
- cameraManager.closeDriver();
- if (!hasSurface) {
- SurfaceView surfaceView = findViewById(R.id.preview_view);
- SurfaceHolder surfaceHolder = surfaceView.getHolder();
- surfaceHolder.removeCallback(this);
- }
- super.onStop();
- }
- @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);
- 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();
- }
- }
|