欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android中Zxing二维码的扫描、生成(带有动态权限申请)

程序员文章站 2022-07-14 18:05:57
...

其实好多时候我们生活中都会使用到二维码,超市的买东西、商店的购物等。。。。。。做开发的过程中我们使用到二维码来进行扫描下载app,下面我来给大家介绍一下如何使用吧!!!

这是我看的大神的github:https://github.com/yipianfengye/android-zxingLibrary

一、添加model依赖

在module的build.gradle中执行compile操作

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

二、初始化Application

在demo中新建一个application执行初始化操作

@Override
    public void onCreate() {
        super.onCreate();

        ZXingLibrary.initDisplayOpinion(this);
    }

三、打开默认二维码界面

先看下activity_main代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/activity_main"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <Button
        android:id="@+id/mBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开二维码扫描界面"
        />

</RelativeLayout>

MainActivity代码如下:

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

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

这里的REQUEST_CODE是我们定义的int型常量。

在Activity的onActivityResult方法中接收扫描结果

/**
         * 处理二维码扫描结果
         */
        if (requestCode == REQUEST_CODE) {
            //处理扫描结果(在界面上显示)
            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();
                } else if (bundle.getInt(CodeUtils.RESULT_TYPE) == CodeUtils.RESULT_FAILED) {
                    Toast.makeText(MainActivity.this, "解析二维码失败", Toast.LENGTH_LONG).show();
                }
            }
        }

三、添加动态权限

首先需要判断下版本号是大于还是小于23,(大于6.0或小于6.0)就需要做权限申请

//首先判断用户手机的版本号 如果版本大于6.0就需要动态申请权限
//如果版本小于6.0就直接去扫描二维码
if(Build.VERSION.SDK_INT<23){
    //说明是android6.0之前的
    Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
    //第二个参数是请求码
    startActivityForResult(intent, REQUEST_CODE);
}else {
    //添加动态权限申请
    //1.定义一个数组,用来装载申请的权限
    String[] permissons={
                   Manifest.permission.READ_EXTERNAL_STORAGE,
                   Manifest.permission.WRITE_EXTERNAL_STORAGE,
                   Manifest.permission.CAMERA,
                   Manifest.permission.VIBRATE
    };
    //2.判断这些权限有没有申请,没有申请的话,就把没有申请的权限放到一个数组里面
    ArrayList<String> deniedPermissions=new ArrayList<String>();
    for(String permission:permissons){
        int i = ContextCompat.checkSelfPermission(this, permission);
        if(PackageManager.PERMISSION_DENIED==i){
            //说明权限没有被申请
            deniedPermissions.add(permission);

        }
    }
    if(deniedPermissions.size()==0){
        return;
    }
    //当你不知道数组多大的时候,就可以先创建一个集合,然后调用集合的toArray方法需要传递一个数组参数,这个数组参数的长度
    //设置成跟集合一样的长度
    String[] strings = deniedPermissions.toArray(new String[permissons.length]);
    //3.去申请权限
    ActivityCompat.requestPermissions(MainActivity.this,strings,REQUEST_ERWERMA_CODE);
}
//4.去检查有没有申请成功


 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
     super.onRequestPermissionsResult(requestCode, permissions, grantResults);
     if(requestCode==REQUEST_ERWERMA_CODE){
         //说明是我们为二维码申请的权限的回调
         for(int i=0;i<grantResults.length;i++){
             if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
                 //说明申请成功了
                 Toast.makeText(this, permissions[i]+"申请成功了", Toast.LENGTH_SHORT).show();
                 Intent intent = new Intent(MainActivity.this, CaptureActivity.class);
                 //第二个参数是请求码
                 startActivityForResult(intent, REQUEST_CODE);
             }else {
                 Toast.makeText(this, permissions[i]+"没有申请成功,请检查下次通过该权限", Toast.LENGTH_SHORT).show();
             }
         }
     }
 }

下面看下效果图吧:

Android中Zxing二维码的扫描、生成(带有动态权限申请)

打开默认的二维码扫描页面

Android中Zxing二维码的扫描、生成(带有动态权限申请)

扫描成功时就会弹出吐司哈~~~

Android中Zxing二维码的扫描、生成(带有动态权限申请)

四、定制化显示UI

由于我们的扫描组件是通过Fragment实现的,所以能够很轻松的实现扫描UI的定制化

在新的Activity中定义Layout布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_second"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/second_button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="取消"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginBottom="10dp"
        android:layout_gravity="bottom|center_horizontal"
        />

    <FrameLayout
        android:id="@+id/fl_my_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></FrameLayout>

</FrameLayout>

启动id为fl_my_container的FrameLayout就是我们需要替换的扫描组件,也就是说我们会将我们定义的扫描Fragment替换到id为fl_my_container的FrameLayout的位置。而上面的button是我们添加的一个额外的控件,在这里你可以添加任意的控件,各种UI效果等。具体可以看下面在Activity的初始化过程。

在Activity中执行Fragment的初始化操作

@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是我们定义的扫描回调函数,其具体的定义:

/**
     * 二维码解析回调函数
     */
    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();
        }
    };

仔细看的话,你会发现我们调用了CondeUtils.setFragmentArgs方法,该方法主要用于修改扫描界面扫描框与透明框相对位置的,与若不调用的话,其会显示默认的组件效果,而如果调用该方法的话,可以修改扫描框与透明框的相对位置等UI效果,我们可以看一下my_camera布局文件的实现.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SurfaceView
        android:id="@+id/preview_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <com.uuzuche.lib_zxing.view.ViewfinderView
        android:id="@+id/viewfinder_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:inner_width="200dp"
        app:inner_height="200dp"
        app:inner_margintop="150dp"
        app:inner_corner_color="@color/scan_corner_color"
        app:inner_corner_length="30dp"
        app:inner_corner_width="5dp"
        app:inner_scan_bitmap="@drawable/scan_image"
        app:inner_scan_speed="10"
        app:inner_scan_iscircle="false"
        />

</FrameLayout>

上面我们自定义的扫描控件的布局文件

五、生成默认的、带logo的二维码

先看activity_third代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true">

    <EditText
        android:id="@+id/edit_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minLines="3"
        android:layout_marginTop="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginLeft="20dp"
        />

    <Button
        android:id="@+id/button_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:layout_below="@+id/edit_content"
        android:text="生成logo二维码图片"
        />

    <Button
        android:id="@+id/button1_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="20dp"
        android:layout_below="@+id/button_content"
        android:text="生成普通二维码图片"
        />

    <ImageView
        android:id="@+id/image_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        />

</RelativeLayout>

生成不带logo的二维码图片

/**
         * 生成不带logo的二维码图片
         */
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String textContent = editText.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                editText.setText("");
                mBitmap = CodeUtils.createImage(textContent, 400, 400, null);
                imageView.setImageBitmap(mBitmap);
            }
        });

生成带Logo的二维码图片:

/**
         * 生成二维码图片
         */
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String textContent = editText.getText().toString();
                if (TextUtils.isEmpty(textContent)) {
                    Toast.makeText(ThreeActivity.this, "您的输入为空!", Toast.LENGTH_SHORT).show();
                    return;
                }
                editText.setText("");
                mBitmap = CodeUtils.createImage(textContent, 400, 400, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
                imageView.setImageBitmap(mBitmap);
            }
        });

下面来看下效果图吧哈哈哈~~~

默认的不带logo的二维码

Android中Zxing二维码的扫描、生成(带有动态权限申请)

生成带logo的二维码

Android中Zxing二维码的扫描、生成(带有动态权限申请)

哈哈哈哈,一切都结束了,下次再见~~~~Android中Zxing二维码的扫描、生成(带有动态权限申请)Android中Zxing二维码的扫描、生成(带有动态权限申请)Android中Zxing二维码的扫描、生成(带有动态权限申请)Android中Zxing二维码的扫描、生成(带有动态权限申请)Android中Zxing二维码的扫描、生成(带有动态权限申请)Android中Zxing二维码的扫描、生成(带有动态权限申请)