• android 二维码生成+扫描


    android 二维码生成+扫描

    1.在Android应用当中,很多时候都要用到二维码扫描,来避免让用户手动输入的麻烦。

    Google官方自己推出了一个二维码开源项目:ZXing库.

    2.这里简单介绍一下ZXing库:ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。

    该项目可实现的条形码编码和解码。目前支持以下格式:UPC-A,UPC-E、EAN-8,EAN-13、39码、93码。ZXing是个很经典的条码/二维码识别的开源类库,以前在功能机上,就有开发者使用J2ME运用ZXing了,

    不过要支持JSR-234规范(自动对焦)的手机才能发挥其威力。

    3.官方demo运行后的效果是:

      扫描后就直接进入到我的博客当中了。

    4.ZXing库主要类: 

    • CaptureActivity。这个是启动Activity 也就是扫描器。
    • CaptureActivityHandler 解码处理类,负责调用另外的线程进行解码。
    • DecodeThread 解码的线程。
    • com.google.zxing.client.android.camera 包,摄像头控制包。
    • ViewfinderView 自定义的View,就是我们看见的拍摄时中间的框框了

    5.二维码生成的方法:

     1 //Edited by mythou
     2 //http://www.cnblogs.com/mythou/
     3   //要转换的地址或字符串,可以是中文
     4     public void createQRImage(String url)
     5     {
     6         try
     7         {
     8             //判断URL合法性
     9             if (url == null || "".equals(url) || url.length() < 1)
    10             {
    11                 return;
    12             }
    13             Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
    14             hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    15             //图像数据转换,使用了矩阵转换
    16             BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
    17             int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
    18             //下面这里按照二维码的算法,逐个生成二维码的图片,
    19             //两个for循环是图片横列扫描的结果
    20             for (int y = 0; y < QR_HEIGHT; y++)
    21             {
    22                 for (int x = 0; x < QR_WIDTH; x++)
    23                 {
    24                     if (bitMatrix.get(x, y))
    25                     {
    26                         pixels[y * QR_WIDTH + x] = 0xff000000;
    27                     }
    28                     else
    29                     {
    30                         pixels[y * QR_WIDTH + x] = 0xffffffff;
    31                     }
    32                 }
    33             }
    34             //生成二维码图片的格式,使用ARGB_8888
    35             Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
    36             bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
    37             //显示到一个ImageView上面
    38             sweepIV.setImageBitmap(bitmap);
    39         }
    40         catch (WriterException e)
    41         {
    42             e.printStackTrace();
    43         }
    44     }

    6.扫描获取二维码信息的工作稍微复杂一些,主要是需要编写Camera的使用,这个跟我们 一般使用Camera一样,需要使用Surfaceview作为预览,这一部我这里就不说了,这个应该不是太复杂。对于使用过Camera做预览的朋友, 应该是挺简单的事情。获取二维码数据的关键处理是在Camera的自动对焦回调函数哪里,调用ZXing的解码接口

     1 //Edited by mythou
     2 //http://www.cnblogs.com/mythou/
     3   private void restartPreviewAndDecode() {
     4     if (state == State.SUCCESS) {
     5       state = State.PREVIEW;
     6       CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
     7       CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
     8       activity.drawViewfinder();
     9     }
    10   }

    这里稍微多说一句,由于解码需要一定时间,所以ZXing的解码调用,都是使用了Handler作为线程通信机制,解码的工作都是放在独立线程里面使用的,如果你直接在主线程解码,恐怕ANR问题是避免不了。

     1 //Edited by mythou
     2 //http://www.cnblogs.com/mythou/
     3 public void handleMessage(Message message) {
     4     switch (message.what) {
     5       case R.id.auto_focus:
     6         //Log.d(TAG, "Got auto-focus message");
     7         // When one auto focus pass finishes, start another. This is the closest thing to
     8         // continuous AF. It does seem to hunt a bit, but I'm not sure what else to do.
     9         if (state == State.PREVIEW) {
    10           CameraManager.get().requestAutoFocus(this, R.id.auto_focus);
    11         }
    12         break;
    13       case R.id.restart_preview:
    14         Log.d(TAG, "Got restart preview message");
    15         restartPreviewAndDecode();
    16         break;
    17       case R.id.decode_succeeded:
    18     //解码成功,获取到界面的结果和原来的二维码数据
    19         Log.d(TAG, "Got decode succeeded message");
    20         state = State.SUCCESS;
    21         Bundle bundle = message.getData();
    22         Bitmap barcode = bundle == null ? null :
    23             (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);
    24         activity.handleDecode((Result) message.obj, barcode);
    25         break;
    26       case R.id.decode_failed:
    27         // We're decoding as fast as possible, so when one decode fails, start another.
    28         state = State.PREVIEW;
    29         CameraManager.get().requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
    30         break;
    31       case R.id.return_scan_result:
    32         Log.d(TAG, "Got return scan result message");
    33         activity.setResult(Activity.RESULT_OK, (Intent) message.obj);
    34         activity.finish();
    35         break;
    36       case R.id.launch_product_query:
    37         Log.d(TAG, "Got product query message");
    38         String url = (String) message.obj;
    39         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    40         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    41         activity.startActivity(intent);
    42         break;
    43     }
    44   }

    7.上面是解码的线程处理不同状态的时候需要注意的地方,我们这里只看获取图像成功的地方, 成功获取图片解码的实在DecodeThread里面实现,DecodeThread里面解码成功后,会把数据序列化,然后保存到Bundle里面,我们 可以直接通过Bundle的序列化,获取到图片数据。同时会把解码后的结果保存到MSG里面,然后就可以根据实际情况进行处理,例如上面代码,解码成功 后,会调用一个处理函数:

     1 //Edited by mythou
     2 //http://www.cnblogs.com/mythou/
     3   public void handleDecode(final Result obj, Bitmap barcode)
     4     {
     5         inactivityTimer.onActivity();
     6         playBeepSoundAndVibrate();
     7         AlertDialog.Builder dialog = new AlertDialog.Builder(this);
     8         if (barcode == null)
     9         {
    10             dialog.setIcon(null);
    11         }
    12         else
    13         {
    14 
    15             Drawable drawable = new BitmapDrawable(barcode);
    16             dialog.setIcon(drawable);
    17         }
    18         dialog.setTitle("扫描结果");
    19         dialog.setMessage(obj.getText());
    20         dialog.setNegativeButton("确定", new DialogInterface.OnClickListener()
    21         {
    22             @Override
    23             public void onClick(DialogInterface dialog, int which)
    24             {
    25                 //用默认浏览器打开扫描得到的地址
    26                 Intent intent = new Intent();
    27                 intent.setAction("android.intent.action.VIEW");
    28                 Uri content_url = Uri.parse(obj.getText());
    29                 intent.setData(content_url);
    30                 startActivity(intent);
    31                 finish();
    32             }
    33         });
    34         dialog.setPositiveButton("取消", new DialogInterface.OnClickListener()
    35         {
    36             @Override
    37             public void onClick(DialogInterface dialog, int which)
    38             {
    39                 finish();
    40             }
    41         });
    42         dialog.create().show();
    43     }

    8.上面就是整个二维码的解码流程,里面因为涉及很多Camera的使用,所以你如果需要使用二维码识别,需要注意一下你的程序需要申请下面的权限,一般的Camera使用以及Camera的自动对焦等。

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

    Edited by 泡泡糖

    ZXing开源项目Google Code地址:https://code.google.com/p/zxing/

    Demo下载地址:http://pan.baidu.com/s/1hqBXPGw

  • 相关阅读:
    Android学习八---OpenCV JAVA API
    Android学习七---Hello OpenCV samples
    Android学习六---OpenCV for android samples
    android学习五---OpenCV for android环境搭建
    android学习四---Activity和Intent
    Servlet总结(Zpoor,你还说你不会Servlet?)
    Eclipse使用小技巧
    Java-List(冷静分析,稍加思索,识破)
    JDBC——setting useSSL=false, or set useSSL=true
    Java-foreach分析总结
  • 原文地址:https://www.cnblogs.com/liangstudyhome/p/3963097.html
Copyright © 2020-2023  润新知