QR Code reader

1. lib :

http://sourceforge.jp/projects/qrcode/

2. code:

MainActivity.java

package com.sec.qrcode.decoder.qrcode;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.data.QRCodeImage;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.URLUtil;

public class MainActivity extends Activity implements SurfaceHolder.Callback, PreviewCallback, AutoFocusCallback{
	
	private final static String TAG = "QRreader";
	
	private int mFrameCount = 0;
	
	private Camera mCamera;
	private SurfaceView mSurfaceView;
	private SurfaceHolder mSurfaceHolder;
	
	private boolean bAFsuccess = false;
	private boolean bDecodeSuccess = false;
	
	private static int LCD_WIDTH = 0;
	private static int LCD_HEIGHT = 0;
	private static int mRectX = 10;
	private static int mRectY = 10;
	private static final int RECT_LENGTH = 450;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.activity_main);
		Log.e(TAG, "onCreate");
		
		mSurfaceView = (SurfaceView)findViewById(R.id.sv_preview);
		mSurfaceHolder = mSurfaceView.getHolder();
		mSurfaceHolder.addCallback(this);		

		getRectSize();
		DrawCaptureRect mRect = new DrawCaptureRect(this, mRectX, mRectY, RECT_LENGTH, RECT_LENGTH, Color.GREEN);
		addContentView(mRect, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
	}
	
	@SuppressLint("NewApi")
	private void getRectSize(){

		Point size = new Point();
		getWindowManager().getDefaultDisplay().getSize(size);
		LCD_WIDTH = size.x;
		LCD_HEIGHT = size.y;
		mRectX = (int)((((float)LCD_WIDTH-(float)RECT_LENGTH))/2);
		mRectY = (int)((((float)LCD_HEIGHT-(float)RECT_LENGTH))/2);
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		Log.e(TAG, "surfaceChanged");
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		Log.e(TAG, "surfaceCreated");
		
		if(null == mCamera){
			
			openCamera();

			setParams();
			
			startPreview();
		}
		
	}

	@Override
	protected void onDestroy() {
		Log.e(TAG, "onDestroy");

		super.onDestroy();
	}

	@Override
	protected void onPause() {
		Log.e(TAG, "onPause");
		
		if(null != mCamera) {
			mCamera.setPreviewCallback(null);
			mCamera.stopPreview();
			mCamera.release();
			mCamera = null;
		}

		mFrameCount = 0;
		bAFsuccess = false;
		bDecodeSuccess = false;

		super.onPause();
	}

	@Override
	protected void onResume() {
		Log.e(TAG, "onResume");
		
		mFrameCount = 0;
		bAFsuccess = false;
		bDecodeSuccess = false;

		if(mSurfaceHolder.getSurface().isValid() && null == mCamera){
			
			openCamera();
			
			setParams();
			
			startPreview();
		}
		
		super.onResume();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		Log.e(TAG, "surfaceDestroyed");
	}
	
	protected void openCamera(){
		Log.e(TAG, "openCamera");
		mCamera = Camera.open();
	}
	
	protected void setParams(){
		Log.e(TAG, "setParams");
		
		if(null == mCamera){
			Log.e(TAG, "mCamera is null, return");
			return;
		}
		
		Parameters mParameters = mCamera.getParameters();
		
		mParameters.setAntibanding(Parameters.ANTIBANDING_50HZ);
		
		mCamera.setParameters(mParameters);
		
		mCamera.setDisplayOrientation(90);
	}
	
	protected void startPreview(){
		Log.e(TAG, "startPreview");
		
		if(null == mCamera){
			Log.e(TAG, "mCamera is null, return");
			return;
		}
		
		try {
			mCamera.setPreviewDisplay(mSurfaceHolder);
		} catch (IOException e) {
			e.printStackTrace();
		}
		mCamera.setPreviewCallback(this);
		mCamera.startPreview();
	}

	@Override
	public void onPreviewFrame(byte[] data, Camera camera) {
		
		mFrameCount++;
		if(2 == mFrameCount && !bDecodeSuccess){
			Log.e(TAG, "onPreviewFrame, mFrameCount="+mFrameCount);
			
			mCamera.autoFocus(this);
		}
		
		if(true == bAFsuccess && null != data){
			
			bAFsuccess = false;
			
			Camera.Parameters mParameters = camera.getParameters();
			int previewWidth = mParameters.getPreviewSize().width;
			int previewHeight = mParameters.getPreviewSize().height;
			YuvImage yuv = new YuvImage(data, mParameters.getPreviewFormat(), previewWidth, previewHeight, null);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			yuv.compressToJpeg(new Rect(0,0,previewWidth,previewHeight), 80, out);
			byte[] bytes = out.toByteArray();
			
			Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
			
			Matrix rotateMatix = new Matrix();
			rotateMatix.reset();
			rotateMatix.setRotate(90);
			Bitmap rotateBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), rotateMatix, true);
			
			Log.e(TAG, "onPreviewFrame, length="+bytes.length+",bm.width="+rotateBitmap.getWidth()+",bm.height="+rotateBitmap.getHeight());
			
			String strResult = decodeQRImage(rotateBitmap);
			Log.e(TAG, "strResult="+strResult);
			
			if(null == strResult){
				mFrameCount=0;
			} else if(URLUtil.isNetworkUrl(strResult)){
				
				Uri mUri = Uri.parse(strResult);
				Intent intent = new Intent(Intent.ACTION_VIEW, mUri);
				startActivity(intent);
				finish();
				
			}else if (findString("wtai://", strResult)){
				
				String[] strArray = strResult.split("wtai://");
				Intent intent = new Intent("android.intent.action.CALL", Uri.parse("tel:"+strArray[1]));
				startActivity(intent);
				finish();
				
			}else if (findString("TEL:", strResult)){
				
				String[] strArray = strResult.split("TEL:");
				Intent intent = new Intent("android.intent.action.CALL", Uri.parse("tel:"+strArray[1]));
				startActivity(intent);
				finish();
				
			}else {
				Bundle mBundle = new Bundle();
				mBundle.putString("QR_DecodeResult", strResult);
				Intent intent = new Intent(MainActivity.this, DisplayResult.class);
				intent.putExtras(mBundle);
				startActivity(intent);
			}
		}
	}

	private boolean findString(String string, String strResult) {
		
		Log.e(TAG, "findString, string="+string+", strResult="+strResult);
		
		String strPattern = "(?i)"+string;
		Pattern p = Pattern.compile(strPattern);
		Matcher m = p.matcher(strResult);
		
		return m.find();
	}

	@Override
	public void onAutoFocus(boolean success, Camera camera) {
		Log.e(TAG, "onAutoFocus,success="+success);
		bAFsuccess = success;

		if(false == bAFsuccess){
			mCamera.autoFocus(this);
		}
	}

	private String decodeQRImage(Bitmap bm) {
		Log.e(TAG, "decodeFrame");
		
		String strResult = null;
		try {
			QRCodeDecoder decoder = new QRCodeDecoder();
			strResult = new String(decoder.decode(new AndroidQRCodeImage(bm)));
		}catch (Exception e) {
			e.printStackTrace();
		}

		return strResult;
	}
	
	class AndroidQRCodeImage implements QRCodeImage {

		Bitmap image;
		
		public AndroidQRCodeImage(Bitmap image){
			this.image = image;
		}
		
		@Override
		public int getHeight() {
			return image.getHeight();
		}

		@Override
		public int getPixel(int x, int y) {
			return image.getPixel(x, y);
		}

		@Override
		public int getWidth() {
			return image.getWidth();
		}
		
	}
}


Rect :

package com.sec.qrcode.decoder.qrcode;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class DrawCaptureRect extends View {
	
	private int color;
	private int x, y, width, height;
	//private static int scanY;

	public DrawCaptureRect(Context context, int x, int y, int width, int height, int color) {
		super(context);
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.color = color;
		//scanY = 0;
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		
		Paint mPaint = new Paint();
		mPaint.setStyle(Paint.Style.FILL);
		mPaint.setColor(color);
		mPaint.setStrokeWidth(2.0F);
		
		canvas.drawLine(x, y, x+width, y, mPaint);
		canvas.drawLine(x, y, x, y+height, mPaint);
		canvas.drawLine(x+width, y, x+width, y+height, mPaint);
		canvas.drawLine(x, y+height, x+width, y+height, mPaint);
		
		/*Paint mPaintScan = new Paint();
		mPaintScan.setStyle(Paint.Style.FILL);
		mPaintScan.setColor(Color.RED);
		mPaintScan.setStrokeWidth(1.0F);
		scanY =(scanY+2)%height;
		canvas.drawLine(x, y+scanY, x+width, y+scanY, mPaint);*/
		
		super.onDraw(canvas);
	}

}


ShowResult:

package com.sec.qrcode.decoder.qrcode;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class DisplayResult extends Activity {
	
	private static final String TAG = "DisplayResult";
	
	private TextView mTvShowResult;

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_result);
		Log.e(TAG, "onCreate");
		
		mTvShowResult = (TextView)findViewById(R.id.tv_showresult);
		String strResult = getIntent().getExtras().getString("QR_DecodeResult", null);
		
		if(null == strResult){
			mTvShowResult.setText("Empty result");
		}else{
			mTvShowResult.setText(strResult);
		}
	}

	@Override
	protected void onDestroy() {
		Log.e(TAG, "onDestroy");
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		Log.e(TAG, "onPause");
		super.onPause();
	}

	@Override
	protected void onResume() {
		Log.e(TAG, "onResume");
		super.onResume();
	}

}


Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sec.qrcode.decoder.qrcode"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="14" />
    
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name = "android.hardware.camera" />
    <uses-feature android:name = "android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".DisplayResult"
            android:screenOrientation="portrait">
        </activity>
    </application>

</manifest>


Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <SurfaceView
    	android:id="@+id/sv_preview"
    	android:visibility="visible"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true" />

</RelativeLayout>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值