二维码、条形码扫描——使用Google ZXing
我在项目中用到了二维码扫描的技术,用的是Google提供的ZXing开源项目,它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。
可以到http://code.google.com/p/zxing/下载ZXing项目的源码,然后按照官方文档进行开发,我这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程截图如下:

其中encoding包是我
在它的基础上自己加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局我也
进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是
colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。
先来看看最后的效果:
首先是根据输入的字符串生成二维码图片(左图),然后扫描二维码图片可以在界面上显示扫描结果(右图):

点击Open Camera按钮代开扫描框(左图),扫描条形码结果如下(右图):

接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:
- <uses-permission android:name="android.permission.VIBRATE" />
- <uses-permission android:name="android.permission.CAMERA" />
- <uses-feature android:name="android.hardware.camera" />
- <uses-feature android:name="android.hardware.camera.autofocus" />
还有就是扫描界面Activity的配置:
- <activity
- android:configChanges="orientation|keyboardHidden"
- android:name="com.zxing.activity.CaptureActivity"
- android:screenOrientation="portrait"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:windowSoftInputMode="stateAlwaysHidden" >
- </activity>
接下来是我自己项目的布局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/white"
- android:orientation="vertical" >
- <Button
- android:id="@+id/btn_scan_barcode"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:text="Open camera" />
- <LinearLayout
- android:orientation="horizontal"
- android:layout_marginTop="10dp"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@android:color/black"
- android:textSize="18sp"
- android:text="Scan result:" />
- <TextView
- android:id="@+id/tv_scan_result"
- android:layout_width="fill_parent"
- android:textSize="18sp"
- android:textColor="@android:color/black"
- android:layout_height="wrap_content" />
- </LinearLayout>
- <EditText
- android:id="@+id/et_qr_string"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="30dp"
- android:hint="Input the text"/>
- <Button
- android:id="@+id/btn_add_qrcode"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Generate QRcode" />
- <ImageView
- android:id="@+id/iv_qr_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp"
- android:layout_gravity="center"/>
- </LinearLayout>
下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:
- public class BarCodeTestActivity extends Activity {
- /** Called when the activity is first created. */
- private TextView resultTextView;
- private EditText qrStrEditText;
- private ImageView qrImgImageView;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
- qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
- qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
- Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
- scanBarCodeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //打开扫描界面扫描条形码或二维码
- Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);
- startActivityForResult(openCameraIntent, 0);
- }
- });
- Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
- generateQRCodeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- try {
- String contentString = qrStrEditText.getText().toString();
- if (!contentString.equals("")) {
- //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
- Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
- qrImgImageView.setImageBitmap(qrCodeBitmap);
- }else {
- Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();
- }
- } catch (WriterException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- });
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- //处理扫描结果(在界面上显示)
- if (resultCode == RESULT_OK) {
- Bundle bundle = data.getExtras();
- String scanResult = bundle.getString("result");
- resultTextView.setText(scanResult);
- }
- }
- }
其中生成二维码图片的代码在EncodingHandler.java中:
- public final class EncodingHandler {
- private static final int BLACK = 0xff000000;
- public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
- Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
- hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
- BitMatrix matrix = new MultiFormatWriter().encode(str,
- BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
- int width = matrix.getWidth();
- int height = matrix.getHeight();
- int[] pixels = new int[width * height];
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- if (matrix.get(x, y)) {
- pixels[y * width + x] = BLACK;
- }
- }
- }
- Bitmap bitmap = Bitmap.createBitmap(width, height,
- Bitmap.Config.ARGB_8888);
- bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
- return bitmap;
- }
- }
最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:
- /**
- * Handler scan result
- * @param result
- * @param barcode
- */
- public void handleDecode(Result result, Bitmap barcode) {
- inactivityTimer.onActivity();
- playBeepSoundAndVibrate();
- String resultString = result.getText();
- //FIXME
- if (resultString.equals("")) {
- Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
- }else {
- // System.out.println("Result:"+resultString);
- Intent resultIntent = new Intent();
- Bundle bundle = new Bundle();
- bundle.putString("result", resultString);
- resultIntent.putExtras(bundle);
- this.setResult(RESULT_OK, resultIntent);
- }
- CaptureActivity.this.finish();
- }
- 转自:http://blog.csdn.net/tangren03/article/details/7831826
二维码、条形码扫描——使用Google ZXing的更多相关文章
- java二维码生成-谷歌(Google.zxing)开源二维码生成学习及实例
java二维码生成-谷歌(Google.zxing)开源二维码生成的实例及介绍 我们使用比特矩阵(位矩阵)的QR码编码在缓冲图片上画出二维码 实例有以下一个传入参数 OutputStream ou ...
- iOS系统原生二维码条形码扫描
本文讲述如何用系统自带的东东实现二维码扫描的功能:点击当前页面的某个按钮,创建扫描VIEW.细心的小伙伴可以发现 title被改变了,返回按钮被隐藏了.这个代码自己写就行了,与本文关系不大...绿色的 ...
- IOS原声二维码条形码扫描实现
本文讲述如何用系统自带的东东实现二维码扫描的功能:点击当前页面的某个按钮,创建扫描VIEW.细心的小伙伴可以发现 title被改变了,返回按钮被隐藏了.这个代码自己写就行了,与本文关系不大...绿色的 ...
- zxing解析带logo二维码会报com.google.zxing.NotFoundException
参考原文:https://blog.csdn.net/cyl1226541/article/details/70557232 //复杂模式,开启PURE_BARCODE模式(☆☆☆) HINTS.pu ...
- iOS雪花动画、音频图、新闻界面框架、2048游戏、二维码条形码扫码生成等源码
iOS精选源码 粒子雪花与烟花的动画 iOS 2048游戏 JHSoundWaveView - 简单地声波图.音波图 一个可快速集成的新闻详情界面框架,类似今日头条,腾讯新闻 二维码/条形码扫描及扫描 ...
- 【转】 Android 基于google Zxing实现对手机中的二维码进行扫描--不错
原文网址:http://blog.csdn.net/xiaanming/article/details/14450809 转载请注明出处:http://blog.csdn.net/xiaanming/ ...
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 现在的二维码可谓是烂大街了,到处都是二维码,什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...
- Android 基于google Zxing实现对手机中的二维码进行扫描
转载请注明出处:http://blog.csdn.net/xiaanming/article/details/14450809 有时候我们有这样子的需求,需要扫描手机中有二维码的的图片,所以今天实现的 ...
- Android高级控件(三)—— 使用Google ZXing实现二维码的扫描和生成相关功能体系
Android高级控件(三)-- 使用Google ZXing实现二维码的扫描和生成相关功能体系 摘要 如今的二维码可谓是烂大街了.到处都是二维码.什么都是二维码,扫一扫似乎已经流行到习以为常了,今天 ...
- QRCode 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式
目录 功能介绍 常见问题 效果图与示例 apk Gradle 依赖 布局文件 自定义属性说明 接口说明 关于我 功能介绍 根据之前公司的产品需求,参考 barcodescanner 改的,希望能帮助到 ...
随机推荐
- vue的过渡动画在除了chrome浏览器外的浏览器下不正常的问题
为过渡动画添加mode="out-in"在其它浏览器下面就能正常的使用了
- Gcd(bzoj 2818)
Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...
- 计算机图形——OpenGL
荒废了太久,趁着"寒假"死磕了两周,验证了不少想法,解开了不少疑惑,代码质量当然是没有的,一切只为看到结果. 有空了再写每一项的细节. 源码地址 2019/5/12 更新 延迟渲染 ...
- SPOJ LIS2 - Another Longest Increasing Subsequence Problem(CDQ分治优化DP)
题目链接 LIS2 经典的三维偏序问题. 考虑$cdq$分治. 不过这题的顺序应该是 $cdq(l, mid)$ $solve(l, r)$ $cdq(mid+1, r)$ 因为有个$DP$. #i ...
- rostopic pub
rostopic pub -1 reinit_motor_wheel std_msgs/String -- "reinit_motor_wheel"rostopic pub -r ...
- HAXM 6.0.5显示不兼容Windows
HAXM 6.0.5显示不兼容Windows 最近更新Android后,用户会在Android Manager中发现,以前可以安装Intel x86模拟器现在不能安装了.提示错误信息如下:intel ...
- luogu P3119 [USACO15JAN]草鉴定Grass Cownoisseur
题目描述 In an effort to better manage the grazing patterns of his cows, Farmer John has installed one-w ...
- [NSThread sleepForTimeInterval:3.0];
在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)laun ...
- python为不同的对象如何分配内存的小知识
id方法的返回值就是对象的内存地址. python中会为每个出现的对象分配内存,哪怕他们的值完全相等(注意是相等不是相同).如执行a=2.0,b=2.0这两个语句时会先后为2.0这个Float类型对象 ...
- ubuntu 卸载干净软件(包括配置文件)
var/cache/apt/archives occupying huge space I am in the process of cleaning up my system. And I see ...