您的位置:首页 > 移动开发 > Android开发

Android 二维码 生成和识别(附Demo源码)

2015-07-16 13:53 489 查看
Posted on 2013-08-25 23:15
泡泡糖 阅读(20424) 评论(7)编辑

收藏

  今天讲一下目前移动领域很常用的技术——二维码。现在大街小巷、各大网站都有二维码的踪迹,不管是IOS、Android、WP都有相关支持的软件。之前我就想了解二维码是如何工作,最近因为工作需要使用相关技术,所以做了初步了解。今天主要是讲解如何使用ZXing库,生成和识别二维码。这篇文章实用性为主,理论性不会讲解太多,有兴趣可以自己查看源码。

1、ZXing库介绍
  这里简单介绍一下ZXing库。ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。该项目可实现的条形码编码和解码。目前支持以下格式:UPC-A,UPC-E、EAN-8,EAN-13、39码、93码。ZXing是个很经典的条码/二维码识别的开源类库,以前在功能机上,就有开发者使用J2ME运用ZXing了,不过要支持JSR-234规范(自动对焦)的手机才能发挥其威力。
  下面是ZXing的demo运行,我这里创建了一个二维码,内容是我博客的网址,大伙可以用微信的扫一扫功能,试一下。就可以直接打开我博客。



(PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)

2、ZXing库主要类

  下面给大家介绍一下,ZXing库里面主要的类以及这些类的作用:

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

3、使用ZXing生成二维码
  下面针对二维码生成和解析做个简单介绍,至于详细的使用方法,建议大家还是自己看看源码,使用起来很简单,不过这个开源项目的代码,值得好好看看。首先给出二维码生成的方法:

按 Ctrl+C 复制代码

按 Ctrl+C 复制代码

  上面就是二维码生成的方法接口,如果你只是使用者方法,很简单,只要传入一个URL即可,就像我截图里面一样,传入一个合法的网址即可。或者像现在一些移动APP的推广,把APP下载地址转为二维码,只要扫一下就可以下载相应的APP。这个也是目前比较流行的APP的推广方式。
  上面代码做的事情不多,主要是调用ZXing库里面QRCodeWriter().encode的方法对我们传进去的URL进行编码,具体如何编码,这个我这里就不详细说,有兴趣可以看ZXing的源码。文章最后会给出ZXing的源码和例子代码。

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


//Edited by mythou
//http://www.cnblogs.com/mythou/

  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();
}
}


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

//Edited by mythou
//http://www.cnblogs.com/mythou/

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:
    //解码成功,获取到界面的结果和原来的二维码数据
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;
}
}


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


//Edited by mythou
//http://www.cnblogs.com/mythou/

  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("扫描结果");
dialog.setMessage(obj.getText());
dialog.setNegativeButton("确定", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//用默认浏览器打开扫描得到的地址
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();
}


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

//Edited by mythou
//http://www.cnblogs.com/mythou/

<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、结语
  上面就是生成和识别二维码的关键流程和代码,有兴趣的朋友可以自己查看ZXing的源码,里面有很多图像分析的知识可以学习。具体使用也可以参考我下面给出的Demo。二维码对于现在移动开发来说很是很常用的技术,所以有空可以了解一下,说不定什么时候就用上了。另外,ZXing库除了二维码外,其实对于条形码也是支持的,只是我这里没有介绍。有需要的自己去看看源码即可。

2013-8-16
Edited by 泡泡糖
ZXing开源项目Google Code地址:https://code.google.com/p/zxing/
ZXingDemo下载:ZXingDemo2013-8-25.rar

Edited by mythou
地址: http://download.csdn.net/category href="/article/4888678.html" target=_blank>

分类:
Android
标签:
android,
二维码,
条形码,
ZXing,
二维码生成,
二维码分析

绿色通道: 好文要顶
关注我 收藏该文与我联系





泡泡糖

关注 - 8

粉丝 - 232

+加关注

3

0

(请您对文章做出评价)

«上一篇:Android遍历API
(1) 动画篇——克隆动画AnimationCloning

»下一篇:Android
自动化测试——Monkey测试

Feedback

#1楼

2013-08-26 09:02 by
IT米粉

用过,不错的东西。貌似扫描条形码的时候,有时会解析错误。
支持(0)反对(0)

#2楼[楼主]

2013-08-26 10:42 by
泡泡糖

@joyworld

条形码还没试过,不过二维码挺稳定。
支持(0)反对(0)

#3楼

2013-08-26 11:30 by
169345559安卓裙

忠实的支持者,我有一个很不错的安卓学习君羊,里面有高手和定期公开课,技术文档,项目源码等,欢迎各android爱好者一起学习和交流 君羊号是: 169345559,加君羊时,请填写验证码:bky
支持(0)反对(0)

#4楼

2013-08-27 14:03 by
我本无名

感觉分享,受益了
支持(0)反对(0)

#5楼

2013-09-05 22:18 by
Lilyandlucy

楼主,你的Demo里的jar包是怎么生成的呢?菜鸟求指导~
支持(0)反对(0)

#6楼

2014-08-16 13:29 by
Softlmis

打开后,界面自动颠倒了是什么意思?而且扫不出来。
支持(0)反对(0)

#7楼

2014-09-09 15:44 by
杉杉来迟

楼主!如果是平板端的话!是不是要把后置摄像头改为前置摄像头!当我改为调用前置摄像头的时候!就没反应了
支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请
登录 或
注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库

【活动】博客园-阿里云开发者俱乐部七月份活动

【推荐】如何让你的程序拥有象Excel一样强大的数据编辑功能

最新IT新闻:

·
Reddit首席工程师Bethanye Blount离职,称对公司失去信心

·
微软修复Hacking Team电邮披露的IE11 0day漏洞

·
云计算时代服务器农场日益庞大

·
7月16日,魅族或牵手诺基亚放大招

·
踢一脚再亲一口,微软要再造诺基亚“老年机”

»
更多新闻...

最新知识库文章:

·
编程王道,唯“慢”不破

·
程序员要有持续产出

·
代码审查过程

·
所谓软件工程

·
也谈怎么学好英语这件小事

»
更多知识库文章...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: