Android zxing(下)
2016-05-03 09:25
501 查看
官方zxing例子学习
如果代码涉及core-3.2.1,就不在研究,有兴趣可自行深入去学习。
扫描二维码
代码调用顺序CaptureActivity → CaptureActivityHandler → CameraManager → PreviewCallback → DecodeHandler → CaptureActivityHandler → CaptureActivity。下面一一分析。
CaptureActivity
CaptureActivity入口类,主要做了Camera,Beep,AmbientLight等初始化。CaptureActivityHandler初始化是在initCamera方法里:private void initCamera(SurfaceHolder surfaceHolder) { …… // Creating the handler starts the preview, which can also throw a RuntimeException. if (handler == null) { handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager); …… }
CaptureActivityHandler
CaptureActivityHandler构造方法做了DecodeThread初始化,DecodeThread run方法做了DecodeHandler初始化,然后Camera开始扫码工作。public CaptureActivityHandler(CaptureActivity activity, Collection<BarcodeFormat> decodeFormats, Map<DecodeHintType, ?> baseHints, String characterSet, CameraManager cameraManager) { this.activity = activity; decodeThread = new DecodeThread(activity, decodeFormats, baseHints, characterSet, new ViewfinderResultPointCallback(activity.getViewfinderView())); decodeThread.start(); state = State.SUCCESS; // Start ourselves capturing previews and decoding. this.cameraManager = cameraManager; cameraManager.startPreview(); restartPreviewAndDecode(); } private void restartPreviewAndDecode() { if (state == State.SUCCESS) { state = State.PREVIEW; //decodeThread.getHandler()拿到DecodeHandler cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode); activity.drawViewfinder(); } }
CameraManager
public synchronized void requestPreviewFrame(Handler handler, int message) { OpenCamera theCamera = camera; if (theCamera != null && previewing) { previewCallback.setHandler(handler, message); theCamera.getCamera().setOneShotPreviewCallback(previewCallback); } }
PreviewCallback
void setHandler(Handler previewHandler, int previewMessage) { this.previewHandler = previewHandler; this.previewMessage = previewMessage; } @Override public void onPreviewFrame(byte[] data, Camera camera) { Point cameraResolution = configManager.getCameraResolution(); Handler thePreviewHandler = previewHandler; if (cameraResolution != null && thePreviewHandler != null) { //给DecodeHandler发消息 Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x, cameraResolution.y, data); message.sendToTarget(); previewHandler = null; } else { Log.d(TAG, "Got preview callback, but no handler or resolution available"); } }
DecodeHandler
扫码结果,反馈给CaptureActivityHandler@Override public void handleMessage(Message message) { if (!running) { return; } int what = message.what; if (what == R.id.decode) { decode((byte[]) message.obj, message.arg1, message.arg2); } else if (what == R.id.quit) { running = false; Looper.myLooper().quit(); } } private void decode(byte[] data, int width, int height) { long start = System.currentTimeMillis(); Result rawResult = null; PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height); if (source != null) { BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); try { rawResult = multiFormatReader.decodeWithState(bitmap); } catch (ReaderException re) { // continue } finally { multiFormatReader.reset(); } } Handler handler = activity.getHandler();//拿到CaptureActivityHandler if (rawResult != null) { // Don't log the barcode contents for security. long end = System.currentTimeMillis(); Log.d(TAG, "Found barcode in " + (end - start) + " ms"); if (handler != null) { //给CaptureActivityHandler发消息 Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult); Bundle bundle = new Bundle(); bundleThumbnail(source, bundle); message.setData(bundle); message.sendToTarget(); } } else { if (handler != null) { Message message = Message.obtain(handler, R.id.decode_failed); message.sendToTarget(); } } }
CaptureActivityHandler
扫码结果,再反馈给CaptureActivity,这样就走完了扫码过程。@Override public void handleMessage(Message message) { int what = message.what; if (what == R.id.restart_preview) { restartPreviewAndDecode(); } else if (what == R.id.decode_succeeded) { state = State.SUCCESS; Bundle bundle = message.getData(); Bitmap barcode = null; float scaleFactor = 1.0f; if (bundle != null) { byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP); if (compressedBitmap != null) { barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null); // Mutable copy: barcode = barcode.copy(Bitmap.Config.ARGB_8888, true); } scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR); } activity.handleDecode((Result) message.obj, barcode, scaleFactor); } }
生成二维码
只需要以下核心代码:public static Bitmap encodeAsBitmap(String contents, int dimension) throws WriterException { String contentsToEncode = contents; if (contentsToEncode == null) { return null; } Map<EncodeHintType, Object> hints = null; String encoding = guessAppropriateEncoding(contentsToEncode); if (encoding != null) { hints = new EnumMap<>(EncodeHintType.class); hints.put(EncodeHintType.CHARACTER_SET, encoding); } BitMatrix result; try { result = new MultiFormatWriter().encode(contentsToEncode, BarcodeFormat.QR_CODE, dimension, dimension, hints); } catch (IllegalArgumentException iae) { // Unsupported format return null; } int width = result.getWidth(); int height = result.getHeight(); int[] pixels = new int[width * height]; for (int y = 0; y < height; y++) { int offset = y * width; for (int x = 0; x < width; x++) { pixels[offset + x] = result.get(x, y) ? BLACK : WHITE; } } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } private static String guessAppropriateEncoding(CharSequence contents) { // Very crude at the moment for (int i = 0; i < contents.length(); i++) { if (contents.charAt(i) > 0xFF) { return "UTF-8"; } } return null; }
源码
官方的例子和我自己的抽离出的代码都上传github了,地址:https://github.com/WuXiaolong/zxingSample
相关文章推荐
- Android Intent Action大汇总(转载)
- Android_前台service_被kill
- Android 存储记录
- Android 6.0 运行时权限处理
- android知识点大总结
- Android中常用的5大布局
- iMobile for Android技术文章-面自动裁剪
- Android Studio 使用 Lambda表达式
- Ubuntu Android 开发(二) Android SDK 安装
- Android 猜歌曲游戏开发
- Android Service 组件基础应用
- 简易版停车管理系统(Android)
- 【风马一族_Android】Android学习
- 通过UserAgent判断设备为Android、Ios、Pc访问
- Android Service 回顾
- Android ClassyShark vs ApkTool
- 自动批量安装APK
- Android 使用Fragment界面向下跳转并一级级返回
- android fragment 跳到另一个fragment
- android FRAMENT的切换(解决REPLACE的低效)