Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android技術基礎 >> 第106章、二維碼(從零開始學Android)

第106章、二維碼(從零開始學Android)

編輯:Android技術基礎

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

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

\

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

 

先來看看最後的效果:

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

 

             \              \

 

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

 

             \              \

接下來看如何使用,首先是把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" />  
[html] view plain copy  
  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 plain copy  
  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>  
[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/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. }  
[java] view plain copy  
  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. }  
[java] view plain copy  
  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.     }  
[java] view plain copy  
  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.     }  
  23.  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved