原文网址:http://www.cnblogs.com/mythou/p/3280023.html

今天讲一下目前移动领域很常用的技术——二维码。现在大街小巷、各大网站都有二维码的踪迹,不管是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生成二维码

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

    
//Edited by mythou
//http://www.cnblogs.com/mythou/
  //要转换的地址或字符串,可以是中文
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");
//图像数据转换,使用了矩阵转换
BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
//下面这里按照二维码的算法,逐个生成二维码的图片,
//两个for循环是图片横列扫描的结果

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);
//显示到一个ImageView上面
sweepIV.setImageBitmap(bitmap);
}
catch (WriterException e)
{
e.printStackTrace();
}
}

  上面就是二维码生成的方法接口,如果你只是使用者方法,很简单,只要传入一个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://www.cnblogs.com/mythou/p/3280023.html 

【转】Android 二维码 生成和识别(附Demo源码)--不错的更多相关文章

  1. Android Studio 的蓝牙串口通信(附Demo源码下载)

    根据相关代码制作了一个开源依赖包,将以下所有的代码进行打包,直接调用即可完成所有的操作.详细说明地址如下,如果觉得有用可以GIthub点个Star支持一下: 项目官网 Kotlin版本说明文档 Jav ...

  2. Asp.net MVC集成Google Calendar API(附Demo源码)

    Asp.net MVC集成Google Calendar API(附Demo源码) Google Calendar是非常方便的日程管理应用,很多人都非常熟悉.Google的应用在国内不稳定,但是在国外 ...

  3. winserver的consul部署实践与.net core客户端使用(附demo源码)

    winserver的consul部署实践与.net core客户端使用(附demo源码)   前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...

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

    今天讲一下目前移动领域很常用的技术——二维码.现在大街小巷.各大网站都有二维码的踪迹,不管是IOS. Android.WP都有相关支持的软件.之前我就想了解二维码是如何工作,最近因为工作需要使用相关技 ...

  5. Android自定义组合控件详细示例 (附完整源码)

    在我们平时的Android开发中,有时候原生的控件无法满足我们的需求,或者经常用到几个控件组合在一起来使用.这个时候,我们就可以根据自己的需求创建自定义的控件了,一般通过继承View或其子类来实现. ...

  6. 物流一站式单号查询之快递鸟API接口(附Demo源码)

    连载篇提前看 物流一站式单号查询之快递鸟API接口 物流一站式查询之TrackingMore篇 物流一站式查询之顺丰接口篇 物流一站式查询之快递100 前情提要 前三篇中,我们已经从注册.申请接口.调 ...

  7. .NET gRPC 核心功能初体验,附Demo源码

    gRPC是高性能的RPC框架, 有效地用于服务通信(不管是数据中心内部还是跨数据中心). 由Google开源,目前是一个Cloud Native Computing Foundation(CNCF)孵 ...

  8. Android二维码识别 开源项目ZXing的编译

    Android二维码识别 开源项目ZXing的编译 Android端的条形码/二维码识别功能 因为手机端的输入不是很方便,所以条形码/二维码的扫描是一种很有效的解决手段. 比较流行的手机应用中,常用的 ...

  9. android 二维码生成+扫描

    android 二维码生成+扫描 1.在Android应用当中,很多时候都要用到二维码扫描,来避免让用户手动输入的麻烦. Google官方自己推出了一个二维码开源项目:ZXing库. 2.这里简单介绍 ...

随机推荐

  1. PHP安全编程:主机文件目录浏览(转)

    除了能在共享服务器上读取任意文件之外,攻击者还能建立一个可以浏览文件系统的脚本.由于你的大多数敏感文件不会保存在网站主目录下,此类脚本一般用于找到你的源文件的所在位置.请看下例: 01 <?ph ...

  2. [置顶] UNIX常用命令

    scp命令用于两个机器之前文件的拷贝 scp 被拷贝文件 远程机器用户名@远程机器IP:拷贝目的目录或者拷贝目录下的目的文件 dos2unix 在执行编译文件时,本来应该生成可执行文件a,但是执行完后 ...

  3. C#编写QQ找茬外挂

    QQ找茬外挂,用C#代码编写. 使用方法 这个工具的主要运行流程很简单:游戏截图->比较图片->标记图片不同点.实现代码 截图的处理类ScreenCapture: /// /// 提供全屏 ...

  4. Android图片异步加载之Android-Universal-Image-Loader(转)

    今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...

  5. 【开源java游戏框架libgdx专题】-03-项目开发与调试

    创建libgdx项目 下载项目配置工具 gdx-setup.jar 生成项目 导入Eclipse File -> Import -> Gradle -> Gradle Project ...

  6. OD: Kernel Exploit - 1

    第 22 章,内核漏洞利用技术 首先编写具有漏洞的驱动 exploitme.sys,再展开内核漏洞利用思路和方法: /***************************************** ...

  7. OJ常见问题及必须认识的对拍处理水题

    HDUOJ: 常见问题及解答 Q: Online Judge(以下简称OJ)支持哪些语言? A: 目前为止,HDOJ支持C.C++.Pascal和Java四种语言. Q: 有什么条件判断我的程序是在O ...

  8. jquery属性选择器之 attr

    在温习jquery手册的时候,注意到这个,坐下记录. attr(name|properties|key,value|fn) 获取匹配的元素集合中的第一个元素的属性的值 或 设置每一个匹配的元素的一个或 ...

  9. 关于调用office com组件导出Excel

    服务器环境: 环境为win2008 r2,系统为64位,程序是C#的winform.因为需要处理数据,然后生成Excel,耗时太长,就使用了多线程.winform程序是由计划任务启动,每天晚上去跑. ...

  10. Objective-C基础知识点总结

    一.#import 和 #include 的区别,@class代表什么?@class 和 #import 的区别?#import<> 和 #import""的区别 答: ...