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

简介: 原文:Android项目实战(二十八):Zxing二维码实现及优化前言:   多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意。   当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的jar包,使用简化版的即可,下文可见。
原文: Android项目实战(二十八):Zxing二维码实现及优化

前言:

  多年之前接触过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,这个需要后面自己去修改,用于实现自己的要求)

 <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功能的实现:

  ①、 生成二维码 

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

<?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_create.xml

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

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

  

  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);

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

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

 

目录
相关文章
|
13天前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
|
17天前
|
缓存 监控 Android开发
构建高效Android应用:从优化用户体验到提升性能表现
【4月更文挑战第23天】 在竞争激烈的移动市场中,一个高效的Android应用是吸引并保留用户的关键。本文将探讨如何通过一系列技术手段和最佳实践来优化Android应用的用户体验和性能表现。我们将深入分析响应式UI设计、内存管理、多线程处理以及最新的Android框架特性,揭示它们如何共同作用以减少应用延迟,提高响应速度,并最终提升整体用户满意度。
|
19天前
|
缓存 API Android开发
Android 应用优化策略:提升性能与用户体验
【4月更文挑战第21天】在移动应用开发领域,性能优化是一个持续的挑战。尤其对于Android平台,由于设备多样性和系统版本的碎片化,开发者需要采取多种策略确保应用流畅运行并给用户带来良好体验。本文将深入探讨针对Android应用的性能优化技巧,包括内存管理、UI渲染效率提升、多线程应用以及电池寿命优化等方面。这些建议旨在帮助开发者诊断和改进现有应用,或在开发新项目时提前考虑到性能因素。
|
10天前
|
缓存 监控 API
Android应用性能优化实践
【4月更文挑战第30天】 随着智能手机的普及,用户对移动应用的性能要求越来越高。对于Android开发者而言,提升应用的性能是吸引和保留用户的关键因素之一。本文将深入探讨影响Android应用性能的主要因素,并提供一系列的优化策略,旨在帮助开发者构建更加流畅和高效的应用体验。
|
10天前
|
移动开发 调度 Android开发
构建高效Android应用:Kotlin协程的实践与优化
【4月更文挑战第30天】在移动开发领域,性能和响应性是衡量应用质量的关键指标。对于Android平台而言,Kotlin协程作为一种新兴的异步编程解决方案,提供了更为简洁和高效的处理并发任务的能力。本文将深入探讨Kotlin协程的核心原理,以及如何通过它们来提升Android应用的性能。我们将从基础概念出发,逐步介绍协程的创建、管理以及与Android UI线程的交互,并最终展示如何优化现有代码以利用协程的优势。
|
11天前
|
移动开发 数据库 Android开发
构建高效Android应用:探究Kotlin协程的优化实践
【4月更文挑战第29天】在移动开发领域,尤其是Android平台上,性能优化一直是开发者关注的重点。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的热门选择。其中,Kotlin协程作为一种轻量级的并发处理机制,为编写异步代码、网络请求和数据库操作提供了极大的便利。本文将深入探讨Kotlin协程在Android应用中的性能优化技巧,帮助开发者构建更加高效的应用程序。
|
12天前
|
移动开发 API Android开发
Android应用性能优化实战
【4月更文挑战第28天】在移动开发领域,一个流畅的用户体验是至关重要的。对于Android开发者而言,应用的性能优化是一项既挑战性也极其重要的工作。本文将深入探讨Android应用性能优化的多个方面,包括内存管理、UI渲染、多线程处理以及电池效率等,旨在为开发者提供实用的性能提升策略和具体的实施步骤。通过分析常见的性能瓶颈,并结合最新的Android系统特性和工具,我们的目标是帮助读者打造更加高效、响应迅速的Android应用。
|
13天前
|
缓存 监控 Android开发
Android 应用性能优化实战
【4月更文挑战第27天】 在竞争激烈的移动应用市场中,性能优越的应用更能吸引和保留用户。针对Android平台,本文将深入探讨影响应用性能的关键因素,并提供一系列实用的优化策略。我们将从内存管理、UI渲染、多线程处理以及电池使用效率等方面入手,通过具体案例分析如何诊断常见问题,并给出相应的解决方案。文中所提技巧旨在帮助开发者构建更加流畅、高效的Android应用。
24 2
|
16天前
|
移动开发 Java Android开发
构建高效Android应用:采用Kotlin协程优化网络请求
【4月更文挑战第24天】 在移动开发领域,尤其是对于Android平台而言,网络请求是一个不可或缺的功能。然而,随着用户对应用响应速度和稳定性要求的不断提高,传统的异步处理方式如回调地狱和RxJava已逐渐显示出局限性。本文将探讨如何利用Kotlin协程来简化异步代码,提升网络请求的效率和可读性。我们将深入分析协程的原理,并通过一个实际案例展示如何在Android应用中集成和优化网络请求。
|
18天前
|
Java 数据库 Android开发
构建高效Android应用:探究Kotlin协程的优化实践
【4月更文挑战第22天】 随着移动开发技术的不断进步,Android平台上的性能优化已成为开发者们关注的焦点。在众多优化手段中,Kotlin协程以其轻量级线程管理和异步编程的优势,为提高应用性能和响应性提供了新的思路。本文将深入探讨Kotlin协程在Android开发中的具体应用,通过实例演示如何利用协程进行网络请求、数据库操作和UI线程的非阻塞更新,以期达到提升应用性能的目的。
16 2