ZXing开源项目,它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。
可以到http://code.google.com/p/zxing/下载ZXing项目的源码
encoding包是我在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。
首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:
[html] view plaincopy
1. <uses-permission android:name="android.permission.VIBRATE" />
2. <uses-permission android:name="android.permission.CAMERA" />
3. <uses-feature android:name="android.hardware.camera" />
4. <uses-feature android:name="android.hardware.camera.autofocus" />
还有就是扫描界面Activity的配置:
[html] view plaincopy
1. <activity
2. android:configChanges="orientation|keyboardHidden"
3. android:name="com.zxing.activity.CaptureActivity"
4. android:screenOrientation="portrait"
5. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
6. android:windowSoftInputMode="stateAlwaysHidden" >
7. </activity>
接下来是我自己项目的布局文件:
[html] view plaincopy
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/btn_scan_barcode"
10. android:layout_width="fill_parent"
11. android:layout_height="wrap_content"
12. android:layout_marginTop="30dp"
13. android:text="Open camera" />
14.
15. <LinearLayout
16. android:orientation="horizontal"
17. android:layout_marginTop="10dp"
18. android:layout_width="fill_parent"
19. android:layout_height="wrap_content">
20.
21. <TextView
22. android:layout_width="wrap_content"
23. android:layout_height="wrap_content"
24. android:textColor="@android:color/black"
25. android:textSize="18sp"
26. android:text="Scan result:" />
27.
28. <TextView
29. android:id="@+id/tv_scan_result"
30. android:layout_width="fill_parent"
31. android:textSize="18sp"
32. android:textColor="@android:color/black"
33. android:layout_height="wrap_content" />
34. </LinearLayout>
35.
36. <EditText
37. android:id="@+id/et_qr_string"
38. android:layout_width="fill_parent"
39. android:layout_height="wrap_content"
40. android:layout_marginTop="30dp"
41. android:hint="Input the text"/>
42.
43. <Button
44. android:id="@+id/btn_add_qrcode"
45. android:layout_width="fill_parent"
46. android:layout_height="wrap_content"
47. android:text="Generate QRcode" />
48.
49. <ImageView
50. android:id="@+id/iv_qr_image"
51. android:layout_width="wrap_content"
52. android:layout_height="wrap_content"
53. android:layout_marginTop="10dp"
54. android:layout_gravity="center"/>
55.
56. </LinearLayout>
下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:
[java] view plaincopy
1. public class BarCodeTestActivity extends Activity {
2. /** Called when the activity is first created. */
3. private TextView resultTextView;
4. private EditText qrStrEditText;
5. private ImageView qrImgImageView;
6.
7. @Override
8. public void onCreate(Bundle savedInstanceState) {
9. super.onCreate(savedInstanceState);
10. setContentView(R.layout.main);
11.
12. resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
13. qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
14. qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
15.
16. Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
17. scanBarCodeButton.setOnClickListener(new OnClickListener() {
18.
19. @Override
20. public void onClick(View v) {
21. //打开扫描界面扫描条形码或二维码
22. Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);
23. startActivityForResult(openCameraIntent, 0);
24. }
25. });
26.
27. Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
28. generateQRCodeButton.setOnClickListener(new OnClickListener() {
29.
30. @Override
31. public void onClick(View v) {
32. try {
33. String contentString = qrStrEditText.getText().toString();
34. if (!contentString.equals("")) {
35. //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
36. Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
37. qrImgImageView.setImageBitmap(qrCodeBitmap);
38. }else {
39. Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();
40. }
41.
42. } catch (WriterException e) {
43. // TODO Auto-generated catch block
44. e.printStackTrace();
45. }
46. }
47. });
48. }
49.
50. @Override
51. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
52. super.onActivityResult(requestCode, resultCode, data);
53. //处理扫描结果(在界面上显示)
54. if (resultCode == RESULT_OK) {
55. Bundle bundle = data.getExtras();
56. String scanResult = bundle.getString("result");
57. resultTextView.setText(scanResult);
58. }
59. }
60. }
其中生成二维码图片的代码在EncodingHandler.java中:
[java] view plaincopy
1. public final class EncodingHandler {
2. private static final int BLACK = 0xff000000;
3.
4. public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
5. Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
6. hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
7. BitMatrix matrix = new MultiFormatWriter().encode(str,
8. BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
9. int width = matrix.getWidth();
10. int height = matrix.getHeight();
11. int[] pixels = new int[width * height];
12.
13. for (int y = 0; y < height; y++) {
14. for (int x = 0; x < width; x++) {
15. if (matrix.get(x, y)) {
16. pixels[y * width + x] = BLACK;
17. }
18. }
19. }
20. Bitmap bitmap = Bitmap.createBitmap(width, height,
21. Bitmap.Config.ARGB_8888);
22. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
23. return bitmap;
24. }
25. }
最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:
[java] view plaincopy
1. /**
2. * Handler scan result
3. * @param result
4. * @param barcode
5. */
6. public void handleDecode(Result result, Bitmap barcode) {
7. inactivityTimer.onActivity();
8. playBeepSoundAndVibrate();
9. String resultString = result.getText();
10. //FIXME
11. if (resultString.equals("")) {
12. Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
13. }else {
14. // System.out.println("Result:"+resultString);
15. Intent resultIntent = new Intent();
16. Bundle bundle = new Bundle();
17. bundle.putString("result", resultString);
18. resultIntent.putExtras(bundle);
19. this.setResult(RESULT_OK, resultIntent);
20. }
21. CaptureActivity.this.finish();
22. }