Android 通过 ZXing 扫描二维码,生成二维码(无图/有图)

12 篇文章 0 订阅
8 篇文章 0 订阅

ZXing 是一个比较完善的与二维码相关的框架,里面有很多有趣的东西,现在我要实现的只是其中最基础的扫描二维码功能和生成二维码功能。

 

1、通过添加模块的方式将 ZXing 添加到项目中

2、使用  ZXing 实现想要的扫码和生成二维码功能

 

1、通过添加模块的方式将 ZXing 添加到项目中

添加方式为:

File > New > Import Module… 

然后选择要添加的模块

选中要添加的模块之后

这里我已经添加过了所以模块名字起冲突了

下面是添加好之后的项目目录

添加好之后需要进行简单的配置

第一步:在 settings.gradle 中添加 模块名称

第二步:File > Project Structurn… 进入依赖设置

选中项目(app) 选择 Dependencies 点击 + 号添加,选择 Module dependency,将里面的 zxinglib 添加到 app 的Dependencies 里面,如上图所示,这时就完成了 ZXing 模块添加

 

2、使用  ZXing 实现想要的扫码和生成二维码功能

效果

扫码(MP4转gif的,看起来有点卡)

生成

不多说,直接上代码

需要权限 AndroidManifest.xml (可能有些用不到)

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!-- unavailable in API 23 -->
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_sweepCode"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击扫码二维码" />

    <EditText
        android:id="@+id/tv_codeReturn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="数据"
        app:layout_constraintTop_toBottomOf="@+id/btn_sweepCode"/>

    <Button
        android:id="@+id/btn_generateCode"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击生成二维码"
        app:layout_constraintTop_toBottomOf="@+id/tv_codeReturn"/>

    <Button
        android:id="@+id/btn_generateCodeImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="点击有图生成二维码"
        app:layout_constraintTop_toBottomOf="@+id/btn_generateCode"/>

    <ImageView
        android:id="@+id/iv_code"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_generateCodeImage" />


</android.support.constraint.ConstraintLayout>

 

MainActivity

package com.example.zxing;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.zxing.utils.QRCodeUtil;
import com.skateboard.zxinglib.CaptureActivity;

public class MainActivity extends AppCompatActivity {

    private Button btn_sweepCode;
    private TextView tv_codeReturn;
    private Button btn_generateCode;
    private ImageView iv_code;
    private Button btn_generateCodeImage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();

        setPermissions();//动态权限

        //点击扫码
        btn_sweepCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent,1001);
            }
        });

        //点击生成普通二维码
        btn_generateCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String generateCode = tv_codeReturn.getText().toString();
                QRCodeUtil.createQRcodeImage(generateCode, iv_code);
            }
        });

        //点击生成中间带图片的二维码
        btn_generateCodeImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String generateCode = tv_codeReturn.getText().toString();
                QRCodeUtil.createQRcodeImage(MainActivity.this,generateCode, iv_code);
            }
        });
    }

    public void init(){
        btn_sweepCode = findViewById(R.id.btn_sweepCode);
        tv_codeReturn = findViewById(R.id.tv_codeReturn);
        btn_generateCode = findViewById(R.id.btn_generateCode);
        iv_code = findViewById(R.id.iv_code);
        btn_generateCodeImage = findViewById(R.id.btn_generateCodeImage);
    }

    /**
     * 动态权限申请(相机)
     */
    private void setPermissions() {
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
        else{
            Log.i("Jurisdiction","权限申请ok");
        }
    }

    //扫码回掉
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==1001 && resultCode== Activity.RESULT_OK) {
            String result = data.getStringExtra(CaptureActivity.KEY_DATA);
            tv_codeReturn.setText(result);//显示在输入框中
            Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        }
    }
}

 

QRCodeUtil (生成二维码的工具类)
package com.example.zxing.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.widget.ImageView;

import com.example.zxing.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import java.util.Hashtable;

public class QRCodeUtil {

    //无图
    public static void createQRcodeImage(String url, ImageView im1) {
        int w= im1.getWidth();
        int h= im1.getHeight();
        try {
            //判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, w, h, hints);
            int[] pixels = new int[w * h];
            //下面这里按照二维码的算法,逐个生成二维码的图片,
            //两个for循环是图片横列扫描的结果
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * w + x] = 0xff000000;
                    } else {
                        pixels[y * w + x] = 0xffffffff;
                    }
                }
            }
            //生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
            //显示到我们的ImageView上面
            im1.setImageBitmap(bitmap);
        }
        catch (WriterException e) {
            e.printStackTrace();
        }
    }

    //有图
    public static void createQRcodeImage(Context context, String url, ImageView im1) {
        int w= im1.getWidth();
        int h= im1.getHeight();
        try {
            //判断URL合法性
            if (url == null || "".equals(url) || url.length() < 1) {
                return;
            }
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            //图像数据转换,使用了矩阵转换
            BitMatrix bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, w, h, hints);
            int[] pixels = new int[w * h];
            //下面这里按照二维码的算法,逐个生成二维码的图片,
            //两个for循环是图片横列扫描的结果
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * w + x] = 0xff000000;
                    } else {
                        pixels[y * w + x] = 0xffffffff;
                    }
                }
            }
            //生成二维码图片的格式,使用ARGB_8888
            Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
            //显示到我们的ImageView上面s
            bitmap = addLogo(bitmap, BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher_round));
            im1.setImageBitmap(bitmap);
        }
        catch (WriterException e) {
            e.printStackTrace();
        }
    }

    //给二维码添加图片
    //第一个参数为原二维码,第二个参数为添加的logo
    private static Bitmap addLogo(Bitmap src, Bitmap logo) {
        //如果原二维码为空,返回空
        if (src ==null ) {
            return null;
        }
        //如果logo为空,返回原二维码
        if (src ==null ||logo ==null) {
            return src;
        }

        //这里得到原二维码bitmap的数据
        int srcWidth = src.getWidth();
        int srcHeight = src.getHeight();
        //logo的Width和Height
        int logoWidth = logo.getWidth();
        int logoHeight = logo.getHeight();

        //同样如果为空,返回空
        if (srcWidth == 0 || srcHeight == 0) {
            return null;
        }
        //同样logo大小为0,返回原二维码
        if (logoWidth == 0 || logoHeight == 0) {
            return src;
        }

        //logo大小为二维码整体大小的1/5,也可以自定义多大,越小越好
        //二维码有一定的纠错功能,中间图片越小,越容易纠错
        float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
        Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
        try {
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(src, 0, 0, null);
            canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
            canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2,null );

            canvas.save();
            canvas.restore();
        } catch (Exception e) {
            bitmap = null;
            e.getStackTrace();
        }

        return bitmap;
    }
}

 

最后,附上github链接 https://github.com/iscopy/ZXing  可以直接拷贝使用我项目中的 zxinglib 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值