Android进阶之路 - zxing二维码扫描与生成

万年之前就想写篇文章记录一下二维码功能的实现,没想到一拖就到了现在,对了今天是周六 ~~~

现在网上有很多的关于扫码的三方库,当然这些都是基于zxing这个框架去扩展的,我这这里记录俩种方式,一种满足与基本需求,另外一种满足一些扩展性的需求,使用起来比使用zxing方便一些,毕竟进行了二次封装。

    • 提前注意 → 权限申请
    • 借鉴文章 → github地址
    • 所遇问题
      • 小米手机扫描二维码崩溃(权限问题)
    • 山寨 zxing (效果一般,识别速度→慢,识别率低,不支持自动放大扫描框,用不了的话就放弃),推荐星数:⭐⭐
      • 预先配置
        • 引入
        • 权限
      • 常用方法
        • ZxingConfig配置(看情况使用,如果只是满足基本功能,没必要理会)
        • 扫码方式
        • 生成二维码
      • 完整Demo代码
        • MainActivity
        • activity_main
    • android-zxingLibrary - 识别较快,满足基本需求;推荐星数:⭐⭐⭐
      • 预先配置
        • 引入
        • 权限
      • 使用方式
        • 1.当前类执行初始化操作
        • 2.在代码中执行打开扫描二维码界面操作
        • 3.重写onActivityResult方法接收扫描结果
      • 完整Demo代码
        • MainActivity
      • 自定义扫一扫界面
        • 原作者提醒
        • 本作者建议
        • 新建扫描类 ScanActivity
        • 扫描类布局 activity_scan
        • 修改打开方式的跳转类

提前注意 → 权限申请

如不申请权限,会导致app崩溃 ~
如懒得申请权限,通过手机应用设置手动开启权限~
如正常申请权限,优先采用下文的RxPermissions

  • Android6.0特性 - 动态权限的多样性处理方式

借鉴文章 → github地址

  • 山寨 zxing (1k Start)
  • android-zxingLibrary - 识别较快,满足基本需求 (4k Start)

所遇问题

小米手机扫描二维码崩溃(权限问题)

这个问题的解决方式并没有在原作者的github中看到,反倒是在他的博客中找到了属于我的答案~

  • 我的权限
	
	
    
    
    
    
  • 正确权限
	
	
	
    
    
    
    

山寨 zxing (效果一般,识别速度→慢,识别率低,不支持自动放大扫描框,用不了的话就放弃),推荐星数:⭐⭐

Effect

预先配置

引入

1.先在 build.gradle(Project:XXXX) 的 repositories 添加

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

2.然后在 build.gradle(Module:app) 的 dependencies 添加

compile 'com.github.yuzhiqiang1993:zxing:2.1.6'

权限

1.常规权限加入









2.针对6.0的动态权限需申请以下对应的权限

Manifest.permission.CAMERA
Manifest.permission.READ_EXTERNAL_STORAGE

常用方法

ZxingConfig配置(看情况使用,如果只是满足基本功能,没必要理会)

//ZxingConfig config = new ZxingConfig();
//config.setShowbottomLayout(true);//底部布局(包括闪光灯和相册)
//config.setPlayBeep(true);//是否播放提示音
//config.setShake(true);//是否震动
//config.setShowAlbum(true);//是否显示相册
//config.setShowFlashLight(true);//是否显示闪光灯

扫码方式

1.触发扫描事件

		//这里的config是原作者包装的一些属性
        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //如果不传 ZxingConfig的话,两行代码就能搞定了
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
//                intent.putExtra(Constant.INTENT_ZXING_CONFIG, config);
                startActivityForResult(intent, REQUEST_CODE_SCAN);
            }
        });

2.onActivityResult回调

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 扫描二维码/条码回传
        if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK) {
            if (data != null) {
                String content = data.getStringExtra(Constant.CODED_CONTENT);
                mContent.setText("扫描结果为:" + content);
            }
        }
    }

生成二维码

  //定义二维码数据
        final String data="我爱你,亲爱的姑娘";
        mCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (TextUtils.isEmpty(data)) {
                    Toast.makeText(MainActivity.this, "data不能为空", Toast.LENGTH_SHORT).show();
                    return;
                }
                Bitmap bitmap = null;
                try {
                    /**
                    * contentEtString:字符串内容
                    * w:图片的宽
                    * h:图片的高
                    * logo:不需要logo的话直接传null
                    * */
                    Bitmap logo = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
                    //logo设置为null,则二维码中心没有图片,大小可自己设置,至于显示位置,在自己的布局进行设置
                    bitmap = CodeCreator.createQRCode(data, 400, 400, null);
                    mIvCreate.setImageBitmap(bitmap);
                } catch (WriterException e) {
                    e.printStackTrace();
                }
            }
        });

完整Demo代码

MainActivity

package com.example.yongliu.zxing;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.WriterException;
import com.yzq.zxinglibrary.android.CaptureActivity;
import com.yzq.zxinglibrary.bean.ZxingConfig;
import com.yzq.zxinglibrary.common.Constant;
import com.yzq.zxinglibrary.encode.CodeCreator;

public class MainActivity extends AppCompatActivity {

    private int REQUEST_CODE_SCAN = 111;
    private TextView mContent;
    private TextView mCreate;
    private ImageView mIvCreate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView mBtn = findViewById(R.id.btn);
        mContent = findViewById(R.id.content);
        mCreate = findViewById(R.id.create);
        mIvCreate = findViewById(R.id.ic_create);

        final ZxingConfig config  = new ZxingConfig();
        config.setShowAlbum(false);
        config.setShowFlashLight(false);
        config.setShowbottomLayout(false);

        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //如果不传 ZxingConfig的话,两行代码就能搞定了
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
//                intent.putExtra(Constant.INTENT_ZXING_CONFIG, config);
                startActivityForResult(intent, REQUEST_CODE_SCAN);
            }
        });

        //定义二维码数据
        final String data="我爱你,亲爱的姑娘";
        mCreate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (TextUtils.isEmpty(data)) {
                    Toast.makeText(MainActivity.this, "data不能为空", Toast.LENGTH_SHORT).show();
                    return;
                }
                Bitmap bitmap = null;
                try {
                    /**
                    * contentEtString:字符串内容
                    * w:图片的宽
                    * h:图片的高
                    * logo:不需要logo的话直接传null
                    * */
                    Bitmap logo = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
                    //logo设置为null,则二维码中心没有图片,大小可自己设置,至于显示位置,在自己的布局进行设置
                    bitmap = CodeCreator.createQRCode(data, 400, 400, null);
                    mIvCreate.setImageBitmap(bitmap);
                } catch (WriterException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 扫描二维码/条码回传
        if (requestCode == REQUEST_CODE_SCAN && resultCode == RESULT_OK) {
            if (data != null) {
                String content = data.getStringExtra(Constant.CODED_CONTENT);
                mContent.setText("扫描结果为:" + content);
            }
        }
    }
}

activity_main




    

    

    

    

android-zxingLibrary - 识别较快,满足基本需求;推荐星数:⭐⭐⭐

预先配置

引入

build.gradle(app)

    implementation 'cn.yipianfengye.android:zxing-library:2.2'

权限

1.常规权限加入










2.针对6.0的动态权限需申请以下对应的权限

Manifest.permission.CAMERA
Manifest.permission.READ_EXTERNAL_STORAGE

使用方式

1.当前类执行初始化操作

@Override
    public void onCreate() {
        super.onCreate();
        ZXingLibrary.initDisplayOpinion(this);
 }

2.在代码中执行打开扫描二维码界面操作

		/**
         * 打开默认二维码扫描界面
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent, 1);
            }
        });

3.重写onActivityResult方法接收扫描结果

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        /**
         * 处理二维码扫描结果
         */
        if (requestCode == 1) {
            //处理扫描结果(在界面上显示)
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                    String result = bundle.getString(CodeUtils.RESULT_STRING);
                    Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                    mContent.setText(result);
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

完整Demo代码

MainActivity

package nkwl.com.scardemo;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.uuzuche.lib_zxing.activity.CaptureActivity;
import com.uuzuche.lib_zxing.activity.CodeUtils;
import com.uuzuche.lib_zxing.activity.ZXingLibrary;

public class MainActivity extends AppCompatActivity {

    private TextView mContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ZXingLibrary.initDisplayOpinion(this);

        mContent = findViewById(R.id.tv_content);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent, 1);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        /**
         * 处理二维码扫描结果
         */
        if (requestCode == 1) {
            //处理扫描结果(在界面上显示)
            if (null != data) {
                Bundle bundle = data.getExtras();
                if (bundle == null) {
                    return;
                }
                if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_SUCCESS) {
                    String result = bundle.getString(CodeUtils.RESULT_STRING);
                    Toast.makeText(this, "解析结果:" + result, Toast.LENGTH_LONG).show();
                    mContent.setText(result);
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}

自定义扫一扫界面

因原始的扫描界面并无返回按钮,用户体验方面可能说不过去,故在看完原作者处理方式之后,在这里总结下~

原作者提醒

  • 启动id为fl_my_container的FrameLayout就是我们需要替换的扫描组件
  • ctivity中执行Fragment的初始化操作(可copy)
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        /**
         * 执行扫面Fragment的初始化操作
         */
        CaptureFragment captureFragment = new CaptureFragment();
        // 为二维码扫描界面设置定制化界面
        CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera);
        
        captureFragment.setAnalyzeCallback(analyzeCallback);
        /**
         * 替换我们的扫描控件
         */ getSupportFragmentManager().beginTransaction().replace(R.id.fl_my_container, captureFragment).commit();
    }
  • analyzeCallback是我们定义的扫描回调函数(可copy)
/**
     * 二维码解析回调函数
     */
    CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
        @Override
        public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
            bundle.putString(CodeUtils.RESULT_STRING, result);
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }

        @Override
        public void onAnalyzeFailed() {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
            bundle.putString(CodeUtils.RESULT_STRING, "");
            resultIntent.putExtras(bundle);
            SecondActivity.this.setResult(RESULT_OK, resultIntent);
            SecondActivity.this.finish();
        }
    };

本作者建议

因有时候原作者描述的有点绕,这里我们直接看默认的 CaptureActivity

这里我们其实只需要 替换 setContentView(R.layout.我们自己的layout)布局为我们自己写的即可 ~

package com.uuzuche.lib_zxing.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.uuzuche.lib_zxing.R;

/**
 * Initial the camera
 * 

* 默认的二维码扫描Activity */ public class CaptureActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.camera); CaptureFragment captureFragment = new CaptureFragment(); captureFragment.setAnalyzeCallback(analyzeCallback); getSupportFragmentManager().beginTransaction().replace(R.id.fl_zxing_container, captureFragment).commit(); captureFragment.setCameraInitCallBack(new CaptureFragment.CameraInitCallBack() { @Override public void callBack(Exception e) { if (e == null) { } else { Log.e("TAG", "callBack: ", e); } } }); } /** * 二维码解析回调函数 */ CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() { @Override public void onAnalyzeSuccess(Bitmap mBitmap, String result) { Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS); bundle.putString(CodeUtils.RESULT_STRING, result); resultIntent.putExtras(bundle); CaptureActivity.this.setResult(RESULT_OK, resultIntent); CaptureActivity.this.finish(); } @Override public void onAnalyzeFailed() { Intent resultIntent = new Intent(); Bundle bundle = new Bundle(); bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED); bundle.putString(CodeUtils.RESULT_STRING, ""); resultIntent.putExtras(bundle); CaptureActivity.this.setResult(RESULT_OK, resultIntent); CaptureActivity.this.finish(); } }; }

新建扫描类 ScanActivity

package com.survey.ddchainclub.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.survey.ddchainclub.R;
import com.survey.ddchainclub.base.BaseActivity;
import com.uuzuche.lib_zxing.activity.CaptureFragment;
import com.uuzuche.lib_zxing.activity.CodeUtils;

import butterknife.ButterKnife;

/**
 * @author MrLiu
 * @date 2019/9/4
 * desc
 */
public class ScanActivity extends BaseActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);
        ButterKnife.inject(this);
        mToolBarHelper.setToolbarTitle("扫一扫");

        /**
         * 执行扫面Fragment的初始化操作
         */
        CaptureFragment captureFragment = new CaptureFragment();
        // 为二维码扫描界面设置定制化界面
        CodeUtils.setFragmentArgs(captureFragment, R.layout.my_camera);

        captureFragment.setAnalyzeCallback(analyzeCallback);
        /**
         * 替换我们的扫描控件
         */
        getSupportFragmentManager().beginTransaction().replace(R.id.fl_my_container, captureFragment).commit();
    }

    /**
     * 二维码解析回调函数
     */
    CodeUtils.AnalyzeCallback analyzeCallback = new CodeUtils.AnalyzeCallback() {
        @Override
        public void onAnalyzeSuccess(Bitmap mBitmap, String result) {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_SUCCESS);
            bundle.putString(CodeUtils.RESULT_STRING, result);
            resultIntent.putExtras(bundle);
            ScanActivity.this.setResult(RESULT_OK, resultIntent);
            ScanActivity.this.finish();
        }

        @Override
        public void onAnalyzeFailed() {
            Intent resultIntent = new Intent();
            Bundle bundle = new Bundle();
            bundle.putInt(CodeUtils.RESULT_TYPE, CodeUtils.RESULT_FAILED);
            bundle.putString(CodeUtils.RESULT_STRING, "");
            resultIntent.putExtras(bundle);
            ScanActivity.this.setResult(RESULT_OK, resultIntent);
            ScanActivity.this.finish();
        }
    };
}

扫描类布局 activity_scan




    


修改打开方式的跳转类

		/**
         * 打开默认二维码扫描界面
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//              Intent intent = new Intent(CurrencyActivity.this, CaptureActivity.class);
// 				修改跳转类,跳转到我们刚写的类内
                Intent intent = new Intent(CurrencyActivity.this, ScanActivity.class);
                startActivityForResult(intent, 1);
            }
        });

你可能感兴趣的:(Android进阶之路,#,三方框架)