(转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

Android项目实战(二十八):使用Zxing实现二维码及优化实例

作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21 我要评论

这篇文章主要介绍了Android项目实战(二十八):使用Zxing实现二维码及优化实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

前言:

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

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

这篇文章讲述:

1、如果快速在项目中集成zxing,实现扫描和生成二维码功能                 

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

一、快速集成zxing二维码

1、下载库文件 :http://xiazai.jb51.net/201611/yuanma/ZXingBarCode_jb51.zip ,

下载完成后可以看到:

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

  ①、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
2
3
4
5
< uses-permission android:name = "android.permission.CAMERA" />
   < uses-permission android:name = "android.permission.VIBRATE" />
   < uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
   < uses-permission android:name = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  < uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />

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

现在需求是一个主界面MainActivity.java 里面有两个按钮,分别跳转 生成二维码界面和 扫描二维码界面
然后分别开始写两个activity功能的实现:

①、 生成二维码

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

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

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

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

效果图:

②、扫描二维码

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private TextView zxing_content;
 
@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进行一些优化修改
 
}
 
/**
  * 扫一扫,成功后返回值进行判断
  */
@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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<? xml version = "1.0" encoding = "utf-8" ?>
< RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
   xmlns:tools = "http://schemas.android.com/tools"
   android:layout_width = "match_parent"
   android:layout_height = "match_parent"
   tools:context = "com.maiji.zxingdemo.ScanActivity" >
 
   < TextView
     android:id = "@+id/zxing_content"
     android:layout_width = "wrap_content"
     android:layout_height = "wrap_content"
     android:layout_centerInParent = "true"
     android:textSize = "30sp"
     />
</ RelativeLayout >

效果图:

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

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
2
3
4
private static final int MIN_FRAME_WIDTH = 240 ;
private static final int MIN_FRAME_HEIGHT = 240 ;
private static final int MAX_FRAME_WIDTH = 480 ;
private static final int MAX_FRAME_HEIGHT = 480 ;

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

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

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

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

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

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

这里是自定义扫描框的类

找到代码:

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

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
initFromCameraParameters方法中,在 Log.d(TAG, "Screen resolution: " + screenResolution);这句之后增加
Point screenResolutionForCamera = new Point();
screenResolutionForCamera.x = screenResolution.x;
screenResolutionForCamera.y = screenResolution.y;
     
if (screenResolution.x < screenResolution.y) {
screenResolutionForCamera.x = screenResolution.y;
screenResolutionForCamera.y = screenResolution.x;
  }

再将cameraResolution = getCameraResolution(parameters, screenResolution);更改为

?
1
cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

原文链接:http://www.cnblogs.com/xqxacm/p/6078729.html

如对本文有疑问,请提交到交流社区,广大热心网友会为你解答!!  点击进入社区

 
Tags: zxing  二维码

转载于:https://www.cnblogs.com/liupengfei005257/p/7448708.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值