Heguming

Heguming

0个粉丝

8

问答

0

专栏

6

资料

Heguming  发布于  2015-11-03 19:03:43
采纳率 0%
8个问答
4687

二维码扫描实例分享

本帖最后由 Heguming 于 2015-11-5 17:34 编辑

        最近,在做一个视频客户端,需要用到二维码扫描,之前在项目中也曾用到过,再次接触,特此mark下,分享给众位,方便下次直接调用。

        关于二维码扫描,可以通过多种方法,不过网上流传最广的还是通过Google提供的ZXing图像处理库。该库高度集成了包括扫码、解码、编码在内的多种条码/二维码处理功能,可根据用户需求进行定制。

        下面,着重介绍下使用方法,并对其中涉及到的部分代码,进行简要分析。

        首先,第一步,引入所需的Zxing.jar文件(附件1:barcode_core),只需拷贝到项目libs目录下即可。

        第二步,引入以下三个包及其包内文件(附件2:package),引入完成后,如果需要,可对三个包分别进行重命名:

                   1.com.barcode.camera
                 
                   2.com.barcode.core

                   3.com.barcode.executor

        其中,com.barcode.core中包含二维码扫描的Activity-CaptureActivity,开发者主要修改此部分代码,实现各自所需的功能。

        第三步,引入布局文件(附件3:activity_capture),此布局是二维码扫描时的UI,主要包含两个TextView控件(当然,可用两个button代替,第一个用于返回当前Activity,第二个用于从图库中选取二维码图片),一个SurfaceView控件(该控件主要用于显示Camera收集到的图像信息),一个com.barcode.core.ViewfinderView控件(此控件为ZXing库中引入的控件,主要功能是在SurfaceView中画出一个扫描框,用于收集二维码信息)。

        第四步,在配置文件AndroidManifest.xml中添加Activity声明,通知Android系统CaptureActivity的存在,同时添加Camera权限。

        第五步,引入相关资源文件(附件4:resource)。

       最后一步,也是最关键的一步,修改当前Activity及CaptureActivity,使之嵌入该项目中。

      下面,对所需改动的部分作简要说明,并附上相应代码:

      首先,在需要进行二维码扫描功能处启动一个Activity,通过intent将数据传递到CaptureActivity(此处未传递任何数据),需要注意的是,此处是通过startActivityForResult方法启动CaptureActivity,故而扫描完成后需要将字符串返回,并对返回的字符串进行处理,代码如下:

     [code]
       Intent intent = new Intent();
       intent.setClass(this, CaptureActivity.class);
       startActivityForResult(intent, SCAN);  // SCAN为int型常量,即需要返回的requestCode
    [/code]

      其次,覆写onActivityResult方法,对返回结果进行处理:

      [code]
       @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                // TODO Auto-generated method stub
                if (resultCode == RESULT_CANCELED) {
                        Toast.makeText(this, "取消扫描二维码", Toast.LENGTH_SHORT).show();
                        return;
                }
                if (resultCode == RESULT_OK && requestCode == SCAN) {
                        if (data != null) {
                        String scan = data.getStringExtra("scan");  // 获取二维码扫描结果
                        // 此处对扫描结果进行处理
                        Toast.makeText(this, "扫描二维码成功", Toast.LENGTH_SHORT).show();
                        }else{
                         Toast.makeText(this, "扫描二维码失败", Toast.LENGTH_SHORT).show();
                        }                       
                }
        }
       [/code]

      最后,修改CaptureActivity代码,主要包括对控件的处理,及对返回结果的处理:

      对控件的处理:

      此处主要修改第二个TextView,实现从相册中选择二维码功能(第一个TextView用于返回当前Activity,直接finish()即可):

     [code]
     TextView.setOnClickListener(new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                                StringUtils.showPictures(CaptureActivity.this, FROM_PHOTO);
                        }
                });
      [/code]

      执行完此带码后,会自动打开系统默认相册,FROM_PHOTO为常量,此功能用于显示SD中存储的图片,相当于打开系统图库。

      对返回结果的处理:

      [code]  
      @Override
        protected void onActivityResult(int requestCode, int resultCode,
                        final Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                android.util.Log.i("steven", "data.getData()" + data);
                if (data != null) {
                        if (requestCode == FROM_PHOTO) {
                                if (resultCode == RESULT_OK) {
                                        String  photoPath;
                                        Cursor cursor = getContentResolver().query(data.getData(),
                                                        null, null, null, null);
                                        if (cursor.moveToFirst()) {
                                                photoPath = cursor.getString(cursor
                                                                .getColumnIndex(MediaColumns.DATA));
                                        }
                                        cursor.close();
                                        new Thread(new Runnable() {
                                                @Override
                                                public void run() {
                                                        Looper.prepare();
                                                        String result = parsLocalPic(photoPath);
                                                        if (result != null) {
                                                                Message m = Message.obtain();
                                                                m.what = PARSE_BARCODE_SUC;
                                                                m.obj = result;
                                                                barHandler.sendMessage(m);
                                                        } else {
                                                                Message m = Message.obtain();
                                                                m.what = PARSE_BARCODE_FAIL;
                                                                m.obj = "扫描失败!";
                                                                barHandler.sendMessage(m);
                                                        }
                                                        Looper.loop();
                                                }
                                        }).start();
                                }
                        }
                }
        }
       [/code]

        此处代码通过Cursor对象,获取选取图片的路径photoPath,并通过二维码解析方法parsLocalPic(String photoPath)对选取图片进行解析,将解析结果通过Message传递给Handler,以通知主线程进行处理:

       [code]
       Handler barHandler = new Handler() {

                @SuppressLint("HandlerLeak")
                @Override
                public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                        switch (msg.what) {
                        case PARSE_BARCODE_SUC:
                                Toast.makeText(this, "解析二维码成功", Toast.LENGTH_SHORT).show();
                                 // 此处添加二维码解析成功后执行的代码
                                break;
                        case PARSE_BARCODE_FAIL:
                                Toast.makeText(this, "解析二维码失败", Toast.LENGTH_SHORT).show();
                                break;
                        }
                }
        };
       [/code]      

        最后,需要将扫描结果返回当前Activity(即启动CaptureActivity前的Activity):

             [code]
               Intent intent = new Intent();
               intent.putExtra("scan", scan);
               setResult(RESULT_OK, intent);
            [/code]

       OK!大功告成。

       当然,从此相册中选取二维码图片功能如果不需要,完全可以删掉,不影响整体效果。

       运行效果如下:

      

       原创,转载请注明出处

      附件:barcode_core.rar
      
                  附件:resource.rar
      
易百纳技术社区文件: activity_capture.rar
下载
易百纳技术社区文件: barcode_core.rar
下载
易百纳技术社区文件: package.rar
下载
易百纳技术社区文件: resource.rar
下载
我来回答
回答3个
时间排序
认可量排序

gstatham

0个粉丝

6

问答

0

专栏

0

资料

gstatham 2015-11-04 13:17:27
认可0
楼主犀利的一米~~~~

kenneth197

0个粉丝

16

问答

0

专栏

17

资料

kenneth197 2015-11-04 15:46:51
认可0
大赞搂主。:lol 青岛大虾呢

dondeng

0个粉丝

3

问答

0

专栏

1

资料

dondeng 2015-11-10 20:02:05
认可0
向LZ致敬。
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区