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>