CaptureActivity.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package me.yoqi.qrcode;
  2. import java.io.IOException;
  3. import java.util.Collection;
  4. import com.google.zxing.BarcodeFormat;
  5. import com.google.zxing.Result;
  6. import com.google.zxing.ResultPoint;
  7. import com.google.zxing.client.android.camera.CameraManager;
  8. import com.google.zxing.client.android.decode.BeepManager;
  9. import com.google.zxing.client.android.decode.CaptureActivityHandler;
  10. import com.google.zxing.client.android.decode.InactivityTimer;
  11. import com.google.zxing.client.android.decode.ViewfinderView;
  12. import com.google.zxing.client.android.result.ResultHandler;
  13. import com.google.zxing.client.android.result.ResultHandlerFactory;
  14. import android.app.Activity;
  15. import android.content.Intent;
  16. import android.graphics.Bitmap;
  17. import android.graphics.Canvas;
  18. import android.graphics.Paint;
  19. import android.os.Bundle;
  20. import android.os.Handler;
  21. import android.os.Message;
  22. import android.util.Log;
  23. import android.view.KeyEvent;
  24. import android.view.SurfaceHolder;
  25. import android.view.SurfaceView;
  26. import android.view.View;
  27. import android.view.View.OnClickListener;
  28. import android.view.Window;
  29. import android.view.WindowManager;
  30. import android.widget.ImageView;
  31. import android.widget.Toast;
  32. /**
  33. * 识别二维码 CaptureActivity
  34. *
  35. * @author liuyuqi
  36. *
  37. */
  38. public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
  39. private static final String TAG = CaptureActivity.class.getSimpleName();
  40. private CameraManager cameraManager;
  41. private CaptureActivityHandler handler;
  42. private Result savedResultToShow;
  43. private ViewfinderView viewfinderView;
  44. private boolean hasSurface;
  45. private Collection<BarcodeFormat> decodeFormats;
  46. private InactivityTimer inactivityTimer;
  47. private String characterSet;
  48. private BeepManager beepManager;
  49. final static String profix1 = "?appid=";
  50. final static String profix2 = "-title=";
  51. final static String action = "muzhiwan.action.detail";
  52. final static String bundle_key = "detail";
  53. ImageView opreateView;
  54. ViewfinderView getViewfinderView() {
  55. return viewfinderView;
  56. }
  57. public Handler getHandler() {
  58. return handler;
  59. }
  60. public CameraManager getCameraManager() {
  61. return cameraManager;
  62. }
  63. @Override
  64. public void onCreate(Bundle icicle) {
  65. super.onCreate(icicle);
  66. Window window = getWindow();
  67. window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  68. setContentView(R.layout.capture);
  69. hasSurface = false;
  70. inactivityTimer = new InactivityTimer(this);
  71. beepManager = new BeepManager(this);
  72. opreateView = (ImageView) findViewById(R.id.button_openorcloseClick);
  73. opreateView.setOnClickListener(new OnClickListener() {
  74. @Override
  75. public void onClick(View v) {
  76. if (cameraManager != null) {
  77. Config.KEY_FRONT_LIGHT = !Config.KEY_FRONT_LIGHT;
  78. if (Config.KEY_FRONT_LIGHT == true) {
  79. opreateView
  80. .setImageResource(R.drawable.mzw_camera_close);
  81. } else {
  82. opreateView
  83. .setImageResource(R.drawable.mzw_camera_open);
  84. }
  85. cameraManager.getConfigManager().initializeTorch(
  86. cameraManager.getCamera().getParameters(), false);
  87. onPause();
  88. onResume();
  89. }
  90. }
  91. });
  92. }
  93. @Override
  94. protected void onResume() {
  95. super.onResume();
  96. // CameraManager must be initialized here, not in onCreate(). This is
  97. // necessary because we don't
  98. // want to open the camera driver and measure the screen size if we're
  99. // going to show the help on
  100. // first launch. That led to bugs where the scanning rectangle was the
  101. // wrong size and partially
  102. // off screen.
  103. cameraManager = new CameraManager(getApplication());
  104. viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
  105. viewfinderView.setCameraManager(cameraManager);
  106. handler = null;
  107. SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
  108. SurfaceHolder surfaceHolder = surfaceView.getHolder();
  109. if (hasSurface) {
  110. // The activity was paused but not stopped, so the surface still
  111. // exists. Therefore
  112. // surfaceCreated() won't be called, so init the camera here.
  113. initCamera(surfaceHolder);
  114. } else {
  115. // Install the callback and wait for surfaceCreated() to init the
  116. // camera.
  117. surfaceHolder.addCallback(this);
  118. surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  119. }
  120. beepManager.updatePrefs();
  121. inactivityTimer.onResume();
  122. }
  123. @Override
  124. protected void onPause() {
  125. if (handler != null) {
  126. handler.quitSynchronously();
  127. handler = null;
  128. }
  129. inactivityTimer.onPause();
  130. cameraManager.closeDriver();
  131. if (!hasSurface) {
  132. SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
  133. SurfaceHolder surfaceHolder = surfaceView.getHolder();
  134. surfaceHolder.removeCallback(this);
  135. }
  136. super.onPause();
  137. }
  138. @Override
  139. protected void onDestroy() {
  140. inactivityTimer.shutdown();
  141. super.onDestroy();
  142. }
  143. @Override
  144. public boolean onKeyDown(int keyCode, KeyEvent event) {
  145. switch (keyCode) {
  146. case KeyEvent.KEYCODE_BACK:
  147. // restartPreviewAfterDelay(0L);
  148. return super.onKeyDown(keyCode, event);
  149. case KeyEvent.KEYCODE_FOCUS:
  150. case KeyEvent.KEYCODE_CAMERA:
  151. // Handle these events so they don't launch the Camera app
  152. return true;
  153. // Use volume up/down to turn on light
  154. case KeyEvent.KEYCODE_VOLUME_DOWN:
  155. cameraManager.setTorch(false);
  156. return true;
  157. case KeyEvent.KEYCODE_VOLUME_UP:
  158. cameraManager.setTorch(true);
  159. return true;
  160. }
  161. return super.onKeyDown(keyCode, event);
  162. }
  163. private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
  164. // Bitmap isn't used yet -- will be used soon
  165. if (handler == null) {
  166. savedResultToShow = result;
  167. } else {
  168. if (result != null) {
  169. savedResultToShow = result;
  170. }
  171. if (savedResultToShow != null) {
  172. Message message = Message.obtain(handler,
  173. R.id.decode_succeeded, savedResultToShow);
  174. handler.sendMessage(message);
  175. }
  176. savedResultToShow = null;
  177. }
  178. }
  179. @Override
  180. public void surfaceCreated(SurfaceHolder holder) {
  181. if (holder == null) {
  182. Log.e(TAG,
  183. "*** WARNING *** surfaceCreated() gave us a null surface!");
  184. }
  185. if (!hasSurface) {
  186. hasSurface = true;
  187. initCamera(holder);
  188. }
  189. }
  190. @Override
  191. public void surfaceDestroyed(SurfaceHolder holder) {
  192. hasSurface = false;
  193. }
  194. @Override
  195. public void surfaceChanged(SurfaceHolder holder, int format, int width,
  196. int height) {
  197. }
  198. /**
  199. * A valid barcode has been found, so give an indication of success and show
  200. * the results.
  201. *
  202. * @param rawResult
  203. * The contents of the barcode.
  204. * @param barcode
  205. * A greyscale bitmap of the camera data which was decoded.
  206. */
  207. public void handleDecode(Result rawResult, Bitmap barcode) {
  208. inactivityTimer.onActivity();
  209. ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(
  210. this, rawResult);
  211. boolean fromLiveScan = barcode != null;
  212. if (fromLiveScan) {
  213. // Then not from history, so beep/vibrate and we have an image to
  214. // draw on
  215. beepManager.playBeepSoundAndVibrate();
  216. // drawResultPoints(barcode, rawResult);
  217. viewfinderView.drawResultBitmap(barcode);
  218. }
  219. String text = rawResult.getText();
  220. Intent intent = new Intent(this, ResultActivity.class);
  221. intent.putExtra("text", text);
  222. startActivity(intent);
  223. // Toast.makeText(this, "扫描结果:" + text, Toast.LENGTH_LONG).show();
  224. // Log.d(TAG, "result-->" + text);
  225. }
  226. /**
  227. * Superimpose a line for 1D or dots for 2D to highlight the key features of
  228. * the barcode.
  229. *
  230. * @param barcode
  231. * A bitmap of the captured image.
  232. * @param rawResult
  233. * The decoded results which contains the points to draw.
  234. */
  235. private void drawResultPoints(Bitmap barcode, Result rawResult) {
  236. ResultPoint[] points = rawResult.getResultPoints();
  237. if (points != null && points.length > 0) {
  238. Canvas canvas = new Canvas(barcode);
  239. Paint paint = new Paint();
  240. paint.setColor(getResources().getColor(R.color.result_points));
  241. if (points.length == 2) {
  242. paint.setStrokeWidth(4.0f);
  243. drawLine(canvas, paint, points[0], points[1]);
  244. } else if (points.length == 4
  245. && (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A || rawResult
  246. .getBarcodeFormat() == BarcodeFormat.EAN_13)) {
  247. // Hacky special case -- draw two lines, for the barcode and
  248. // metadata
  249. drawLine(canvas, paint, points[0], points[1]);
  250. drawLine(canvas, paint, points[2], points[3]);
  251. } else {
  252. paint.setStrokeWidth(10.0f);
  253. for (ResultPoint point : points) {
  254. canvas.drawPoint(point.getX(), point.getY(), paint);
  255. }
  256. }
  257. }
  258. }
  259. private static void drawLine(Canvas canvas, Paint paint, ResultPoint a,
  260. ResultPoint b) {
  261. canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
  262. }
  263. private void initCamera(SurfaceHolder surfaceHolder) {
  264. if (surfaceHolder == null) {
  265. throw new IllegalStateException("No SurfaceHolder provided");
  266. }
  267. if (cameraManager.isOpen()) {
  268. Log.w(TAG,
  269. "initCamera() while already open -- late SurfaceView callback?");
  270. return;
  271. }
  272. try {
  273. cameraManager.openDriver(surfaceHolder);
  274. // Creating the handler starts the preview, which can also throw a
  275. // RuntimeException.
  276. if (handler == null) {
  277. handler = new CaptureActivityHandler(this, viewfinderView,
  278. decodeFormats, characterSet, cameraManager);
  279. }
  280. decodeOrStoreSavedBitmap(null, null);
  281. } catch (IOException ioe) {
  282. Log.w(TAG, ioe);
  283. Toast.makeText(this, R.string.camera_problem, Toast.LENGTH_SHORT)
  284. .show();
  285. finish();
  286. } catch (RuntimeException e) {
  287. // Barcode Scanner has seen crashes in the wild of this variety:
  288. // java.?lang.?RuntimeException: Fail to connect to camera service
  289. Log.w(TAG, "Unexpected error initializing camera", e);
  290. Toast.makeText(this, R.string.framwork_problem, Toast.LENGTH_SHORT)
  291. .show();
  292. }
  293. }
  294. public void restartPreviewAfterDelay(long delayMS) {
  295. if (handler != null) {
  296. handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
  297. }
  298. }
  299. public void drawViewfinder() {
  300. viewfinderView.drawViewfinder();
  301. }
  302. }