2014年1月14日 星期二

[Android]使用ZXing產生QRCode

QRCode相當方便,手機上用對應的app掃描,可達到快速decode的效果!若在android手機上能有產生QRcode的功能對user來說是相當方便~


ZXing是開放源碼,而且是Apache License 2.0的License,對於企業要商用也非常方便。可以到下面這個網址下載ZXing-2.2.zip:
https://code.google.com/p/zxing/downloads/list




下載完解開來後,會包含這麼多資料夾:其實我們會用到的只有「core」以下的而己

產生QRCode的步驟:
1、在Eclipse裡面建一個新專案,將core\src 複製到新專案的src下
  複製完後會有這麼多東西:
  ps:若覺得這樣未來不好管理的話,推荐將這些東西包成一個jar檔,包成jar檔的方法不在本篇討論的範圍。

2、在"需要產生QRCode的地方"加入下列的程式碼:




String target = "QRCode Test";
QRCodeWriter qrcodewriter = new QRCodeWriter();
BitMatrix bitmatrix = null;
try {
  Hashtable<EncodeHintType,Object> hst = new Hashtable<EncodeHintType,Object>();
  hst.put(EncodeHintType.CHARACTER_SET, "UTF-8");
  bitmatrix = qrcodewriter.encode(target, BarcodeFormat.QR_CODE, 1, 1,hst);
} catch (Exception e) {
  e.printStackTrace();
}
上面的程式碼中,我們得到BitMatrix,這個就是用來描述QRCode的資料結構了!接下來,我們只要將這個Bitmatrix給畫出來就可以了。我的建議是另外寫一個class extends view,並覆寫onDraw 這個method。如下:
class QRCodeDrawer extends View{
 BitMatrix bitmatrix;
 Paint paint;
 public QRCodeDrawer(Context context,BitMatrix bitmatrix){
  super(context);
  this.bitmatrix = bitmatrix;
  paint = new Paint();
 }
 @Override
 public void onDraw(Canvas c){
  if(bitmatrix==null) return;
  c.drawColor(Color.WHITE);
  Rect bounds = c.getClipBounds();
  int w = bounds.width();
  int h = bounds.height();
   
  int imageSize = bitmatrix.getHeight();
  int blockSize = w/imageSize;
  
  int top_offset = (h - imageSize*blockSize)/2;
  int left_offset = (w - imageSize*blockSize)/2;
  
  for(int i=0;i<imageSize;i++)
   for(int j=0;j<imageSize;j++)
    if(bitmatrix.get(i, j))
     c.drawRect(left_offset + i*blockSize, top_offset + j*blockSize, left_offset+(i+1)*blockSize,top_offset+ (j+1)*blockSize, paint);
 }
}
差不多快要大功告成了!!!!! 接下來把剛算好了BitMatrix丟進這個QRDrawer,再加到螢幕上去就行了!
下面是一個範例的完整程式碼:
package com.example.qrcode;
import java.util.Hashtable;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.View;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

public class MainActivity extends Activity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
        String target = "QRCode Test";
     QRCodeWriter qrcodewriter = new QRCodeWriter();
     BitMatrix bitmatrix = null;
  try {
   Hashtable<EncodeHintType,Object> hst = new Hashtable<EncodeHintType,Object>();
   hst.put(EncodeHintType.CHARACTER_SET, "UTF-8");
   bitmatrix = qrcodewriter.encode(target, BarcodeFormat.QR_CODE, 1, 1,hst);
  } catch (Exception e) {
   e.printStackTrace();
  }
  
  class QRCodeDrawer extends View{
   BitMatrix bitmatrix;
   Paint paint;
   public QRCodeDrawer(Context context,BitMatrix bitmatrix){
    super(context);
    this.bitmatrix = bitmatrix;
    paint = new Paint();
   }
   @Override
   public void onDraw(Canvas c){
    if(bitmatrix==null) return;
    c.drawColor(Color.WHITE);
    Rect bounds = c.getClipBounds();
    int w = bounds.width();
    int h = bounds.height();
     
    int imageSize = bitmatrix.getHeight();
    int blockSize = w/imageSize;
    
    int top_offset = (h - imageSize*blockSize)/2;
    int left_offset = (w - imageSize*blockSize)/2;
    
    for(int i=0;i<imageSize;i++)
     for(int j=0;j<imageSize;j++)
      if(bitmatrix.get(i, j))
       c.drawRect(left_offset + i*blockSize, top_offset + j*blockSize, left_offset+(i+1)*blockSize,top_offset+ (j+1)*blockSize, paint);
   }
  }
  
  setContentView(new QRCodeDrawer(this,bitmatrix));
 }
}
在模擬器上跑的結果:
快拿起手機掃掃看吧!
注意!! 程式碼有一行:
hst.put(EncodeHintType.CHARACTER_SET, "UTF-8");
加了這一行的話,就算用中文字也不會產生亂碼囉 !!

沒有留言:

張貼留言