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

其实好多时候我们生活中都会使用到二维码,超市的买东西、商店的购物等。。。。。。做开发的过程中我们使用到二维码来进行扫描下载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();
             }
         }
     }
 }

下面看下效果图吧:


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


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


四、定制化显示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的二维码

生成带logo的二维码

哈哈哈哈,一切都结束了,下次再见~~~~吐舌头吐舌头吐舌头再见再见再见












猜你喜欢

转载自blog.csdn.net/tdltdltdl886/article/details/79817879