最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 二維碼 生成和識(shí)別二維碼 附源碼下載

 更新時(shí)間:2016年06月23日 09:11:28   作者:泡泡糖  
這篇文章主要介紹了Android 生成和識(shí)別二維碼的方法,提供源碼下載,需要的朋友可以參考下。

  今天講一下目前移動(dòng)領(lǐng)域很常用的技術(shù)——二維碼?,F(xiàn)在大街小巷、各大網(wǎng)站都有二維碼的蹤跡,不管是IOS、Android、WP都有相關(guān)支持的軟件。之前我就想了解二維碼是如何工作,最近因?yàn)楣ぷ餍枰褂孟嚓P(guān)技術(shù),所以做了初步了解。今天主要是講解如何使用ZXing庫(kù),生成和識(shí)別二維碼。這篇文章實(shí)用性為主,理論性不會(huì)講解太多,有興趣可以自己查看源碼。

1、ZXing庫(kù)介紹

  這里簡(jiǎn)單介紹一下ZXing庫(kù)。ZXing是一個(gè)開(kāi)放源碼的,用Java實(shí)現(xiàn)的多種格式的1D/2D條碼圖像處理庫(kù),它包含了聯(lián)系到其他語(yǔ)言的端口。Zxing可以實(shí)現(xiàn)使用手機(jī)的內(nèi)置的攝像頭完成條形碼的掃描及解碼。該項(xiàng)目可實(shí)現(xiàn)的條形碼編碼和解碼。目前支持以下格式:UPC-A,UPC-E、EAN-8,EAN-13、39碼、93碼。ZXing是個(gè)很經(jīng)典的條碼/二維碼識(shí)別的開(kāi)源類(lèi)庫(kù),以前在功能機(jī)上,就有開(kāi)發(fā)者使用J2ME運(yùn)用ZXing了,不過(guò)要支持JSR-234規(guī)范(自動(dòng)對(duì)焦)的手機(jī)才能發(fā)揮其威力。
  下面是ZXing的demo運(yùn)行,我這里創(chuàng)建了一個(gè)二維碼,大伙可以用微信的掃一掃功能,試一下。就可以直接打開(kāi)下面的網(wǎng)址。 

http://img.jbzj.com/file_images/article/201606/201606230912461.jpg

2、ZXing庫(kù)主要類(lèi)

  下面給大家介紹一下,ZXing庫(kù)里面主要的類(lèi)以及這些類(lèi)的作用:

  CaptureActivity。這個(gè)是啟動(dòng)Activity 也就是掃描器。
  CaptureActivityHandler 解碼處理類(lèi),負(fù)責(zé)調(diào)用另外的線程進(jìn)行解碼。
  DecodeThread 解碼的線程。
  com.google.zxing.client.android.camera 包,攝像頭控制包。
  ViewfinderView 自定義的View,就是我們看見(jiàn)的拍攝時(shí)中間的框框了。

 

3、使用ZXing生成二維碼

  下面針對(duì)二維碼生成和解析做個(gè)簡(jiǎn)單介紹,至于詳細(xì)的使用方法,建議大家還是自己看看源碼,使用起來(lái)很簡(jiǎn)單,不過(guò)這個(gè)開(kāi)源項(xiàng)目的代碼,值得好好看看。首先給出二維碼生成的方法:

//要轉(zhuǎn)換的地址或字符串,可以是中文
public void createQRImage(String url)
{
 try
 {
 //判斷URL合法性
 if (url == null || "".equals(url) || url.length() < 1)
 {
  return;
 }
 Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
 hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
 //圖像數(shù)據(jù)轉(zhuǎn)換,使用了矩陣轉(zhuǎn)換
 BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
 int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
 //下面這里按照二維碼的算法,逐個(gè)生成二維碼的圖片,
 //兩個(gè)for循環(huán)是圖片橫列掃描的結(jié)果
 for (int y = 0; y < QR_HEIGHT; y++)
 {
  for (int x = 0; x < QR_WIDTH; x++)
  {
  if (bitMatrix.get(x, y))
  {
   pixels[y * QR_WIDTH + x] = 0xff000000;
  }
  else
  {
   pixels[y * QR_WIDTH + x] = 0xffffffff;
  }
  }
 }
 //生成二維碼圖片的格式,使用ARGB_8888
 Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
 bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
 //顯示到一個(gè)ImageView上面
 sweepIV.setImageBitmap(bitmap);
 }
 catch (WriterException e)
 {
 e.printStackTrace();
 }
}

  上面就是二維碼生成的方法接口,如果你只是使用者方法,很簡(jiǎn)單,只要傳入一個(gè)URL即可,就像我截圖里面一樣,傳入一個(gè)合法的網(wǎng)址即可?;蛘呦瘳F(xiàn)在一些移動(dòng)APP的推廣,把APP下載地址轉(zhuǎn)為二維碼,只要掃一下就可以下載相應(yīng)的APP。這個(gè)也是目前比較流行的APP的推廣方式。

  上面代碼做的事情不多,主要是調(diào)用ZXing庫(kù)里面QRCodeWriter().encode的方法對(duì)我們傳進(jìn)去的URL進(jìn)行編碼,具體如何編碼,這個(gè)我這里就不詳細(xì)說(shuō),有興趣可以看ZXing的源碼。文章最后會(huì)給出ZXing的源碼和例子代碼。

4、掃描二維碼獲取信息

  掃描獲取二維碼信息的工作稍微復(fù)雜一些,主要是需要編寫(xiě)Camera的使用,這個(gè)跟我們一般使用Camera一樣,需要使用Surfaceview作為預(yù)覽,這一部我這里就不說(shuō)了,這個(gè)應(yīng)該不是太復(fù)雜。對(duì)于使用過(guò)Camera做預(yù)覽的朋友,應(yīng)該是挺簡(jiǎn)單的事情。獲取二維碼數(shù)據(jù)的關(guān)鍵處理是在Camera的自動(dòng)對(duì)焦回調(diào)函數(shù)哪里,調(diào)用ZXing的解碼接口。

private void restartPreviewAndDecode() {
 if (state == State.SUCCESS) {
 state = State.PREVIEW;
 CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
 CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
 activity.drawViewfinder();
 }
}

  這里稍微多說(shuō)一句,由于解碼需要一定時(shí)間,所以ZXing的解碼調(diào)用,都是使用了Handler作為線程通信機(jī)制,解碼的工作都是放在獨(dú)立線程里面使用的,如果你直接在主線程解碼,恐怕ANR問(wèn)題是避免不了。

public void handleMessage(Message message) {
 switch (message.what) {
 case R.id.auto_focus:
 //Log.d(TAG, "Got auto-focus message");
 // When one auto focus pass finishes, start another. This is the closest thing to
 // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
 if (state == State.PREVIEW) {
  CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
 }
 break;
 case R.id.restart_preview:
 Log.d(TAG, "Got restart preview message");
 restartPreviewAndDecode();
 break;
 case R.id.decode_succeeded:
    //解碼成功,獲取到界面的結(jié)果和原來(lái)的二維碼數(shù)據(jù)
 Log.d(TAG, "Got decode succeeded message");
 state = State.SUCCESS;
 Bundle bundle = message.getData();
 Bitmap barcode = bundle == null ? null :
  (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
 activity.handleDecode((Result) message.obj, barcode);
 break;
 case R.id.decode_failed:
 // We're decoding as fast as possible, so when one decode fails, start another.
 state = State.PREVIEW;
 CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
 break;
 case R.id.return_scan_result:
 Log.d(TAG, "Got return scan result message");
 activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
 activity.finish();
 break;
 case R.id.launch_product_query:
 Log.d(TAG, "Got product query message");
 String url = (String) message.obj;
 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
 activity.startActivity(intent);
 break;
 }
}

  上面是解碼的線程處理不同狀態(tài)的時(shí)候需要注意的地方,我們這里只看獲取圖像成功的地方,成功獲取圖片解碼的實(shí)在DecodeThread里面實(shí)現(xiàn),DecodeThread里面解碼成功后,會(huì)把數(shù)據(jù)序列化,然后保存到Bundle里面,我們可以直接通過(guò)Bundle的序列化,獲取到圖片數(shù)據(jù)。同時(shí)會(huì)把解碼后的結(jié)果保存到MSG里面,然后就可以根據(jù)實(shí)際情況進(jìn)行處理,例如上面代碼,解碼成功后,會(huì)調(diào)用一個(gè)處理函數(shù):

public void handleDecode(final Result obj, Bitmap barcode)
{
 inactivityTimer.onActivity();
 playBeepSoundAndVibrate();
 AlertDialog.Builder dialog = new AlertDialog.Builder(this);
 if (barcode == null)
 {
 dialog.setIcon(null);
 }
 else
 {

 Drawable drawable = new BitmapDrawable(barcode);
 dialog.setIcon(drawable);
 }
 dialog.setTitle("掃描結(jié)果");
 dialog.setMessage(obj.getText());
 dialog.setNegativeButton("確定", new DialogInterface.OnClickListener()
 {
 @Override
 public void onClick(DialogInterface dialog, int which)
 {
  //用默認(rèn)瀏覽器打開(kāi)掃描得到的地址
  Intent intent = new Intent();
  intent.setAction("android.intent.action.VIEW");
  Uri content_url = Uri.parse(obj.getText());
  intent.setData(content_url);
  startActivity(intent);
  finish();
 }
 });
 dialog.setPositiveButton("取消", new DialogInterface.OnClickListener()
 {
 @Override
 public void onClick(DialogInterface dialog, int which)
 {
  finish();
 }
 });
 dialog.create().show();
}

  上面就是整個(gè)二維碼的解碼流程,里面因?yàn)樯婕昂芏郈amera的使用,所以你如果需要使用二維碼識(shí)別,需要注意一下你的程序需要申請(qǐng)下面的權(quán)限,一般的Camera使用以及Camera的自動(dòng)對(duì)焦等。


<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

5、結(jié)語(yǔ)

  上面就是生成和識(shí)別二維碼的關(guān)鍵流程和代碼,有興趣的朋友可以自己查看ZXing的源碼,里面有很多圖像分析的知識(shí)可以學(xué)習(xí)。具體使用也可以參考我下面給出的Demo。二維碼對(duì)于現(xiàn)在移動(dòng)開(kāi)發(fā)來(lái)說(shuō)很是很常用的技術(shù),所以有空可以了解一下,說(shuō)不定什么時(shí)候就用上了。另外,ZXing庫(kù)除了二維碼外,其實(shí)對(duì)于條形碼也是支持的,只是我這里沒(méi)有介紹。有需要的自己去看看源碼即可。

ZXing開(kāi)源項(xiàng)目Google Code地址:https://code.google.com/p/zxing/

ZXingDemo下載:ZXingDemo.rar

以上就是本文的全部?jī)?nèi)容,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

湛江市| 确山县| 合川市| 谢通门县| 庆元县| 鹤峰县| 余江县| 南通市| 军事| 白沙| 广元市| 临江市| 毕节市| 卢湾区| 洪湖市| 保德县| 永泰县| 美姑县| 金平| 增城市| 溆浦县| 崇义县| 苍溪县| 什邡市| 南华县| 蒙自县| 呈贡县| 临沧市| 平舆县| 藁城市| 桃园县| 威海市| 什邡市| 定陶县| 江永县| 芜湖县| 清水河县| 纳雍县| 玉龙| 司法| 涿鹿县|