当前位置: 移动技术网 > IT编程>移动开发>Android > Android项目实战(二十八):使用Zxing实现二维码及优化实例

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

无锡车友会,炫耀墙,网页模版素材

前言:

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

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

这篇文章讲述:

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

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

一、快速集成zxing二维码

1、下载库文件 : ,

下载完成后可以看到:

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

  ①、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,这个需要后面自己去修改,用于实现自己的要求)

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

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

<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

<?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代码: 代码比较简单 ,不在此解释了

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)的关键代码

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); //显示扫描二维码得到的数据
  }
}

布局文件:

<?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 文件

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

 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;

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

 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

这里是自定义扫描框的类

找到代码:

 canvas.drawrect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);

   collection<resultpoint> currentpossible = possibleresultpoints;

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

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

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);更改为

cameraresolution = getcameraresolution(parameters, screenresolutionforcamera);

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

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网