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

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

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

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

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

     首先写好布局文件:

     

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="@android:color/white"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <Button  
  9.         android:id="@+id/bt_bigin_scan"  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:layout_marginTop="30dp"  
  13.         android:text="开始扫描" />  
  14.   
  15.     <TextView  
  16.         android:layout_width="wrap_content"  
  17.         android:layout_height="wrap_content"  
  18.         android:text="二维码信息:"  
  19.         android:textColor="@android:color/black"  
  20.         android:textSize="18sp" />  
  21.   
  22.     <EditText  
  23.         android:id="@+id/scan_result"  
  24.         android:layout_width="match_parent"  
  25.         android:layout_height="wrap_content"  
  26.         android:textColor="@android:color/black"  
  27.         android:textSize="18sp" />  
  28.   
  29.     <Button  
  30.         android:layout_width="fill_parent"  
  31.         android:layout_height="wrap_content"  
  32.         android:layout_marginTop="30dp"  
  33.         android:onClick="checkResult"  
  34.         android:text="进入网页" />  
  35.   
  36.     <Button  
  37.         android:layout_width="fill_parent"  
  38.         android:layout_height="wrap_content"  
  39.         android:layout_marginTop="30dp"  
  40.         android:onClick="Create2QR"  
  41.         android:text="生成二维码" />  
  42.   
  43.     <ImageView  
  44.         android:id="@+id/iv_qr_image"  
  45.         android:layout_width="wrap_content"  
  46.         android:layout_height="wrap_content"  
  47.         android:layout_gravity="center"  
  48.         />  
  49.   
  50. </LinearLayout>  
          主Activity:

[java]  view plain  copy
  1. package com.androidzhang.zxingframe;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.graphics.Bitmap;  
  6. import android.net.Uri;  
  7. import android.os.Bundle;  
  8. import android.util.DisplayMetrics;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.Button;  
  12. import android.widget.EditText;  
  13. import android.widget.ImageView;  
  14.   
  15. import com.google.zxing.WriterException;  
  16. import com.zxing.activity.CaptureActivity;  
  17.   
  18. public class ZxingFrame extends Activity {  
  19.   
  20.     private EditText resultTextView;  
  21.     private Button scanBarCodeButton;  
  22.     private ImageView iv_qr_image;  
  23.       
  24.     protected int mScreenWidth ;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_zxing_frame);  
  30.   
  31.         resultTextView = (EditText) this.findViewById(R.id.scan_result);  
  32.   
  33.         scanBarCodeButton = (Button) this.findViewById(R.id.bt_bigin_scan);  
  34.   
  35.         iv_qr_image = (ImageView)findViewById(R.id.iv_qr_image);  
  36.           
  37.         DisplayMetrics dm = new DisplayMetrics();  
  38.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  39.         mScreenWidth = dm.widthPixels;  
  40.           
  41.         scanBarCodeButton.setOnClickListener(new OnClickListener() {  
  42.   
  43.             @Override  
  44.             public void onClick(View v) {  
  45.                 // 调用ZXIng开源项目源码  扫描二维码  
  46.                 Intent openCameraIntent = new Intent(ZxingFrame.this,  
  47.                         CaptureActivity.class);  
  48.                 startActivityForResult(openCameraIntent, 0);  
  49.             }  
  50.         });  
  51.     }  
  52.       
  53.     @Override  
  54.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  55.         super.onActivityResult(requestCode, resultCode, data);  
  56.         // 取得返回信息  
  57.         if (resultCode == RESULT_OK) {  
  58.             Bundle bundle = data.getExtras();  
  59.             String scanResult = bundle.getString("result");  
  60.             resultTextView.setText(scanResult);  
  61.         }  
  62.     }  
  63.       
  64.     //调用浏览器打开,功能尚未完善、、、  
  65.     public void checkResult(View v){  
  66.         String result = resultTextView.getText().toString();  
  67. //      Intent intent = new Intent(ZxingFrame.this,  
  68. //              CheckResult.class);  
  69. //      intent.putExtra("result", result);  
  70. //      startActivity(intent);  
  71.           
  72.         Intent i= new Intent();            
  73.         i.setAction("android.intent.action.VIEW");        
  74.         Uri content_url = Uri.parse(result);       
  75.         i.setData(content_url);               
  76.         i.setClassName("com.android.browser","com.android.browser.BrowserActivity");       
  77.         startActivity(i);  
[java]  view plain  copy
  1. }  
  2.       
  3.     //生成二维码  
  4.     public void Create2QR(View v){  
  5.         String uri = resultTextView.getText().toString();  
  6. //      Bitmap bitmap = BitmapUtil.create2DCoderBitmap(uri, mScreenWidth/2, mScreenWidth/2);  
  7.         Bitmap bitmap;  
  8.         try {  
  9.             bitmap = BitmapUtil.createQRCode(uri, mScreenWidth);  
  10.               
  11.             if(bitmap != null){  
  12.                 iv_qr_image.setImageBitmap(bitmap);  
  13.             }  
  14.               
  15.         } catch (WriterException e) {  
  16.             // TODO Auto-generated catch block  
  17.             e.printStackTrace();  
  18.         }  
  19.           
  20.           
  21.     }  
  22.   
  23. }  

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


接着就是处理了:都在CaptureActivity

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


[java]  view plain  copy
  1. /** 
  2.      * Handler scan result 
  3.      *  
  4.      * @param result 
  5.      * @param barcode 
  6.      *            获取结果 
  7.      */  
  8.     public void handleDecode(Result result, Bitmap barcode) {  
  9.         inactivityTimer.onActivity();  
  10.         playBeepSoundAndVibrate();  
  11.         String resultString = result.getText();  
  12.         // FIXME  
  13.         if (resultString.equals("")) {  
  14.             Toast.makeText(CaptureActivity.this"扫描失败!", Toast.LENGTH_SHORT)  
  15.                     .show();  
  16.         } else {  
  17.             // System.out.println("Result:"+resultString);  
  18.             Intent resultIntent = new Intent();  
  19.             Bundle bundle = new Bundle();  
  20.             bundle.putString("result", resultString);  
  21.             resultIntent.putExtras(bundle);  
  22.             this.setResult(RESULT_OK, resultIntent);  
  23.         }  
  24.         CaptureActivity.this.finish();  
  25.     }  

其中添加的是否打开闪光灯:

[java]  view plain  copy
  1. // 是否开启闪光灯  
  2.     public void IfOpenLight(View v) {  
  3.         ifOpenLight++;  
  4.   
  5.         switch (ifOpenLight % 2) {  
  6.         case 0:  
  7.             // 关闭  
  8.             CameraManager.get().closeLight();  
  9.             break;  
  10.   
  11.         case 1:  
  12.             // 打开  
  13.             CameraManager.get().openLight(); // 开闪光灯  
  14.             break;  
  15.         default:  
  16.             break;  
  17.         }  
  18.     }  

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

[java]  view plain  copy
  1. /* 
  2.      * 获取带二维码的相片进行扫描 
  3.      */  
  4.     public void pickPictureFromAblum(View v) {  
  5.         // 打开手机中的相册  
  6.         Intent innerIntent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"  
  7.         innerIntent.setType("image/*");  
  8.         Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");  
  9.         this.startActivityForResult(wrapperIntent, 1);  
  10.     }  
  11.   
  12.     String photo_path;  
  13.     ProgressDialog mProgress;  
  14.     Bitmap scanBitmap;  
  15.   
  16.     /*  
  17.      * (non-Javadoc)  
  18.      *   
  19.      * @see android.app.Activity#onActivityResult(intint,  
  20.      * android.content.Intent) 对相册获取的结果进行分析  
  21.      */  
  22.     @Override  
  23.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  24.         // TODO Auto-generated method stub  
  25.   
  26.         if (resultCode == RESULT_OK) {  
  27.             switch (requestCode) {  
  28.             case 1:  
  29.                 // 获取选中图片的路径  
  30.                 Cursor cursor = getContentResolver().query(data.getData(),  
  31.                         nullnullnullnull);  
  32.                 if (cursor.moveToFirst()) {  
  33.                     photo_path = cursor.getString(cursor  
  34.                             .getColumnIndex(MediaStore.Images.Media.DATA));  
  35.   
  36.                     Log.i("路径", photo_path);  
  37.                 }  
  38.                 cursor.close();  
  39.   
  40.                 mProgress = new ProgressDialog(CaptureActivity.this);  
  41.                 mProgress.setMessage("正在扫描...");  
  42.                 mProgress.setCancelable(false);  
  43.                 mProgress.show();  
  44.   
  45.                 new Thread(new Runnable() {  
  46.                     @Override  
  47.                     public void run() {  
  48.                         Result result = scanningImage(photo_path);  
  49.                         if (result != null) {  
  50.                             Message m = mHandler.obtainMessage();  
  51.                             m.what = 1;  
  52.                             m.obj = result.getText();  
  53.                             mHandler.sendMessage(m);  
  54.                         } else {  
  55.                             Message m = mHandler.obtainMessage();  
  56.                             m.what = 2;  
  57.                             m.obj = "Scan failed!";  
  58.                             mHandler.sendMessage(m);  
  59.                         }  
  60.   
  61.                     }  
  62.                 }).start();  
  63.                 break;  
  64.   
  65.             default:  
  66.                 break;  
  67.             }  
  68.         }  
  69.   
  70.         super.onActivityResult(requestCode, resultCode, data);  
  71.     }  
  72.   
  73.     final Handler mHandler = new Handler() {  
  74.   
  75.         @Override  
  76.         public void handleMessage(Message msg) {  
  77.             // TODO Auto-generated method stub  
  78.   
  79.             switch (msg.what) {  
  80.             case 1:  
  81.                 mProgress.dismiss();  
  82.                 String resultString = msg.obj.toString();  
  83.                 if (resultString.equals("")) {  
  84.                     Toast.makeText(CaptureActivity.this"扫描失败!",  
  85.                             Toast.LENGTH_SHORT).show();  
  86.                 } else {  
  87.                     // System.out.println("Result:"+resultString);  
  88.                     Intent resultIntent = new Intent();  
  89.                     Bundle bundle = new Bundle();  
  90.                     bundle.putString("result", resultString);  
  91.                     resultIntent.putExtras(bundle);  
  92.                     CaptureActivity.this.setResult(RESULT_OK, resultIntent);  
  93.                 }  
  94.                 CaptureActivity.this.finish();  
  95.                 break;  
  96.   
  97.             case 2:  
  98.                 mProgress.dismiss();  
  99.                 Toast.makeText(CaptureActivity.this"解析错误!", Toast.LENGTH_LONG)  
  100.                         .show();  
  101.   
  102.                 break;  
  103.             default:  
  104.                 break;  
  105.             }  
  106.   
  107.             super.handleMessage(msg);  
  108.         }  
  109.   
  110.     };  
  111.   
  112.     /** 
  113.      * 扫描二维码图片的方法 
  114.      *  
  115.      * 目前识别度不高,有待改进 
  116.      *  
  117.      * @param path 
  118.      * @return 
  119.      */  
  120.     public Result scanningImage(String path) {  
  121.         if (TextUtils.isEmpty(path)) {  
  122.             return null;  
  123.         }  
  124.         Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();  
  125.         hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置二维码内容的编码  
  126.   
  127.         BitmapFactory.Options options = new BitmapFactory.Options();  
  128.         options.inJustDecodeBounds = true// 先获取原大小  
  129.         scanBitmap = BitmapFactory.decodeFile(path, options);  
  130.         options.inJustDecodeBounds = false// 获取新的大小  
  131.         int sampleSize = (int) (options.outHeight / (float100);  
  132.         if (sampleSize <= 0)  
  133.             sampleSize = 1;  
  134.         options.inSampleSize = sampleSize;  
  135.         scanBitmap = BitmapFactory.decodeFile(path, options);  
  136.         RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);  
  137.         BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));  
  138.         QRCodeReader reader = new QRCodeReader();  
  139.         try {  
  140.             return reader.decode(bitmap1, hints);  
  141.   
  142.         } catch (NotFoundException e) {  
  143.             e.printStackTrace();  
  144.         } catch (ChecksumException e) {  
  145.             e.printStackTrace();  
  146.         } catch (FormatException e) {  
  147.             e.printStackTrace();  
  148.         }  
  149.         return null;  
  150.     }  

剩下一个主要的功能就是生成二维码: 

[java]  view plain  copy
  1. package com.androidzhang.zxingframe;  
  2.   
  3. import java.util.Hashtable;  
  4.   
  5. import android.graphics.Bitmap;  
  6. import android.util.Log;  
  7.   
  8. import com.google.zxing.BarcodeFormat;  
  9. import com.google.zxing.EncodeHintType;  
  10. import com.google.zxing.MultiFormatWriter;  
  11. import com.google.zxing.WriterException;  
  12. import com.google.zxing.common.BitMatrix;  
  13. import com.google.zxing.qrcode.QRCodeWriter;  
  14.   
  15. public class BitmapUtil {  
  16.   
  17.     /** 
  18.      * 生成一个二维码图像 
  19.      *  
  20.      * @param url 
  21.      *            传入的字符串,通常是一个URL 
  22.      * @param QR_WIDTH 
  23.      *            宽度(像素值px) 
  24.      * @param QR_HEIGHT 
  25.      *            高度(像素值px) 
  26.      * @return 
  27.      */  
  28.     public static final Bitmap create2DCoderBitmap(String url, int QR_WIDTH,  
  29.             int QR_HEIGHT) {  
  30.         try {  
  31.             // 判断URL合法性  
  32.             if (url == null || "".equals(url) || url.length() < 1) {  
  33.                 return null;  
  34.             }  
  35.             Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
  36.             hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
  37.             // 图像数据转换,使用了矩阵转换  
  38.             BitMatrix bitMatrix = new QRCodeWriter().encode(url,  
  39.                     BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);  
  40.             int[] pixels = new int[QR_WIDTH * QR_HEIGHT];  
  41.             // 下面这里按照二维码的算法,逐个生成二维码的图片,  
  42.             // 两个for循环是图片横列扫描的结果  
  43.             for (int y = 0; y < QR_HEIGHT; y++) {  
  44.                 for (int x = 0; x < QR_WIDTH; x++) {  
  45.                     if (bitMatrix.get(x, y)) {  
  46.                         pixels[y * QR_WIDTH + x] = 0xff000000;  
  47.                     } else {  
  48.                         pixels[y * QR_WIDTH + x] = 0xffffffff;  
  49.                     }  
  50.                 }  
  51.             }  
  52.             // 生成二维码图片的格式,使用ARGB_8888  
  53.             Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,  
  54.                     Bitmap.Config.ARGB_8888);  
  55.             bitmap.setPixels(pixels, 0, QR_WIDTH, 00, QR_WIDTH, QR_HEIGHT);  
  56.             // 显示到一个ImageView上面  
  57.             // sweepIV.setImageBitmap(bitmap);  
  58.             return bitmap;  
  59.         } catch (WriterException e) {  
  60.             Log.i("log""生成二维码错误" + e.getMessage());  
  61.             return null;  
  62.         }  
  63.     }  
  64.   
  65.     private static final int BLACK = 0xff000000;  
  66.   
  67.     /** 
  68.      * 生成一个二维码图像 
  69.      *  
  70.      * @param url 
  71.      *            传入的字符串,通常是一个URL 
  72.      * @param widthAndHeight 
  73.      *           图像的宽高 
  74.      * @return 
  75.      */  
  76.     public static Bitmap createQRCode(String str, int widthAndHeight)  
  77.             throws WriterException {  
  78.         Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();  
  79.         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
  80.         BitMatrix matrix = new MultiFormatWriter().encode(str,  
  81.                 BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);  
  82.         int width = matrix.getWidth();  
  83.         int height = matrix.getHeight();  
  84.         int[] pixels = new int[width * height];  
  85.   
  86.         for (int y = 0; y < height; y++) {  
  87.             for (int x = 0; x < width; x++) {  
  88.                 if (matrix.get(x, y)) {  
  89.                     pixels[y * width + x] = BLACK;  
  90.                 }  
  91.             }  
  92.         }  
  93.         Bitmap bitmap = Bitmap.createBitmap(width, height,  
  94.                 Bitmap.Config.ARGB_8888);  
  95.         bitmap.setPixels(pixels, 0, width, 00, width, height);  
  96.         return bitmap;  
  97.     }  
  98. }  

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

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


还是那句话: 演示图:







源代码下载地址:http://download.csdn.net/detail/xiaorenwu1206/7785619

原文地址:http://blog.csdn.net/xiaorenwu1206/article/details/38684983


希望有高手指点其中的不足啊!小白谢过。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值