前言:

  多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意。

  当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的jar包,使用简化版的即可,下文可见。

  这篇文章讲述:1、如果快速在项目中集成zxing,实现扫描和生成二维码功能

         2、根据项目需求去修改源码实现我们的要求并进行优化

一、快速集成zxing二维码

1、下载库文件 : http://download.csdn.NET/detail/u013210620/9036083   ,文件名:BarCodeTest

   下载完成后可以看到:

  

  我们从这些文件中拷贝需要的到自己的项目中,下面开始:

  ①、res 目录下 : raw文件夹 整个复制到个人项目相对位置

  ②、res --> values目录下:ids.xml文件中的内容全部复制到个人项目相对位置,个人项目没有则直接复制文件到相对位置

  ③、res --> values目录下:colors.xml文件中的内容全部复制到个人项目的相对位置

  ④、res --> layout目录下:camera.xml 布局文件复制到个人项目相对位置

  ⑤、res --> drawable_mdpi 目录下:navbar.9.png图片复制到个人项目相对位置,这张图片是标题栏背景图片,这里建议先改成navbar.png 不要使用.9图片

  ⑥、libs目录下:zxing.jar文件复制到个人项目相对位置,并且右键点击as library

  ⑦、src --> com目录下:zxing 文件夹复制到个人项目相对位置 ,会报错,修改R的目录结构即可

  ⑧、AndroidManifest.xml文件中 添加 (二维码扫描activity,这个需要后面自己去修改,用于实现自己的要求)

  1. <activity android:name="com.zxing.activity.CaptureActivity"/>

  ⑨、AndroidManifest.xml文件中 添加权限

  1.   <uses-permission android:name="android.permission.CAMERA" />
  2. <uses-permission android:name="android.permission.VIBRATE" />
  3. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  4. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  5.   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2、准备工作完成了,下面开始写demo

  现在需求是一个主界面MainActivity.java 里面有两个按钮,分别跳转 生成二维码界面和 扫描二维码界面

  

  然后分别开始写两个activity功能的实现:

  ①、 生成二维码

    先写布局文件  ,一个图片 , 一个开始生成按钮 , 一个输入框(二维码需要根据文本信息生成,没有文本信息无法生成)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context="com.maiji.zxingdemo.CreateActivity">
  8.  
  9. <ImageView
  10. android:id="@+id/create_img"
  11. android:layout_width="300dp"
  12. android:layout_height="300dp"
  13. android:scaleType="fitXY"
  14. android:layout_gravity="center_horizontal"
  15. />
  16.  
  17. <Button
  18. android:id="@+id/create_btn"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_gravity="center_horizontal"
  22. android:text="开始生成二维码"
  23. />
  24.  
  25. <EditText
  26. android:id="@+id/create_edit"
  27. android:layout_width="match_parent"
  28. android:layout_height="wrap_content" />
  29. </LinearLayout>

activity_create.xml

    activity代码: 代码比较简单 ,不在此解释了

  1.   private ImageView create_img;
  2. private Button create_btn;
  3. private EditText create_edit;
  4.  
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_create);
  9.  
  10. initView();
  11. initEvent();
  12.  
  13. }
  14.  
  15. private void initEvent() {
  16. create_btn.setOnClickListener(this);
  17. }
  18.  
  19. private void initView() {
  20. create_img = (ImageView) findViewById(R.id.create_img);
  21. create_btn = (Button) findViewById(R.id.create_btn);
  22. create_edit = (EditText) findViewById(R.id.create_edit);
  23. }
  24.  
  25. @Override
  26. public void onClick(View v) {
  27. switch (v.getId()){
  28. case R.id.create_btn:
  29. String content = "" ;
  30. if (create_edit.getText().toString().equals("")){
  31. Toast.makeText(this,"请输入二维码信息",Toast.LENGTH_SHORT).show();
  32. return;
  33. }
  34. content = create_edit.getText().toString();
  35. try {
  36. //生成二维码图片,第一个参数是二维码的内容,第二个参数是正方形图片的边长,单位是像素
  37. Bitmap qrcodeBitmap = EncodingHandler.createQRCode(content, );
  38. if (qrcodeBitmap!=null) {
  39. create_img.setImageBitmap(qrcodeBitmap);
  40. }else{
  41. Toast.makeText(this,"生成二维码失败",Toast.LENGTH_SHORT).show();
  42. }
  43. } catch (Exception e) {
  44. // TODO Auto-generated catch block
  45. e.printStackTrace();
  46. }
  47. break;
  48. }
  49. }
  50.  
  51. public byte[] Bitmap2Bytes(Bitmap bm) {
  52. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  53. bm.compress(Bitmap.CompressFormat.PNG, , baos);
  54. return baos.toByteArray();
  55. }

  效果图:

         

 ②、扫描二维码

  这个就更简单了,只需要打开一个zxing提供的activity 然后获取到扫描得到的字符串即可

  看ScanActivity(扫描Activity)的关键代码

  1. private TextView zxing_content;
  2.  
  3. @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scan);
    zxing_content = (TextView) findViewById(R.id.zxing_content);
    Intent startScan = new Intent(this,CaptureActivity.class);
    startActivityForResult(startScan, 0); //实际打开了一个zxing提供给我们的扫描activity,当然我们后面会对这个activity进行一些优化修改
  4.  
  5. }
  6.  
  7. /**
    * 扫一扫,成功后返回值进行判断
    */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == -1) {
    String result = data.getExtras().getString("result");
    zxing_content.setText(result); //显示扫描二维码得到的数据
    }
    }

布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context="com.maiji.zxingdemo.ScanActivity">
  7.  
  8. <TextView
  9. android:id="@+id/zxing_content"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:layout_centerInParent="true"
  13. android:textSize="30sp"
  14. />
  15. </RelativeLayout>

activity_scan

效果图:

        

二、修改源码,实现项目的需求

1、修改扫描二维码的界面

  对应的是 zxing-->activity-->CaptureActivity.java   ,布局文件为 camera.xml

  所以修改界面只需要在 camera.xml文件中修改即可。

 无非就是把原来的“CANCEL”取消按钮去掉,把顶部的标题栏换一下。

  布局里面有一个 <SurfaceView>控件 用于显示相机拍出的画面预览,这里可以根据需求改是全界面显示还是显示局部

            <com.zxing.view.ViewfinderView>控件,即扫描框,默认的是宽高比1:1.5,实际需要修改宽高,在下面介绍

2、修改扫描框的宽高

 第1步操作做完之后会发现,我们没法修改扫描框的宽高。

 修改扫描框宽高很简单,找到 zxing-->camera-->CameraManager.java 文件

 这里较为顶部的代码中看到:

  

  1. private static final int MIN_FRAME_WIDTH = ;
  2. private static final int MIN_FRAME_HEIGHT = ;
  3. private static final int MAX_FRAME_WIDTH = ;
  4. private static final int MAX_FRAME_HEIGHT = ;

  这四个属性的值即扫描框的宽高,然后可以根据需求直接修改,当然这个值在不同分辨率的设备上宽高不一致 , 有需要的话可以进行一下单位转换

  

  1. public static int Dp2Px( Context context,float dp) {
  2. final float scale = context.getResources().getDisplayMetrics().density;
  3. return (int) (dp * scale + 0.5f);
  4. }

效果图: 我修改了扫描框的最小最大宽高分别一致,并且载camera.xml布局中删去了“CANCEL”取消按钮

  

3、给扫描框添加文字提示

  看一下微信的扫描界面,会发现扫描框下面有一段文字提示。 那么我们这里没有,需要添加

  找到zxing-->view-->Viewfinderview.java

  这里是自定义扫描框的类

  找到代码:

  

  1.     canvas.drawRect(frame.left + , middle - , frame.right - , middle + , paint);
  2.  
  3. Collection<ResultPoint> currentPossible = possibleResultPoints;

  在这两行代码之间我们画上文字提示

  1.     canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
  1.     TextPaint textPaint = new TextPaint();
  2. textPaint.setARGB(0xFF, 0xFF, 0xFF,0xFF); //字体颜色
  3. textPaint.setTextSize(32); //字体大小
  4. textPaint.setAntiAlias(true); //设置抗锯齿,否则字迹会很模糊
  5. StaticLayout layout = new StaticLayout("将二维码放入框内,即可自动扫描",textPaint,
  6. frame.right-frame.left, Layout.Alignment.ALIGN_NORMAL,1.0F,0.0F,true);
  7. canvas.translate(frame.left+5, (float) (frame.bottom + (float)30)); //绘制起始位置
  8. layout.draw(canvas);
  1.    Collection<ResultPoint> currentPossible = possibleResultPoints;

  然后在看下扫描界面效果图:

  

4、解决扫描界面相机预览拉伸变形问题

实现了上面几步的优化,仔细的同学可能会发现,如果我们给SurfaceView设置全屏显示(可以看到的相机画面很多),会发现相机拍摄出来的预览图有些拉伸变形

  原因:zxing横屏变竖屏之后,Camera的代码还是采用的横屏代码设置的参数

    优化方法:找到 zxing-->camera--> CameraConfigurationManager.java

  1. initFromCameraParameters方法中,
  2.  
  3. Log.d(TAG, "Screen resolution: " + screenResolution);这句之后增加
  4. Point screenResolutionForCamera = new Point();
  5. screenResolutionForCamera.x = screenResolution.x;
  6. screenResolutionForCamera.y = screenResolution.y;
  7.  
  8. if (screenResolution.x < screenResolution.y) {
  9. screenResolutionForCamera.x = screenResolution.y;
  10. screenResolutionForCamera.y = screenResolution.x;
  11. }
  12. 再将cameraResolution = getCameraResolution(parameters, screenResolution);
  13.  
  14. 更改为
  15.  
  16. cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);

 完成之后,在进行扫描操作,这时候相机拍出来的预览界面就正常显示,不再有拉伸变形问题。

 至此便给项目引入了一个可以使用的二维码模块功能了。

Android项目实战(二十八):Zxing二维码实现及优化的更多相关文章

  1. Android项目实战(十二):解决OOM的一种偷懒又有效的办法

    在程序的manifest文件的application节点加入android:largeHeap=“true” 即可. 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可 ...

  2. Android项目实战(十九):Android Studio 优秀插件: Parcelable Code Generator

    Android Studio 优秀插件系列: Android Studio 优秀插件(一):GsonFormat Android Studio 优秀插件(二): Parcelable Code Gen ...

  3. Android开发实战(十八):Android Studio 优秀插件:GsonFormat

    Android Studio 优秀插件系列: Android Studio 优秀插件(一):GsonFormat Android Studio 优秀插件(二): Parcelable Code Gen ...

  4. 【慕课网实战】Spark Streaming实时流处理项目实战笔记十八之铭文升级版

    铭文一级: 功能二:功能一+从搜索引擎引流过来的 HBase表设计create 'imooc_course_search_clickcount','info'rowkey设计:也是根据我们的业务需求来 ...

  5. Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件

    大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: .QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对于 ...

  6. Android项目实战(十四):TextView显示html样式的文字

    项目需求: TextView显示一段文字,格式为:(消息个数,不确定)条消息 这段文字中名字和数字的长度是不确定的,还要求名字和数字各自有各自的颜色. 一开始我想的是用(转) SpannableStr ...

  7. Android项目实战(十):自定义倒计时的TextView

    项目总结 -------------------------------------------------------------------------------------------- 有这 ...

  8. android 项目学习随笔十八(三级缓存)

    xUtils的BitmapUtils模块用的就是三级缓存,在项目中尽量还是应用BitmapUtils 三级缓存(机制) import com.itheima.zhsh66.R; import andr ...

  9. (二十八)golang--二维数组

    初始化: var array [2][3]int = [2][3]int{{0,0,0},{0,0,0}} var array [2][3]int = [...][3]int{{0,0,0},{0,0 ...

  10. Android项目实战(十五):自定义不可滑动的ListView和GridView

    不可滑动的ListView (RecyclweView类似) public class NoScrollListView extends ListView { public NoScrollListV ...

随机推荐

  1. Vue.js实现checkbox的全选和反选

    小颖之前写的代码存在一个bug,就是当你选择全选的时候去掉后面的一个选项,再点全选结果就是反的了.很感谢博客园的朋友帮我改了这个问题嘻嘻,下面一起来看看具体是怎么实现的吧. 1.html <te ...

  2. Openfire/XMPP学习之——一个简单的Smack样例

    昨天讲了Openfire的搭建和配置,今天来讲一下Smack.如果对如何搭建和配置Openfire的,可以参考Openfire/XMPP学习之——Openfire的安装.配置. Smack是一个开源, ...

  3. 【记录】VS2012新建MVC3/MVC4项目时,报:此模板尝试加载组件程序集“NuGet.VisualStudio.Interop...”

    最近电脑装了 VisualStudio "14" CTP,由于把其他版本的 VS 卸掉,由高到低版本安装,当时安装完 VisualStudio "14" CTP ...

  4. golang中的类和接口的使用

    类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: type People struct { //.. } func (p *People) SayHi() { fmt.Prin ...

  5. C# 将excel表格嵌入到Word中

    C# 将excel表格嵌入到Word中 继续开扒,今天要实现的是使用C#将excel表格嵌入到Word中这个功能,将word表格导入到excel中我已经写过了,如有需要可参考我之前的文章,在开始前还有 ...

  6. CentOS 7.2 yum方式安装MySQL 5.7

    CentOS 7之后的版本yum的默认源中使用MariaDB替代原先MySQL,因此安装方式较为以往有一些改变: 下载mysql的源 wget http://dev.mysql.com/get/mys ...

  7. ASP.NET或者 js方式实现文件夹多图片浏览的方式

    1.JS方式,限制大,而且图片名称如果不规则的话会获取不全. <html> <head> <style> img { max-width:1300px; } < ...

  8. 通过寄生组合式继承创建js的异常类

    最近项目中在做js的统一的异常处理,需要自定义异常类.理想的设计方案为:自定义一个异常错误类BaseError,继承自Error,然后再自定义若干个系统异常,例如用户取消异常.表单异常.网络异常,这些 ...

  9. SIFT特征详解

    1.SIFT概述 SIFT的全称是Scale Invariant Feature Transform,尺度不变特征变换,由加拿大教授David G.Lowe提出的.SIFT特征对旋转.尺度缩放.亮度变 ...

  10. Nancy之Forms authentication的简单使用

    一.前言 想必大家或多或少都听过微软推出的ASP.NET Identity技术,可以简单的认为就是一种授权的实现 很巧的是,Nancy中也有与之相类似的技术Authentication,这两者之间都用 ...