二维码、条形码扫描——使用Google ZXing

85580695 2013-07-17

我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。

可以到http://code.google.com/p/zxing/下载ZXing项目的源码,然后按照官方文档进行开发,我这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程截图如下:

二维码、条形码扫描——使用Google ZXing

其中encoding包是我 在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也 进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是 colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。

先来看看最后的效果:

首先是根据输入的字符串生成二维码图片(左图),然后扫描二维码图片可以在界面上显示扫描结果(右图):

             二维码、条形码扫描——使用Google ZXing              二维码、条形码扫描——使用Google ZXing

点击Open Camera按钮代开扫描框(左图),扫描条形码结果如下(右图):

             二维码、条形码扫描——使用Google ZXing              二维码、条形码扫描——使用Google ZXing

接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:

public class BarCodeTestActivity extends Activity {  
    /** Called when the activity is first created. */  
    private TextView resultTextView;  
    private EditText qrStrEditText;  
    private ImageView qrImgImageView;  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
          
        resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);  
        qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);  
        qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);  
          
        Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);  
        scanBarCodeButton.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                //打开扫描界面扫描条形码或二维码  
                Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);  
                startActivityForResult(openCameraIntent, 0);  
            }  
        });  
          
        Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);  
        generateQRCodeButton.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                try {  
                    String contentString = qrStrEditText.getText().toString();  
                    if (!contentString.equals("")) {  
                        //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)  
                        Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);  
                        qrImgImageView.setImageBitmap(qrCodeBitmap);  
                    }else {  
                        Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();  
                    }  
                      
                } catch (WriterException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        });  
    }  
  
    @Override  
    protected 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);  
        }  
    }  
}  


其中生成二维码图片的代码在EncodingHandler.java中:

public final class EncodingHandler {  
    private static final int BLACK = 0xff000000;  
      
    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;  
    }  
}  


最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:

/** 
     * Handler scan result 
     * @param result 
     * @param barcode 
     */  
    public void handleDecode(Result result, Bitmap barcode) {  
        inactivityTimer.onActivity();  
        playBeepSoundAndVibrate();  
        String resultString = result.getText();  
        //FIXME  
        if (resultString.equals("")) {  
            Toast.makeText(CaptureActivity.this, "Scan failed!", 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();  
    }  


以上过程没有把每一步的详细步骤写出来,整体思路基本大致如上,源码下载:源码

相关推荐