Android中如何使用YXing集成库(生成二维码、扫描二维码)

YXing原Github地址:GitHub - amggg/YXing

YXing 集成了CameraX + zxing,减少了冗余的代码,使用起来很方便,可惜文档写的不是很清晰,特地写一篇文章来分享一下容易遇到的问题。

使用前准备

1.在setting.gradle中的dependencyResolutionManagement中添加jitpack依赖。

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

2.在build.gradle中的dependencies中添加YXing库。

implementation 'com.github.amggg:YXing:V2.0.1'

3.在AndroidManifast.xml中向系统申请摄像头权限。

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

扫码

向用户申请使用摄像头的权限

新建Permission.java

package com.example.signapp.ui.scan;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;




//用于授权相机权限
public class Permission {
    public static final int REQUEST_CODE = 5;
    //定义三个权限
    private static final String[] permission = new String[]{
            Manifest.permission.CAMERA,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };
    //每个权限是否已授
    public static boolean isPermissionGranted(Activity activity){
        if(Build.VERSION.SDK_INT >= 23){
            for(int i = 0; i < permission.length;i++) {
                int checkPermission = ContextCompat.checkSelfPermission(activity,permission[i]);
                /***
                 * checkPermission返回两个值
                 * 有权限: PackageManager.PERMISSION_GRANTED
                 * 无权限: PackageManager.PERMISSION_DENIED
                 */
                if(checkPermission != PackageManager.PERMISSION_GRANTED){
                    return false;
                }
            }
            return true;
        }else{
            return true;
        }
    }

    public static boolean checkPermission(Activity activity){
        if(isPermissionGranted(activity)) {
            return true;
        } else {
            //如果没有设置过权限许可,则弹出系统的授权窗口
            ActivityCompat.requestPermissions(activity,permission,REQUEST_CODE);
            return false;
        }
    }
}

之后直接在onCreate或onCreateView中调用checkPermission(Activity activity)方法即可。

@Override
public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_scan, container, false);
        

        appCompatActivity = (AppCompatActivity) getActivity();

        Permission.checkPermission(appCompatActivity);

}


//在授权的activity或fragment中可以重写这个方法,如果用户拒绝授权就退出应用
@Override
public void onRequestPermissionsResult(
        int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == Permission.REQUEST_CODE) {
        for (int grantResult : grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                Log.e("Permission","授权失败!");
                // 授权失败,退出应用
                appCompatActivity.finish();
                return;
            }
        }
    }
}

调用打开扫码界面

接着在对应的点击事件中打开扫码界面,一些具体的参数可以参考文档:Yxing集成文档

appCompatActivity = (AppCompatActivity) getActivity();
ScanFragment = getParentFragment();

@Override
            public void onClick(View v) {
              
                    //如果是在activity中调用就不用加fragment参数了
                    ScanCodeConfig.create(appCompatActivity,ScanFragment )
                            .setStyle(ScanStyle.WECHAT )
                            .setPlayAudio(false)
                            .setShowFrame(true)
                            .buidler()
                            .start(ScanCodeActivity.class);
                    
}

 接收二维码中带的数据

接受数据很大一部分都是为了去发送Http请求,但我这里的需求比较简单,只需要获取码里的信息就好了。关于Android怎么给后端发请求我会再出一篇文章。

如果是在fragment中打开的扫码界面,信息最终还是会返回到fragment所在的activity中去,所以在activity中重写onActivityResult。

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && data != null) {
            

            //接收扫码结果
            Bundle extras = data.getExtras();
            //扫到码的类型
            int codeType = extras.getInt(ScanCodeConfig.CODE_TYPE);
            //码中的数据
            QRCodeValue = extras.getString(ScanCodeConfig.CODE_KEY);
}
}

生成二维码

生成二维码比较简单

bitmap = ScanCodeConfig.createQRCode(dateString);
imageView.setImageBitmap(bitmap);

这里要说的是一个比较有意思的需求:二维码要求每五秒刷新一次,同时还要携带时间等信息。

        思路比较简单就是每五秒获取一次时间戳,转化为字符串生成二维码。我在做的时候遇到的问题是关于UI线程的问题,正常一个activity只有一个线程就是UI线程,如果你直接在UI线程中做这个生成二维码的操作就会导致UI不能刷新,甚至app也会崩溃,所以需要新建线程来执行这些费时操作,同时更新二维码图标的操作通过handler用post方法给Runnable推到UI线程中去。

//在onCreate中获取主线程
handler = new Handler(); 




//当点击开始生成二维码时
        @Override
        public void onClick(View v) {
            
        //通过thread_stop来决定循环什么时候结束,如果直接使用thread的stop方法的话很不安全
            thread_stop = true;
            starDate = new Date();

            //5秒刷新一次
            final long timeInterval = 5000;

            imageView.setVisibility(View.VISIBLE);
            

            //新建线程用于生成二维码并更新UI
            Thread t  = new Thread() {


                @Override
                public void run() {

                    while (thread_stop ){


                        Date date = new Date();
                        

                        String dateString = date.toString();
                        bitmap = ScanCodeConfig.createQRCode(dateString);
                        handler.post(runnable);

                        try {
                            sleep(timeInterval);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                    }

                    if(!thread_stop){
                        handler.post(UIrun);
                    }

                }

            };
            t.start();



 //手动结束线程的方法
        public void stopThread() {
            thread_stop = false;
            Log.d("Thread","ThreadStop");
        }



//更新二维码
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            imageView.setImageBitmap(bitmap);
        }
    };

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值