您的位置:首页 > 移动开发 > Android开发

android基于zBar扫一扫案例

2016-07-25 20:38 531 查看
刚刚工作接到的第二个任务是做出二维码扫描基于ZBar的,代码如下 废话不多说,直接上代码,经本人翻阅大量的资料,发现好像基于ZBar的从相册中直接扫描出二维码的案例,貌似不可能实现!!!如果有人实现这个功能希望共享一下,感激不尽!

布局文件 其中的一些图片没有共享,由于时间很紧,希望谅解!

做这个功能时 记住先下载zbar的包和其中的几个文件,这个可自行百度!这里只给出思路!

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@drawable/qrcode_frame_icon" >

<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<com.example.test5.QRCodeFinderView
android:id="@+id/findView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>

<!-- 返回按钮 -->

<!-- 说明部分 -->

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="285dp"
android:gravity="center_horizontal" >

<TextView
android:id="@+id/explain"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:text="@string/qrcode_notice"
android:textColor="@android:color/white"
android:textSize="@dimen/fontSize" />

<!-- 闪光灯 -->

<RelativeLayout
android:id="@+id/qrcodeLight"
android:layout_width="200dp"
android:layout_height="36dp"
android:layout_below="@+id/explain"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@drawable/layer_list_ex"
android:gravity="center" >

<TextView
android:id="@+id/light_BtnText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/qrcode_light"
android:textColor="@android:color/white"
android:textSize="@dimen/fontSize" />
</RelativeLayout>

<!-- 添加设备 -->

<RelativeLayout
android:id="@+id/qrcode_adddevice"
android:layout_width="200dp"
android:layout_height="36dp"
android:layout_below="@+id/qrcodeLight"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@drawable/layer_list_ex"
android:gravity="center" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/add_device"
android:textColor="@android:color/white"
android:textSize="@dimen/fontSize" />
</RelativeLayout>
</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/navigation_bar_bg">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:text="@string/activity_qrcode_title"
android:textColor="@color/white"
android:textSize="@dimen/title_text_size" />
<ImageButton
android:id="@+id/qrcode_back"
android:layout_width="@dimen/back_imgbtn_width"
android:layout_height="@dimen/back_imgbtn_height"
android:layout_marginLeft="12dp"
android:layout_centerVertical="true"
android:background="@drawable/qrcode_back_icon" />
<Button
android:id="@+id/btnImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:text="@string/click"
/>
</RelativeLayout>

</FrameLayout>


扫描成功后的显示结果界面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="@+id/title_bar"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@color/navigation_bar_bg" >

<ImageButton
android:id="@+id/qrcode_sucess_back"
android:layout_width="@dimen/back_imgbtn_width"
android:layout_height="@dimen/back_imgbtn_height"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:background="@drawable/back_button_selector" />

<TextView
android:id="@+id/titleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:text="@string/result"
android:textColor="@color/white"
android:textSize="@dimen/title_text_size" />
</RelativeLayout>
<TextView
android:id="@+id/tvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"

/>

</RelativeLayout>


这个类用于实现扫描

package com.example.test5;

import java.util.List;

import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MfrmQRCode extends Activity implements SurfaceHolder.Callback {

private static final int DOAUTOFOCUSDELAY = 1000;
// surfaceView
private SurfaceHolder mHolder;
private SurfaceView surfaceView;
// 用于自动聚焦
private Handler autoFocusHandler;
private AsyncDecode asyncDecode;
// 图片扫描器
ImageScanner scanner;
// 相机
private Camera mCamera;
public static final String TAG = "MfrmQRCode";

private String QRcode;
// 扫描surfaceView
private QRCodeFinderView findView;
Button btnImage;

Image barcode;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcode);
initVaraible();
addListener();
}

private void addListener() {
btnImage.setOnClickListener(new ClickImage());
}

private void initVaraible() {
findView = (QRCodeFinderView) findViewById(R.id.findView);
// 强制竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// 获取照相机
// mCamera = getCameraInstance();
autoFocusHandler = new Handler();
// 图形初始化
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
mHolder = surfaceView.getHolder();
mHolder.addCallback(this);
// android 3.0以下版本需要增加此方法
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
asyncDecode = new AsyncDecode();
btnImage = (Button) findViewById(R.id.btnImage);
}

// callBack中的方法
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int hight) {
if (mHolder.getSurface() == null || mCamera == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {

}
try {

mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);

} catch (Exception e) {
Log.d(TAG, "Error starting canera preview:" + e.getMessage());
}
}

// Image类用于获取二维码图片,ImageScanner类用于对图片的初步解析,而图片的最终解析是在SymbolSet类和
// Symbol中去实现的
PreviewCallback previewCallback = new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] date, Camera camera) {
if (asyncDecode.stoped) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
Image barcodeImage = new Image(size.width, size.height, "Y800");
Rect scanImageRect = findView.getScanImageRect(size.height,
size.width);
barcodeImage.setCrop(scanImageRect.top, scanImageRect.left,
scanImageRect.bottom, scanImageRect.right);
barcodeImage.setData(date);
asyncDecode = new AsyncDecode();
asyncDecode.execute(barcodeImage);

}
}
};

private class AsyncDecode extends AsyncTask<Image, Void, Void> {
// -------------------------------------

private boolean stoped = true;

@Override
protected Void doInBackground(Image... params) {
stoped = false;
barcode = params[0];
int result = scanner.scanImage(barcode);

if (result != 0) {
SymbolSet syms = scanner.getResults();
// 扫描成功跳转到设备详情页面
for (Symbol sym : syms) {
QRcode = sym.getData();
if (QRcode != null) {
Intent intent = new Intent(MfrmQRCode.this,
Result.class);
intent.putExtra("Code", sym.getData());
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "错误",
Toast.LENGTH_SHORT).show();
}
return null;
}
}
return null;
}

@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
stoped = true;
}

}

// 自动对焦回调
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, DOAUTOFOCUSDELAY);
}
};
// 自动对焦
private Runnable doAutoFocus = new Runnable() {
@Override
public void run() {
if (mCamera == null || autoFocusCallback == null) {
return;
}
mCamera.autoFocus(autoFocusCallback);
}
};

@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open(0);
if (mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
if (parameters.getPreviewSize().width > 1920) {
List<Size> supportedPreviewSizes = parameters
.getSupportedPreviewSizes();
for (int i = 0; i < supportedPreviewSizes.size(); i++) {
if (supportedPreviewSizes.get(i).width == 1920
&& supportedPreviewSizes.get(i).height == 1080) {
parameters.setPreviewSize(1920, 1080);
mCamera.setParameters(parameters);
break;
} else if (supportedPreviewSizes.get(i).width == 1280
&& supportedPreviewSizes.get(i).height == 720) {
parameters.setPreviewSize(1280, 720);
mCamera.setParameters(parameters);
break;
} else if (supportedPreviewSizes.get(i).width == 640
&& supportedPreviewSizes.get(i).height == 480) {
parameters.setPreviewSize(640, 480);
mCamera.setParameters(parameters);
break;
}
}
}
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
}
} catch (Exception e) {
Log.d(TAG, "JSONException :" + e);
mCamera = null;
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}

class ClickImage implements OnClickListener {

@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 0);
}

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
// 得到图片的全路径
Uri uri = data.getData();

// 通过路径加载图片
// 这里省去了图片缩放操作,如果图片过大,可能会导致内存泄漏
// 图片缩放的实现,请看:http://blog.csdn.net/reality_jie_blog/article/details/16891095
/*
* Log.e("TAG--------------", uri+""); ContentResolver cr =
* this.getContentResolver(); bmp =
MediaStore.Images.Media.getBitmap(cr, uri);
*/
// 获取图片的缩略图,可能为空!
// Bitmap bitmap = data.getParcelableExtra("data");
// this.iv_image.setImageBitmap(bitmap);

}
super.onActivityResult(requestCode, resultCode, data);
}
}


这个类是扫描时最上面的框以及不断滑动的横线

package com.example.test5;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class QRCodeFinderView extends View{
private static final long ANIMATION_DELAY = 30;
private static final int  LINE_HEIGHT = 30;
private Paint finderMaslPaint;
private int measureedWidth;
private int measureedHeight;

private Rect topRect = new Rect();
private Rect bottomRect = new Rect();
private Rect rightRect = new Rect();
private Rect leftRect = new Rect();
private Rect middleRect = new Rect();
private Rect lineRect = new Rect();
private Drawable zx_code_kuang;
private Drawable zx_code_line;
private int lineHeight;

public QRCodeFinderView(Context context,AttributeSet  attrs){
super(context, attrs);
init(context);
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//确定矩形框的大小
canvas.drawRect(leftRect,finderMaslPaint);
canvas.drawRect(topRect,finderMaslPaint);
canvas.drawRect(rightRect,finderMaslPaint);
canvas.drawRect(bottomRect,finderMaslPaint);
//画框
zx_code_kuang.setBounds(middleRect);
zx_code_kuang.draw(canvas);
//线的循环位置
if(lineRect.bottom <  middleRect.bottom){
zx_code_line.setBounds(lineRect);
lineRect.top = lineRect.top + lineHeight / 5;
lineRect.bottom = lineRect.bottom +lineHeight /5;
}else{
lineRect.set(middleRect);
lineRect.bottom = lineRect.top +lineHeight;
zx_code_line.setBounds(lineRect);
}
zx_code_line.draw(canvas);
postInvalidateDelayed(ANIMATION_DELAY, middleRect.left, middleRect.top, middleRect.right, middleRect.bottom);
}
private void init(Context context) {
// 设置底层半透明
int finder_mask = context.getResources().getColor(R.color.qecode_transparent_bg);
finderMaslPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
finderMaslPaint.setColor(finder_mask);
//引入项目所需的图
zx_code_kuang = context.getResources().getDrawable(R.drawable.qrcode_frame_icon);
zx_code_line = context.getResources().getDrawable(R.drawable.qrcode_line_icon);
//线的高度
lineHeight = LINE_HEIGHT;
}

public Rect getScanImageRect(int w, int h) {
//先求出实际矩形
Rect rect = new Rect();
float temp_w = w / (float) measureedWidth;
rect.left = (int)(middleRect.left * temp_w);
rect.right = (int)(middleRect.right * temp_w);
float temp_h = h / (float) measureedHeight;
rect.top = (int) (middleRect.top * temp_h);
rect.bottom = (int) (middleRect.bottom * temp_h);
return rect;
}

//自定义View重载函数
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//屏幕初始值
measureedWidth = MeasureSpec.getSize(widthMeasureSpec);
measureedHeight = MeasureSpec.getSize(heightMeasureSpec);
int borderWidth = measureedWidth / 2 +100;
//矩形框的位置[对应位置设置,依次为左上右下,数值越大矩形扫描位置更改越大。]
middleRect.set((measureedWidth - borderWidth) /2,(measureedHeight - borderWidth) / 4,(measureedWidth - borderWidth) / 2 + borderWidth,(measureedHeight - borderWidth) / 4 + borderWidth);
lineRect.set(middleRect);
//确定矩形框大小,分别减去左上右下的多余部分,确定大小
leftRect.set(0, middleRect.top, middleRect.left,middleRect.bottom);
topRect.set(0,0, measureedWidth,middleRect.top);
rightRect.set(middleRect.right, middleRect.top, measureedWidth, middleRect.bottom);
bottomRect.set(0,  middleRect.bottom, measureedWidth,measureedHeight);

}

}


这个类用于显示结果

package com.example.test5;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.style.BackgroundColorSpan;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;

public class Result extends Activity {
private TextView tView;
private ImageButton imageButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
init();
addListener();
}

private void init() {
tView = (TextView) findViewById(R.id.tvResult);
imageButton = (ImageButton) findViewById(R.id.qrcode_sucess_back);

/* 取出Intent中附加的数据 */
Bundle sBundle = getIntent().getExtras();
CharSequence mResult = sBundle.getCharSequence("Code");
tView.setText(mResult);
}

private void addListener() {
imageButton.setOnClickListener(new Back());
}

class Back implements OnClickListener {

@Override
public void onClick(View v) {
Intent intent = new Intent(Result.this, MfrmQRCode.class);
startActivity(intent);
}

}

}


由于时间现在很紧,所以写的比较仓促,认真读一下代码,应该可以实现出功能!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: