zoukankan      html  css  js  c++  java
  • Android之不须要自己定义View(ViewfindView.java)最简单的二维码扫描

    不废话,先爆照




    第一步:

    看下我项目里面的类结构


    第二步:

    给项目加入zxing.jar包


    add as library

    而且增加权限:
        <uses-permission android:name="android.permission.CALL_PHONE"/>
        <!-- 在SDCard中创建与删除文件权限 -->
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
        <!-- 往SDCard写入数据权限 -->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.INTERNET"></uses-permission>
        <!--加入扫一扫二维码的权限-->
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-permission android:name="android.permission.FLASHLIGHT" />
    
        <uses-feature android:name="android.hardware.camera" />
        <uses-feature android:name="android.hardware.camera.autofocus" />
    
        <uses-permission android:name="android.permission.VIBRATE" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />

    第三步:介绍相关类

    camera类是关于相机的相关的配置

    decode用来解码

    utils是我们的帮助类

    第四步:

    这是CaptureActivity类
    /*
     * Copyright (C) 2008 ZXing authors
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.dtr.zxing.activity;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.graphics.Rect;
    import android.os.Bundle;
    import android.os.Handler;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.Window;
    import android.view.WindowManager;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    
    import com.dtr.zxing.camera.CameraManager;
    import com.dtr.zxing.decode.DecodeThread;
    import com.dtr.zxing.utils.BeepManager;
    import com.dtr.zxing.utils.CaptureActivityHandler;
    import com.dtr.zxing.utils.InactivityTimer;
    import com.google.zxing.Result;
    import com.kuyu.kuyucontact.R;
    
    /**
     * This activity opens the camera and does the actual scanning on a background
     * thread. It draws a viewfinder to help the user place the barcode correctly,
     * shows feedback as the image processing is happening, and then overlays the
     * results when a scan is successful.
     * 
     * @author dswitkin@google.com (Daniel Switkin)
     * @author Sean Owen
     */
    public final class CaptureActivity extends Activity implements SurfaceHolder.Callback {
    
    	private static final String TAG = CaptureActivity.class.getSimpleName();
    
    	private CameraManager cameraManager;
    	private CaptureActivityHandler handler;
    	private InactivityTimer inactivityTimer;
    	private BeepManager beepManager;
    
    	private SurfaceView scanPreview = null;
    	private RelativeLayout scanContainer;
    	private RelativeLayout scanCropView;
    	private ImageView scanLine;
    
    	private Rect mCropRect = null;
    
    	public Handler getHandler() {
    		return handler;
    	}
    
    	public CameraManager getCameraManager() {
    		return cameraManager;
    	}
    
    	private boolean isHasSurface = false;
    
    	@Override
    	public void onCreate(Bundle icicle) {
    		super.onCreate(icicle);
    
    		Window window = getWindow();
    		window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    		setContentView(R.layout.activity_capture);
    
    		scanPreview = (SurfaceView) findViewById(R.id.capture_preview);
    		scanContainer = (RelativeLayout) findViewById(R.id.capture_container);
    		scanCropView = (RelativeLayout) findViewById(R.id.capture_crop_view);
    		scanLine = (ImageView) findViewById(R.id.capture_scan_line);
    
    		inactivityTimer = new InactivityTimer(this);
    		beepManager = new BeepManager(this);
    
    		TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
    				0.9f);
    		animation.setDuration(4500);
    		animation.setRepeatCount(-1);
    		animation.setRepeatMode(Animation.RESTART);
    		scanLine.startAnimation(animation);
    	}
    
    	@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());
    
    		handler = null;
    
    		if (isHasSurface) {
    			// The activity was paused but not stopped, so the surface still
    			// exists. Therefore
    			// surfaceCreated() won't be called, so init the camera here.
    			initCamera(scanPreview.getHolder());
    		} else {
    			// Install the callback and wait for surfaceCreated() to init the
    			// camera.
    			scanPreview.getHolder().addCallback(this);
    		}
    
    		inactivityTimer.onResume();
    	}
    
    	@Override
    	protected void onPause() {
    		if (handler != null) {
    			handler.quitSynchronously();
    			handler = null;
    		}
    		inactivityTimer.onPause();
    		beepManager.close();
    		cameraManager.closeDriver();
    		if (!isHasSurface) {
    			scanPreview.getHolder().removeCallback(this);
    		}
    		super.onPause();
    	}
    
    	@Override
    	protected void onDestroy() {
    		inactivityTimer.shutdown();
    		super.onDestroy();
    	}
    
    	@Override
    	public void surfaceCreated(SurfaceHolder holder) {
    		if (holder == null) {
    			Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
    		}
    		if (!isHasSurface) {
    			isHasSurface = true;
    			initCamera(holder);
    		}
    	}
    
    	@Override
    	public void surfaceDestroyed(SurfaceHolder holder) {
    		isHasSurface = 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 bundle
    	 *            The extras
    	 */
    	public void handleDecode(Result rawResult, Bundle bundle) {
    		inactivityTimer.onActivity();
    		beepManager.playBeepSoundAndVibrate();
    
    		bundle.putInt("width", mCropRect.width());
    		bundle.putInt("height", mCropRect.height());
    		bundle.putString("result", rawResult.getText());
    
    		startActivity(new Intent(CaptureActivity.this, ResultActivity.class).putExtras(bundle));
    	}
    
    	private void initCamera(SurfaceHolder surfaceHolder) {
    		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, cameraManager, DecodeThread.ALL_MODE);
    			}
    
    			initCrop();
    		} 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 initializing camera", e);
    			displayFrameworkBugMessageAndExit();
    		}
    	}
    
    	private void displayFrameworkBugMessageAndExit() {
    		// camera error
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setTitle(getString(R.string.app_name));
    		builder.setMessage("相机打开出错,请稍后重试");
    		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
    
    			@Override
    			public void onClick(DialogInterface dialog, int which) {
    				finish();
    			}
    
    		});
    		builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
    
    			@Override
    			public void onCancel(DialogInterface dialog) {
    				finish();
    			}
    		});
    		builder.show();
    	}
    
    	public void restartPreviewAfterDelay(long delayMS) {
    		if (handler != null) {
    			handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
    		}
    	}
    
    	public Rect getCropRect() {
    		return mCropRect;
    	}
    
    	/**
    	 * 初始化截取的矩形区域
    	 */
    	private void initCrop() {
    		int cameraWidth = cameraManager.getCameraResolution().y;
    		int cameraHeight = cameraManager.getCameraResolution().x;
    
    		/** 获取布局中扫描框的位置信息 */
    		int[] location = new int[2];
    		scanCropView.getLocationInWindow(location);
    
    		int cropLeft = location[0];
    		int cropTop = location[1] - getStatusBarHeight();
    
    		int cropWidth = scanCropView.getWidth();
    		int cropHeight = scanCropView.getHeight();
    
    		/** 获取布局容器的宽高 */
    		int containerWidth = scanContainer.getWidth();
    		int containerHeight = scanContainer.getHeight();
    
    		/** 计算终于截取的矩形的左上角顶点x坐标 */
    		int x = cropLeft * cameraWidth / containerWidth;
    		/** 计算终于截取的矩形的左上角顶点y坐标 */
    		int y = cropTop * cameraHeight / containerHeight;
    
    		/** 计算终于截取的矩形的宽度 */
    		int width = cropWidth * cameraWidth / containerWidth;
    		/** 计算终于截取的矩形的高度 */
    		int height = cropHeight * cameraHeight / containerHeight;
    
    		/** 生成终于的截取的矩形 */
    		mCropRect = new Rect(x, y, width + x, height + y);
    	}
    
    	private int getStatusBarHeight() {
    		try {
    			Class<?> c = Class.forName("com.android.internal.R$dimen");
    			Object obj = c.newInstance();
    			Field field = c.getField("status_bar_height");
    			int x = Integer.parseInt(field.get(obj).toString());
    			return getResources().getDimensionPixelSize(x);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return 0;
    	}
    }

    ResulutActivity.java类
    package com.dtr.zxing.activity;
    
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.util.TypedValue;
    import android.widget.ImageView;
    import android.widget.LinearLayout.LayoutParams;
    import android.widget.TextView;
    
    import com.dtr.zxing.decode.DecodeThread;
    import com.kuyu.kuyucontact.R;
    
    public class ResultActivity extends Activity {
    
    	private ImageView mResultImage;
    	private TextView mResultText;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_result);
    
    		Bundle extras = getIntent().getExtras();
    
    		mResultImage = (ImageView) findViewById(R.id.result_image);
    		mResultText = (TextView) findViewById(R.id.result_text);
    
    		if (null != extras) {
    			int width = extras.getInt("width");
    			int height = extras.getInt("height");
    
    			LayoutParams lps = new LayoutParams(width, height);
    			lps.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, getResources().getDisplayMetrics());
    			lps.leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
    			lps.rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
    			
    			mResultImage.setLayoutParams(lps);
    
    			String result = extras.getString("result");
    			mResultText.setText(result);
    
    			Bitmap barcode = null;
    			byte[] compressedBitmap = extras.getByteArray(DecodeThread.BARCODE_BITMAP);
    			if (compressedBitmap != null) {
    				barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
    				// Mutable copy:
    				barcode = barcode.copy(Bitmap.Config.RGB_565, true);
    			}
    
    			mResultImage.setImageBitmap(barcode);
    		}
    	}
    }
    

    资源文件



    好了,有些资源可能没有,Demo里面有相关的类和资源文件


  • 相关阅读:
    roportional Rate Reduction (PRR)
    【C++11新特性】 nullptr关键字
    C++ 智能指针
    std::thread
    C++11 的 std::ref 用法
    for auto
    C++11右值引用与移动构造函数
    leetcode刷题笔记一百零六题 从中序与后序遍历序列构造二叉树
    leetcode刷题笔记一百零五题 从前序与中序遍历序列构造二叉树
    leetcode刷题笔记一百零四题 二叉树的最大深度
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7067321.html
Copyright © 2011-2022 走看看