基于Zxing的二维码生成和二维码扫描

来源:互联网 发布:phpstudy怎样配置域名 编辑:程序博客网 时间:2024/04/28 05:43

最近又在倒腾二维码,发现网上的教程都不够用,所以把之前整合的二维码Demo有拿出来重新添加些功能,这里也算是重新学习吧!

     当然对于二维码,相信大家都很熟悉了。这里就不多说。本项目是基于Zxing的开源项目开发的。

     这里用的Demo是之前网上搜的教程。时间久了,也就忘了,大家网上应该可以搜到,当然如果不想那么麻烦,可以下载我的这个Demo,用的时候直接用就行了。这里我新添加了一些功能。

     好吧不说废话了,进入主题:

     首先写好布局文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@android:color/white"    android:orientation="vertical" >    <Button        android:id="@+id/bt_bigin_scan"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="30dp"        android:text="开始扫描" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="二维码信息:"        android:textColor="@android:color/black"        android:textSize="18sp" />    <EditText        android:id="@+id/scan_result"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textColor="@android:color/black"        android:textSize="18sp" />    <Button        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="30dp"        android:onClick="checkResult"        android:text="进入网页" />    <Button        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="30dp"        android:onClick="Create2QR"        android:text="生成二维码" />    <ImageView        android:id="@+id/iv_qr_image"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        /></LinearLayout>

主Activity:

package com.androidzhang.zxingframe;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.net.Uri;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import com.google.zxing.WriterException;import com.zxing.activity.CaptureActivity;public class ZxingFrame extends Activity {private EditText resultTextView;private Button scanBarCodeButton;private ImageView iv_qr_image;protected int mScreenWidth ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_zxing_frame);resultTextView = (EditText) this.findViewById(R.id.scan_result);scanBarCodeButton = (Button) this.findViewById(R.id.bt_bigin_scan);iv_qr_image = (ImageView)findViewById(R.id.iv_qr_image);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);mScreenWidth = dm.widthPixels;scanBarCodeButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 调用ZXIng开源项目源码  扫描二维码Intent openCameraIntent = new Intent(ZxingFrame.this,CaptureActivity.class);startActivityForResult(openCameraIntent, 0);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);// 取得返回信息if (resultCode == RESULT_OK) {Bundle bundle = data.getExtras();String scanResult = bundle.getString("result");resultTextView.setText(scanResult);}}//调用浏览器打开,功能尚未完善、、、public void checkResult(View v){String result = resultTextView.getText().toString();//Intent intent = new Intent(ZxingFrame.this,//CheckResult.class);//intent.putExtra("result", result);//startActivity(intent);Intent i= new Intent();                  i.setAction("android.intent.action.VIEW");              Uri content_url = Uri.parse(result);             i.setData(content_url);                     i.setClassName("com.android.browser","com.android.browser.BrowserActivity");             startActivity(i);}//生成二维码public void Create2QR(View v){String uri = resultTextView.getText().toString();//Bitmap bitmap = BitmapUtil.create2DCoderBitmap(uri, mScreenWidth/2, mScreenWidth/2);Bitmap bitmap;try {bitmap = BitmapUtil.createQRCode(uri, mScreenWidth);if(bitmap != null){iv_qr_image.setImageBitmap(bitmap);}} catch (WriterException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

上面每个函数都注释的很清楚了。


接着就是处理了:都在CaptureActivity

这里扫描二维码需要用到的结果:

/** * Handler scan result *  * @param result * @param barcode *            获取结果 */public void handleDecode(Result result, Bitmap barcode) {inactivityTimer.onActivity();playBeepSoundAndVibrate();String resultString = result.getText();// FIXMEif (resultString.equals("")) {Toast.makeText(CaptureActivity.this, "扫描失败!", Toast.LENGTH_SHORT).show();} else {// System.out.println("Result:"+resultString);Intent resultIntent = new Intent();Bundle bundle = new Bundle();bundle.putString("result", resultString);resultIntent.putExtras(bundle);this.setResult(RESULT_OK, resultIntent);}CaptureActivity.this.finish();}
其中添加的是否打开闪光灯:

// 是否开启闪光灯public void IfOpenLight(View v) {ifOpenLight++;switch (ifOpenLight % 2) {case 0:// 关闭CameraManager.get().closeLight();break;case 1:// 打开CameraManager.get().openLight(); // 开闪光灯break;default:break;}}

接着就是从相册中获取带有二维码的照片,然后解析二维码:(这个功能还不够强大,对于只有二维码的图片能解析成功,如果图片含有其他干扰就不一定能解析出来了。希望有大神能够指点指点。。。)

/* * 获取带二维码的相片进行扫描 */public void pickPictureFromAblum(View v) {// 打开手机中的相册Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"innerIntent.setType("image/*");Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");this.startActivityForResult(wrapperIntent, 1);}String photo_path;ProgressDialog mProgress;Bitmap scanBitmap;/* * (non-Javadoc) *  * @see android.app.Activity#onActivityResult(int, int, * android.content.Intent) 对相册获取的结果进行分析 */@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubif (resultCode == RESULT_OK) {switch (requestCode) {case 1:// 获取选中图片的路径Cursor cursor = getContentResolver().query(data.getData(),null, null, null, null);if (cursor.moveToFirst()) {photo_path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));Log.i("路径", photo_path);}cursor.close();mProgress = new ProgressDialog(CaptureActivity.this);mProgress.setMessage("正在扫描...");mProgress.setCancelable(false);mProgress.show();new Thread(new Runnable() {@Overridepublic void run() {Result result = scanningImage(photo_path);if (result != null) {Message m = mHandler.obtainMessage();m.what = 1;m.obj = result.getText();mHandler.sendMessage(m);} else {Message m = mHandler.obtainMessage();m.what = 2;m.obj = "Scan failed!";mHandler.sendMessage(m);}}}).start();break;default:break;}}super.onActivityResult(requestCode, resultCode, data);}final Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubswitch (msg.what) {case 1:mProgress.dismiss();String resultString = msg.obj.toString();if (resultString.equals("")) {Toast.makeText(CaptureActivity.this, "扫描失败!",Toast.LENGTH_SHORT).show();} else {// System.out.println("Result:"+resultString);Intent resultIntent = new Intent();Bundle bundle = new Bundle();bundle.putString("result", resultString);resultIntent.putExtras(bundle);CaptureActivity.this.setResult(RESULT_OK, resultIntent);}CaptureActivity.this.finish();break;case 2:mProgress.dismiss();Toast.makeText(CaptureActivity.this, "解析错误!", Toast.LENGTH_LONG).show();break;default:break;}super.handleMessage(msg);}};/** * 扫描二维码图片的方法 *  * 目前识别度不高,有待改进 *  * @param path * @return */public Result scanningImage(String path) {if (TextUtils.isEmpty(path)) {return null;}Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true; // 先获取原大小scanBitmap = BitmapFactory.decodeFile(path, options);options.inJustDecodeBounds = false; // 获取新的大小int sampleSize = (int) (options.outHeight / (float) 100);if (sampleSize <= 0)sampleSize = 1;options.inSampleSize = sampleSize;scanBitmap = BitmapFactory.decodeFile(path, options);RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));QRCodeReader reader = new QRCodeReader();try {return reader.decode(bitmap1, hints);} catch (NotFoundException e) {e.printStackTrace();} catch (ChecksumException e) {e.printStackTrace();} catch (FormatException e) {e.printStackTrace();}return null;}

剩下一个主要的功能就是生成二维码: 
package com.androidzhang.zxingframe;import java.util.Hashtable;import android.graphics.Bitmap;import android.util.Log;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatWriter;import com.google.zxing.WriterException;import com.google.zxing.common.BitMatrix;import com.google.zxing.qrcode.QRCodeWriter;public class BitmapUtil {/** * 生成一个二维码图像 *  * @param url *            传入的字符串,通常是一个URL * @param QR_WIDTH *            宽度(像素值px) * @param QR_HEIGHT *            高度(像素值px) * @return */public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH,int QR_HEIGHT) {try {// 判断URL合法性if (url == null || "".equals(url) || url.length() < 1) {return null;}Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");// 图像数据转换,使用了矩阵转换BitMatrix bitMatrix = new QRCodeWriter().encode(url,BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);int[] pixels = new int[QR_WIDTH * QR_HEIGHT];// 下面这里按照二维码的算法,逐个生成二维码的图片,// 两个for循环是图片横列扫描的结果for (int y = 0; y < QR_HEIGHT; y++) {for (int x = 0; x < QR_WIDTH; x++) {if (bitMatrix.get(x, y)) {pixels[y * QR_WIDTH + x] = 0xff000000;} else {pixels[y * QR_WIDTH + x] = 0xffffffff;}}}// 生成二维码图片的格式,使用ARGB_8888Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,Bitmap.Config.ARGB_8888);bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);// 显示到一个ImageView上面// sweepIV.setImageBitmap(bitmap);return bitmap;} catch (WriterException e) {Log.i("log", "生成二维码错误" + e.getMessage());return null;}}private static final int BLACK = 0xff000000;/** * 生成一个二维码图像 *  * @param url *            传入的字符串,通常是一个URL * @param widthAndHeight *           图像的宽高 * @return */public static Bitmap createQRCode(String str, int widthAndHeight)throws WriterException {Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");BitMatrix matrix = new MultiFormatWriter().encode(str,BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);int width = matrix.getWidth();int height = matrix.getHeight();int[] pixels = new int[width * height];for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {if (matrix.get(x, y)) {pixels[y * width + x] = BLACK;}}}Bitmap bitmap = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);bitmap.setPixels(pixels, 0, width, 0, 0, width, height);return bitmap;}}

这里写了两种方法,都能用。

这里功能基本上够用了,剩下的自己再琢磨琢磨吧!


还是那句话: 演示图:


源代码下载地址:

http://download.csdn.net/detail/xiaorenwu1206/7785619



转自:http://blog.csdn.net/xiaorenwu1206/article/details/38684983

0 0
原创粉丝点击