在Android中使用 Google ZXing 實現二維碼、條形碼掃描

openkk 12年前發布 | 342K 次閱讀 條形碼 Android開發 移動開發

我在項目中用到了二維碼掃描的技術,用的是Google提供的ZXing開源項目,它提供二維碼和條形碼的掃描。掃描條形碼就是直接讀取條形碼的內容,掃描二維碼是按照自己指定的二維碼格式進行編碼和解碼。

可以到http://code.google.com/p/zxing/下載ZXing項目的源碼,然后按照官方文檔進行開發,我這里使用的ZXing是經過簡化版的,去除了一些一般使用不必要的文件,項目工程截圖如下:

在Android中使用 Google ZXing 實現二維碼、條形碼掃描

其中encoding包是我在它的基礎上自己加上去的,功能是根據傳入的字符串來生成二維碼圖片,返回一個Bitmap,其余的包是ZXing項目自帶的。另外對掃描界面的布局我也進行了修改,官方的掃描界面是橫向的,我改成了縱向的,并加入了頂部的Tab和取消按鈕(camera.xml),另外還需要的一些文件是colors.xml、ids.xml,這些都是原本ZXing項目中自帶的,最后就是libs下面的jar包。


先來看看最后的效果:

首先是根據輸入的字符串生成二維碼圖片(左圖),然后掃描二維碼圖片可以在界面上顯示掃描結果(右圖):


             在Android中使用 Google ZXing 實現二維碼、條形碼掃描              在Android中使用 Google ZXing 實現二維碼、條形碼掃描


點擊Open Camera按鈕代開掃描框(左圖),掃描條形碼結果如下(右圖):


             在Android中使用 Google ZXing 實現二維碼、條形碼掃描              在Android中使用 Google ZXing 實現二維碼、條形碼掃描

接下來看如何使用,首先是把ZXing項目中的一些文件拷貝到我們自己的項目中,然后在Mainifest文件中進行配置權限:

<uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
還有就是掃描界面Activity的配置:

<activity
            android:configChanges="orientation|keyboardHidden"
            android:name="com.zxing.activity.CaptureActivity"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >
        </activity>
接下來是我自己項目的布局文件:

<?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/btn_scan_barcode"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="Open camera" />

    <LinearLayout 
        android:orientation="horizontal"
        android:layout_marginTop="10dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:textSize="18sp"
        android:text="Scan result:" />

        <TextView 
        android:id="@+id/tv_scan_result"
        android:layout_width="fill_parent"
        android:textSize="18sp"
        android:textColor="@android:color/black"
        android:layout_height="wrap_content" />
    </LinearLayout>

    <EditText 
        android:id="@+id/et_qr_string"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:hint="Input the text"/>

    <Button
        android:id="@+id/btn_add_qrcode"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Generate QRcode" />

    <ImageView 
        android:id="@+id/iv_qr_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"/>

</LinearLayout>


下面是主Activity的代碼,主要功能是打開掃描框、顯示掃描結果、根據輸入的字符串生成二維碼圖片:

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();
    }

以上過程沒有把每一步的詳細步驟寫出來,整體思路基本大致如上,源碼下載:源碼


歡迎關注我的新浪微博和我交流:@唐韌_Ryan


轉自:http://blog.csdn.net/tangren03/article/details/7831826



 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!