首页 > 其他分享 >android 二维码扫描的逻辑

android 二维码扫描的逻辑

时间:2024-09-04 18:15:28浏览次数:5  
标签:Log fragment void 扫描 二维码 TAG android public

用的是ZXing库

依赖有

//二维码依赖(ZXing库)
    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'

 


1.建立一个二维码扫描的工具类(QrCodeScanner)

里面的逻辑有

  • 可以根据不同的标识符处理不同的扫描出来的结果
  • 权限的处理
public class QrCodeScanner {

    private static final int CAMERA_REQUEST_CODE = 100;  // 相机权限请求码
    private static final String TAG = "QrCodeScanner";  // 日志标签
    private final Fragment fragment;  // 用于启动扫描的Fragment
    private final String identifier;  // 标识符,用于区分不同的扫描请求
    private final ScanResultCallback callback;  // 扫描结果回调接口

    // 扫描结果回调接口,用于处理扫描结果
    public interface ScanResultCallback {
        void onScanResult(String msg);
    }

    // 构造函数,初始化Fragment、标识符和回调接口
    public QrCodeScanner(Fragment fragment, String identifier, ScanResultCallback callback) {
        this.fragment = fragment;
        this.identifier = identifier;
        this.callback = callback;
    }

    // 启动二维码扫描
    public void startScan() {
        Log.d(TAG, "startScan: Initiating scan");
        // 检查相机权限
        if (ContextCompat.checkSelfPermission(fragment.requireContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "startScan: Camera permission not granted, requesting permission");
            // 如果没有权限,请求相机权限
            fragment.requestPermissions(new String[]{android.Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
        } else {
            // 已有权限,启动二维码扫描
            Log.d(TAG, "startScan: Camera permission granted, starting scan");
            initiateScan();
        }
    }

    // 实际启动扫描的方法
    private void initiateScan() {
        Log.d(TAG, "initiateScan: Starting QR code scan");
        Intent intent = new Intent(fragment.getActivity(), CustomCaptureActivity.class);
        fragment.startActivityForResult(intent, CAMERA_REQUEST_CODE);
    }

    // 处理权限请求结果
    public void handlePermissionsResult(int requestCode, @NonNull int[] grantResults) {
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "handlePermissionsResult: Camera permission granted, starting scan");
                initiateScan();  // 如果权限被授予,启动扫描
            } else {
                Log.d(TAG, "handlePermissionsResult: Camera permission denied");
                Toast.makeText(fragment.getContext(), "相机权限被拒绝,无法进行二维码扫描", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 处理扫描结果
    public void handleScanResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
            String scannedText = data.getStringExtra("SCANNED_TEXT");
            Log.d(TAG, "handleScanResult: Scanned text = " + scannedText);
            handleScannedResult(scannedText);
        } else {
            Log.d(TAG, "handleScanResult: Scan failed or cancelled");
            Toast.makeText(fragment.getContext(), "扫描失败或已取消", Toast.LENGTH_SHORT).show();
        }
    }

    // 根据不同的标识符处理扫描结果
    private void handleScannedResult(String scannedText) {
        if ("com/example/bighealth/mine/family".equals(identifier)) {
            Log.d(TAG, "handleScannedResult: Processing result for family identifier");
            // 将扫描结果传递给 FamilyActivity
            Intent intent = new Intent(fragment.getActivity(), FamilyActivity.class);
            intent.putExtra("scannedContent", scannedText);
            fragment.getActivity().startActivity(intent);
        } else {
            Log.d(TAG, "handleScannedResult: Unhandled identifier: " + identifier);
            if (callback != null) {
                callback.onScanResult(scannedText);
            }
        }
    }
}

2.建立一个CustomCaptureActivity(用来自定义扫描界面和解码)

这里我搞了个扫描线,和四角的框。

扫描的线我的逻辑是搞了一个正方形的框,扫描的线就在这个正方形里面移动,因为我还能获取到实际扫描框的大小,只能这样曲线救国了

public class CustomCaptureActivity extends Activity {

    private static final String TAG = "CustomCaptureActivity"; // 日志标签
    private CaptureManager capture;
    private CustomDecoratedBarcodeView barcodeScannerView;
    private ImageView scannerLine;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.zxing_custom_capture);  // 使用自定义的布局

        // 初始化BarcodeScannerView和扫描线
        barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);  // 使用自定义的DecoratedBarcodeView
        scannerLine = findViewById(R.id.scanner_line);

        // 启动扫描线动画
        startScannerAnimation();

        // 初始化CaptureManager
        Log.d(TAG, "Initializing CaptureManager...");
        capture = new CaptureManager(this, barcodeScannerView);

        // 从Intent中初始化并启动解码
        Log.d(TAG, "Initializing from intent...");
        capture.initializeFromIntent(getIntent(), savedInstanceState);

        Log.d(TAG, "Starting QR code decode...");
        capture.decode();

        // 设置解码回调
        barcodeScannerView.decodeContinuous(new BarcodeCallback() {
            @Override
            public void barcodeResult(BarcodeResult result) {
                if (result != null) {
                    String scannedText = result.getText();
                    Log.d(TAG, "Scanned text: " + scannedText);

                    // 返回扫描结果
                    Intent resultIntent = new Intent();
                    resultIntent.putExtra("SCANNED_TEXT", scannedText);
                    setResult(Activity.RESULT_OK, resultIntent);
                    finish();  // 关闭活动
                }
            }

            @Override
            public void possibleResultPoints(List<ResultPoint> resultPoints) {
                // 可以处理可能的结果点
            }
        });
    }

    private void startScannerAnimation() {
        if (scannerLine != null) {
            View scannerFrame = findViewById(R.id.scanner_frame);
            int frameHeight = scannerFrame.getLayoutParams().height;

            TranslateAnimation animation = new TranslateAnimation(
                    0, 0, // x从0到0
                    0, frameHeight); // y从0到frameHeight
            animation.setDuration(2000); // 动画持续时间2秒
            animation.setRepeatCount(Animation.INFINITE); // 无限循环
            animation.setRepeatMode(Animation.REVERSE); // 动画反向播放
            scannerLine.startAnimation(animation); // 启动动画
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "Resuming CaptureManager...");
        capture.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "Pausing CaptureManager...");
        capture.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Destroying CaptureManager...");
        capture.onDestroy();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        Log.d(TAG, "Handling permissions result...");
        capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.d(TAG, "Handling key down event: " + keyCode);
        return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }
}

上面的代码用的是下面这个自定义布局

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

    <!-- 使用自定义的 CustomDecoratedBarcodeView -->
    <com.example.bighealth.customView.CustomDecoratedBarcodeView
        android:id="@+id/zxing_barcode_scanner"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!-- 自定义扫描框 (正方形) -->
    <RelativeLayout
        android:id="@+id/scanner_frame"
        android:layout_width="310dp"
        android:layout_height="250dp"
        android:layout_gravity="center"
        android:background="@android:color/transparent">

        <!-- 自定义扫描线 -->
        <ImageView
            android:id="@+id/scanner_line"
            android:layout_width="match_parent"
            android:layout_height="4dp"
            android:background="#E8B66C"
            android:layout_alignParentTop="true" />
    </RelativeLayout>

</FrameLayout>

3.工具都做好了,接下来就是怎么用

  // 初始化二维码扫描器,传入标识符"family"
        qrCodeScanner = new QrCodeScanner(this, "com/example/bighealth/mine/family", new QrCodeScanner.ScanResultCallback() {
            @Override
            public void onScanResult(String msg) {
                // 将服务器返回的msg内容打印到日志中
                Log.d(TAG, "服务器返回的消息: " + msg);
                scannedQrCodeContent = msg;
                fetchUserData(scannedQrCodeContent);
                Log.d(TAG, "fetchUserData 方法被调用");
            }
        });

 

标签:Log,fragment,void,扫描,二维码,TAG,android,public
From: https://www.cnblogs.com/lachesism/p/18397091

相关文章

  • 在Android中发送网络请求(post和get的区别)
    get//将参数附加到URLStringurlWithParams=HttpConfig.GET_USER_NAME+"?qrCodeContent="+msg;//构建请求Requestrequest=newRequest.Builder().url(urlWithParams).addHeader("Authorization&q......
  • mac 上golang编译 安卓系统的so 错误 'android/log.h' file not found
    lib.gopackagemainimport"C"//exportSpeedTestfuncSpeedTest(config*C.char){ configContent:=C.GoString(config) run(configContent)}funcmain(){}需要安装NDK,用Androidstudio安装,在SDKManeger的SDKTool里选择安装NDK(sidebyside),成功后一般在......
  • Android 12.0 wifi设置静态ip功能实现
    1.前言在12.0的系统rom定制化开发中,在某些功能开发中,在wifi模块中,有产品需要要求设置wifi静态ip功能,而系统中wifi连接后ip是动态的,每次开机后连接wifi的ip就是不固定的,所以产品需要采用固定ip,就需要实现静态ip功能2.wifi设置静态ip功能实现的核心类frameworks\base\wifi\ja......
  • 移动端Android跟ios兼容性问题,反人类!!!
    一、查询参数编码问题我们在日常开发中,有时候会遇到拼接参数特别多的情况,那么就会导致一行代码特别长。那么为了美观呢,有的同学会进行换行处理,如下代码:可以看到我红色框出来的地方就是经过了手动的回车导致产生的回车换行符。这么做乍一看也挺正常是吧,但其实对于JavaScript来说......
  • Android终端如何快速接入GB28181平台实现实时音视频回传
    技术背景GB28181是由中国国家标准委员会发布的基于IP网络的安防视频监控标准。Android平台GB28181设备对接模块,主要涉及到视频监控领域,可实现不具备国标音视频能力的Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如执法记录仪、智能安全帽、智能监控、智慧零售、......
  • Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点SpannableString在Android开发中是一个非常强大的工具,它允许你在单个字符串范围内应用多种样式。使用SpannableString,你可以为文本中的不同部分设置不同颜色,字体大小,字体......
  • 2-STM32F103+ML307(中移4G Cat1)基本控制篇(自建物联网平台)-整体运行测试-Android扫
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/ML307/my.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  说明这节测试一......
  • android java BufferedWriter writer 需要关闭资源吗?
    在Android开发中,使用Java的`BufferedWriter`或其他类似的I/O资源时,**确实需要关闭资源**。这是因为:1.**释放系统资源**:关闭`BufferedWriter`会释放与之关联的底层资源,如文件句柄。2.**保证数据完整性**:确保所有写入操作完成并刷新缓冲区,这样数据才能被完整地写入到文件中。......
  • Android开机流程-从Init进程启动到进入Android桌面
    1.init进程启动流程Androidbootloader负责加载boot.img,将其内容放入内存,然后启动内核。内核接管之后,会解压并加载ramdisk到内存中,然后启动用户空间的第一个进程init。在Android系统启动过程中,ramdisk.img被内核直接解压到内存中并用作初始根文件系统。这一过程不是通过......
  • Android使用addr2line分析Native Crash
    NDK提供的工具将函数地址解析为具体的函数名和行数才能进一步分析问题。常用的地址转换工具有addr2line、ndk-stack等,个人比较喜欢addr2line,所以接下来介绍下该工具的基本使用方式日常使用过程中,只需要关注-C-f-e三个参数即可//-C:Demangle函数名//-f:显示函数名//......