转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9526247

最近二维码真是越来越火了,随便电视上、网络上、商场里,到处都是二维码。而内嵌二维码扫描功能的软件也越来越多,QQ、微信、UC浏览器等等应用都可以对着二维码扫一扫,感觉我们自己的应用里不加上二维码扫描功能,都跟不上时代潮流了。所以今天我就将带着大家一起,在我们自己的程序里加入二维码扫描的功能。

不过,二维码功能如果真要做起来还是非常复杂的,从零开始实现不太现实,比较好的做法就是借助现有的开源项目。目前在二维码这一领域名气最大的开源项目就是ZXing了(Zebra Crossing),它提供了多个平台的二维码扫描解决方案,开源项目地址是 https://code.google.com/p/zxing/ 。

虽说网上已经有现成的开源项目了,不过关于ZXing的文档和教程好像还比较少,因此还是有不少朋友并不知道在项目中该如何引入ZXing的,这里我就带着大家一步步地实现,相信每个人在看完本篇文章后都可以在自己的项目中实现二维码扫描功能。

首先,我们需要下载ZXing项目所依赖的Jar包的源码。

下载地址是 http://repo1.maven.org/maven2/com/google/zxing/core/2.2/core-2.2-sources.jar 。

然后我们再来下载ZXing项目,下载地址是 https://zxing.googlecode.com/files/ZXing-2.2.zip 。

建议使用迅雷下载,因为Google Code和Maven的访问在国内不稳定,经常出现断联的情况,使用迅雷可以保证文件的完整性。

另外,经过我的测试,在ZXing项目中直接导入core-2.2的Jar包是无法正常运行的,所以我们只能通过将core-2.2的源码加入到ZXing项目中来实现。下载好以上两个文件后,先解压core-2.2-sources.jar文件,解压之后的目录结构如下图所示:

然后解压ZXing-2.2这个压缩包,里面可以看到各种平台下的ZXing项目源码,我们进入到Android文件夹的src目录下,将core-2.2-sources中的源码拷贝进来。拷贝之后android文件夹下的目录结构如下图所示:

这样准备工作已经完成了,现在我们新建一个Android项目ScannerTest,项目使用Android 4.0的API。

然后将上图中src目录下的所有文件全部复制,粘贴到我们ScannerTest项目的src目录下,完成后目录结构如下图所示:

拷贝完了代码,现在该拷贝资源了,展开ZXing项目android文件夹下的res目录,将drawable文件夹、layout文件夹、menu文件夹、raw文件夹、values文件夹以及xml文件夹中的内容都拷贝到ScannerTest项目的res目录下,注意有冲突的部分要小心解决,比如两个values文件夹中都有string.xml文件,要将它们的内容进行合并,不能只是简单地覆盖。

然后我们还需要将AndroidManifest中的内容进行合并,注意ZXing Android项目下的AndroidManifest在声明Activity时用的都是简写,而现在由于项目包名变了,再使用简写会出现找不到活动的情况,因此所有的简写都要改成完整类名,例如.CaptureActivity要改成com.google.zxing.client.android.CaptureActivity。另外ZXing Android项目下的主活动是CaptureActivity,这里我们需要将主活动的声明删除掉,因为ScannerTest项目中主活动是MainActivity。合并后的AndroidManifest中的代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.example.scannertest"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-permission android:name="android.permission.CAMERA" />
  7. <uses-permission android:name="android.permission.INTERNET" />
  8. <uses-permission android:name="android.permission.VIBRATE" />
  9. <uses-permission android:name="android.permission.FLASHLIGHT" />
  10. <uses-permission android:name="android.permission.READ_CONTACTS" />
  11. <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
  12. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  13. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  14. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  15. <uses-sdk
  16. android:minSdkVersion="14"
  17. android:targetSdkVersion="17" />
  18. <uses-feature
  19. android:name="android.hardware.camera"
  20. android:required="false" />
  21. <uses-feature
  22. android:name="android.hardware.camera.front"
  23. android:required="false" />
  24. <uses-feature
  25. android:name="android.hardware.camera.autofocus"
  26. android:required="false" />
  27. <uses-feature
  28. android:name="android.hardware.camera.flash"
  29. android:required="false" />
  30. <uses-feature android:name="android.hardware.screen.landscape" />
  31. <uses-feature
  32. android:name="android.hardware.wifi"
  33. android:required="false" />
  34. <uses-feature android:name="android.hardware.touchscreen" />
  35. <supports-screens
  36. android:anyDensity="true"
  37. android:largeScreens="true"
  38. android:normalScreens="true"
  39. android:smallScreens="true"
  40. android:xlargeScreens="true" />
  41. <application
  42. android:allowBackup="true"
  43. android:icon="@drawable/ic_launcher"
  44. android:label="@string/app_name"
  45. android:theme="@style/AppTheme" >
  46. <activity
  47. android:name="com.example.scannertest.MainActivity"
  48. android:label="@string/app_name" >
  49. <intent-filter>
  50. <action android:name="android.intent.action.MAIN" />
  51. <category android:name="android.intent.category.LAUNCHER" />
  52. </intent-filter>
  53. </activity>
  54. <activity
  55. android:name="com.google.zxing.client.android.CaptureActivity"
  56. android:clearTaskOnLaunch="true"
  57. android:configChanges="orientation|keyboardHidden"
  58. android:screenOrientation="landscape"
  59. android:stateNotNeeded="true"
  60. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  61. android:windowSoftInputMode="stateAlwaysHidden" >
  62. <intent-filter>
  63. <action android:name="com.google.zxing.client.android.SCAN" />
  64. <category android:name="android.intent.category.DEFAULT" />
  65. </intent-filter>
  66. <intent-filter>
  67. <action android:name="android.intent.action.VIEW" />
  68. <category android:name="android.intent.category.DEFAULT" />
  69. <category android:name="android.intent.category.BROWSABLE" />
  70. <data
  71. android:host="zxing.appspot.com"
  72. android:path="/scan"
  73. android:scheme="http" />
  74. </intent-filter>
  75. <intent-filter>
  76. <action android:name="android.intent.action.VIEW" />
  77. <category android:name="android.intent.category.DEFAULT" />
  78. <category android:name="android.intent.category.BROWSABLE" />
  79. <data
  80. android:host="www.google.com"
  81. android:path="/m/products/scan"
  82. android:scheme="http" />
  83. </intent-filter>
  84. <intent-filter>
  85. <action android:name="android.intent.action.VIEW" />
  86. <category android:name="android.intent.category.DEFAULT" />
  87. <category android:name="android.intent.category.BROWSABLE" />
  88. <data
  89. android:host="www.google.co.uk"
  90. android:path="/m/products/scan"
  91. android:scheme="http" />
  92. </intent-filter>
  93. <intent-filter>
  94. <action android:name="android.intent.action.VIEW" />
  95. <category android:name="android.intent.category.DEFAULT" />
  96. <category android:name="android.intent.category.BROWSABLE" />
  97. <data
  98. android:host="scan"
  99. android:path="/"
  100. android:scheme="zxing" />
  101. </intent-filter>
  102. </activity>
  103. <activity
  104. android:name="com.google.zxing.client.android.PreferencesActivity"
  105. android:label="@string/preferences_name"
  106. android:stateNotNeeded="true" >
  107. </activity>
  108. <activity
  109. android:name="com.google.zxing.client.android.encode.EncodeActivity"
  110. android:stateNotNeeded="true" >
  111. <intent-filter>
  112. <action android:name="com.google.zxing.client.android.ENCODE" />
  113. <category android:name="android.intent.category.DEFAULT" />
  114. </intent-filter>
  115. <intent-filter>
  116. <action android:name="android.intent.action.SEND" />
  117. <category android:name="android.intent.category.DEFAULT" />
  118. <data android:mimeType="text/x-vcard" />
  119. </intent-filter>
  120. <intent-filter>
  121. <action android:name="android.intent.action.SEND" />
  122. <category android:name="android.intent.category.DEFAULT" />
  123. <data android:mimeType="text/plain" />
  124. </intent-filter>
  125. </activity>
  126. <activity
  127. android:name="com.google.zxing.client.android.book.SearchBookContentsActivity"
  128. android:configChanges="orientation|keyboardHidden"
  129. android:label="@string/sbc_name"
  130. android:screenOrientation="landscape"
  131. android:stateNotNeeded="true" >
  132. <intent-filter>
  133. <action android:name="com.google.zxing.client.android.SEARCH_BOOK_CONTENTS" />
  134. <category android:name="android.intent.category.DEFAULT" />
  135. </intent-filter>
  136. </activity>
  137. <activity
  138. android:name="com.google.zxing.client.android.share.ShareActivity"
  139. android:screenOrientation="user"
  140. android:stateNotNeeded="true"
  141. android:theme="@android:style/Theme.Light" >
  142. <intent-filter>
  143. <action android:name="com.google.zxing.client.android.SHARE" />
  144. <category android:name="android.intent.category.DEFAULT" />
  145. </intent-filter>
  146. </activity>
  147. <activity
  148. android:name="com.google.zxing.client.android.history.HistoryActivity"
  149. android:label="@string/history_title"
  150. android:stateNotNeeded="true" >
  151. <intent-filter>
  152. <action android:name="android.intent.action.VIEW" />
  153. <category android:name="android.intent.category.DEFAULT" />
  154. </intent-filter>
  155. </activity>
  156. <activity
  157. android:name="com.google.zxing.client.android.share.BookmarkPickerActivity"
  158. android:label="@string/bookmark_picker_name"
  159. android:stateNotNeeded="true" >
  160. <intent-filter>
  161. <action android:name="android.intent.action.PICK" />
  162. <category android:name="android.intent.category.DEFAULT" />
  163. </intent-filter>
  164. </activity>
  165. <activity
  166. android:name="com.google.zxing.client.android.share.AppPickerActivity"
  167. android:configChanges="orientation"
  168. android:label="@string/app_picker_name"
  169. android:stateNotNeeded="true" >
  170. <intent-filter>
  171. <action android:name="android.intent.action.PICK" />
  172. <category android:name="android.intent.category.DEFAULT" />
  173. </intent-filter>
  174. </activity>
  175. <activity
  176. android:name="com.google.zxing.client.android.HelpActivity"
  177. android:screenOrientation="user" >
  178. <intent-filter>
  179. <action android:name="android.intent.action.VIEW" />
  180. <category android:name="android.intent.category.DEFAULT" />
  181. </intent-filter>
  182. </activity>
  183. </application>
  184. </manifest>

完成到这一步之后,你会发现项目中还是有很多的错误。不用担心,剩下的错误全部都是由于找不到R文件所造成的。这是因为ZXing项目中所引用的R文件都是com.google.zxing.client.android包下的R,而现在我们拷贝到ScannerTest项目之后,应该引用com.example.scannertest包下的R文件。我们需要将有错误的文件一个个地修改过来,虽然工作量不少,但都是傻瓜式操作,只要大家有耐心,就一定可以完成。

现在ScannerTest项目中应该已经没有任何错误了,然后我们还需要对ZXing的代码进行稍微的定制。

打开CaptureActivity,这个类就是用于扫描二维码的最主要的一个类,其中有一个handleDecode()方法,当二维码扫描完成之后会把结果回调到这个方法中,我们现在不想使用默认的处理方式,于是修改handleDecode()中的代码,如下所示:

  1. public void handleDecode(Result rawResult, Bitmap barcode, float scaleFactor) {
  2. String result = rawResult.getText();
  3. if (!TextUtils.isEmpty(result)) {
  4. Intent intent = new Intent();
  5. intent.putExtra("scan_result", rawResult.getText());
  6. setResult(RESULT_OK, intent);
  7. } else {
  8. setResult(RESULT_CANCELED);
  9. }
  10. finish();
  11. }

这里我们将扫描出来的结果借助Intent进行返回。

然后打开或新建activity_main.xml文件做为ScannerTest项目的主布局,在其中添加如下代码:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical" >
  5. <Button
  6. android:id="@+id/scan_button"
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:text="扫一扫" />
  10. <TextView
  11. android:id="@+id/scan_result"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content" />
  14. </LinearLayout>

这个布局文件很简单,一个按钮用于开启二维码扫描功能,一个TextView用于显示扫描结果。

最后打开或新建MainActivity做为ScannerTest项目的主Activity,代码如下所示:

  1. public class MainActivity extends Activity {
  2. public static final int SCAN_CODE = 1;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. Button button = (Button) findViewById(R.id.scan_button);
  8. button.setOnClickListener(new OnClickListener() {
  9. @Override
  10. public void onClick(View v) {
  11. Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
  12. startActivityForResult(intent, SCAN_CODE);
  13. }
  14. });
  15. }
  16. @Override
  17. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  18. switch (requestCode) {
  19. case SCAN_CODE:
  20. TextView scanResult = (TextView) findViewById(R.id.scan_result);
  21. if (resultCode == RESULT_OK) {
  22. String result = data.getStringExtra("scan_result");
  23. scanResult.setText(result);
  24. } else if (resultCode == RESULT_CANCELED) {
  25. scanResult.setText("扫描出错");
  26. }
  27. break;
  28. default:
  29. break;
  30. }
  31. }
  32. }

这个类也很简单,点击按钮时,我们通过startActivityForResult()方法启动CaptureActivity,开始执行二维码扫描,扫描的结果将回调到onActivityResult()方法中,然后在这个方法中取出扫描的结果,并展示在TextView上。

这样我们所有的编码工作就已经完成了,可以尝试运行一下了。首先看到程序的主界面如下图所示:

点击扫一扫后可以进行二维码扫描,见下图:

扫描完成后会将结果返回到主界面,如下图所示:

不知道大家有没有成功呢?这里我精心给大家准备了一张二维码图片,看看有多少朋友能够成功扫出来。 ^_^

另外,ZXing项目是比较庞大的,里面还有很多复杂的功能我们并不需要,如果你有兴趣深度钻研ZXing源码的话,其实还可以简化非常多的代码。 这里我就不带着大家深入研究了,因为我自己都还没完全搞明白呢 

好了,今天的讲解到此结束,有疑问的朋友请在下面留言。

源码下载,请点击这里

Android二维码功能实现,在程序内嵌入ZXing项目的更多相关文章

  1. Android二维码功能实现

    最近二维码真是越来越火了,随便电视上.网络上.商场里,到处都是二维码.而内嵌二维码扫描功能的软件也越来越多,QQ.微信.UC浏览器等等应用都可以对着二维码扫一扫,感觉我们自己的应用里不加上二维码扫描功 ...

  2. Android二维码的生成,解析以及扫描功能

    <1> 布局只有2个按钮,实现生成二维码和解析二维码 <Button android:layout_width="wrap_content" android:la ...

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

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

  4. android 二维码扫描

    了解二维码这个东西还是从微信 中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从一张图片中扫一下竟然能直接加好友,不可思议啊,那时候还不了解二维码,呵呵,然后做项目的时候, 老板说要加上二维码扫描功 ...

  5. android 二维码生成+扫描

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

  6. Android二维码开源项目zxing用例简化和生成二维码、条形码

    上一篇讲到:Android二维码开源项目zxing编译,编译出来后有一个自带的測试程序:CaptureActivity比較复杂,我仅仅要是把一些不用的东西去掉,用看起来更方便,二维码和条形码的流行性自 ...

  7. SNF开发平台WinForm-平板拍照及扫描二维码功能

    在我们做项目的时候,经常会有移动平板处理检验,审核等,方便移动办公.这时就需要在现场拍照上传问题,把当场问题进行上传,也有已经拍完照的图片或加工过的图片进行上传.还有在车间现场一体机,工控机 这种产物 ...

  8. H5实现扫描二维码功能

    为了实现H5扫描二维码功能,我在网上找到了可用的代码:https://github.com/zhiqiang21/WebComponent/tree/master/html5-Qrcode 该程序能基 ...

  9. FastReport 中添加二维码功能.(Delphi)

    http://www.cnblogs.com/fancycloud/archive/2011/07/24/2115240.html FastReport 中添加二维码功能.(Delphi)   在实际 ...

随机推荐

  1. php类和对象

    <?php 1. 类的简单格式: [修饰符] class 类名{ [成员属性] //成员属性,也叫成员变量 [成员方法] //成员方法:也叫成员函数 } 类的完整格式: [修饰符] class ...

  2. Eclipse设置选中高亮显示

    高亮显示选中的变量对于程序员编程很有帮助,正常情况下Eclipse选中变量时都会高亮显示,可能软件冲突导致高亮显示失效,通过如下方法可以进行恢复. 单击IDE顶部Window菜单下的Prefences ...

  3. Android 基于Android的手机邮件收发(JavaMail)之四(邮件的发送)

    上一个邮件的接受,因为不当操作,保存未完成,一切东西都得从头开始那就先从邮件发送来吧. 先下我们做一个较为简单的邮件发送 以下是源代码:相信看过上篇文章所给连接的人,对于javamail应该都有了一定 ...

  4. Hibernate操作指南-搭建一个简单的示例(基于Java Persistence API JPA)

  5. android 中获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)

    final int[] location = new int[2]; view.getLocationOnScreen(location); final int[] location = new in ...

  6. Java实现冒泡排序

    冒泡排序思想就是将数列的相邻两个数比较,较大的数往后保存,小的数往前. package Sort; import java.util.Arrays; public class BubbleSort { ...

  7. ora-02292

    select  table_name from all_constraints where constraint_name = '约束的名称'

  8. synchronized四要素及抽象

    面向对象,java的核心思想就是面向对象编程,以贴近人类在现实生活中的思考方式,任何事物我们都会把它抽象成一个对象,一辆车,一个人,对象是我们思考的基石. 我想说的是,我们写汉字的时候,不会在脑海中命 ...

  9. javascript 创建 div

        纯JAVASCRIPPT创建 (1):document.getElementById("要创建DIV位置的ID").innerHTML='<div>div里面的 ...

  10. Good Bye 2015 D. New Year and Ancient Prophecy

    D. New Year and Ancient Prophecy time limit per test 2.5 seconds memory limit per test 512 megabytes ...