Kotlin+Jecpack的CameraX+MLKit实现Android手机扫描二维码功能

前两篇文章介绍了使用Jetpack的CameraX库的基本使用方法。
传送门:
CameraX基本使用: https://www.jianshu.com/p/c1955529dd4c
CameraController更方便的使用 :https://www.jianshu.com/p/e2092b3ab531

之前在Android开发时扫描二维码都是用Camera+zxing库进行开发。但是现在发现使用CameraController+MLKit库进行二维码扫描更方便。

本篇文章是默认已经引入CameraX库的基础之上进行开发的。引入CameraX库的方法这里不再赘述。

其中MLKit库的使用方法是参照了这篇文章进行的修改:
https://juejin.cn/post/6950448798208376839 (来自 安和桥北的少年)

可以直接下载Demo:https://github.com/cgztzero/KotlinCameraXDemo

1.引入MLKit库

implementation 'com.google.mlkit:barcode-scanning:16.1.1'

2.重写图片分析器

class QRCodeAnalyser(private val listener: (List, Int, Int) -> Unit) :
    ImageAnalysis.Analyzer {
    //配置当前扫码格式
    private val options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(
            Barcode.FORMAT_QR_CODE,
            Barcode.FORMAT_AZTEC
        ).build()

    //获取解析器
    private val detector = BarcodeScanning.getClient(options)

    @SuppressLint("UnsafeExperimentalUsageError", "UnsafeOptInUsageError")
    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image ?: kotlin.run {
            imageProxy.close()
            return
        }
        val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
        detector.process(image)
            .addOnSuccessListener { barCodes ->
                Log.e("ztzt", "barCodes: ${barCodes.size}")
                if (barCodes.size > 0) {
                    listener.invoke(barCodes, imageProxy.width, imageProxy.height)
                    //接收到结果后,就关闭解析
                    detector.close()
                }
            }
            .addOnFailureListener { Log.e("ztzt", "Error: ${it.message}") }
            .addOnCompleteListener { imageProxy.close() }
    }
}

这里我们需要自己实现一个listener,在解析完二维码时返回数据,让我们自己做业务处理

3.CameraController设置ImageAnalysis.Analyzer

 lifecycleCameraController = LifecycleCameraController(this)
        lifecycleCameraController.bindToLifecycle(this)
        lifecycleCameraController.imageCaptureFlashMode = ImageCapture.FLASH_MODE_AUTO
        lifecycleCameraController.setImageAnalysisAnalyzer(
            cameraExecutor,
            QRCodeAnalyser { barcodes, imageWidth, imageHeight ->
                if (barcodes.isEmpty()) {
                    return@QRCodeAnalyser
                }
                initScale(imageWidth, imageHeight)
                val list = ArrayList()
                val strList = ArrayList()

                barcodes.forEach { barcode ->
                    barcode.boundingBox?.let { rect ->
                        val translateRect = translateRect(rect)
                        list.add(translateRect)
                        Log.e(
                            "ztzt", "left:${translateRect.left}  +" +
                                    "  top:${translateRect.top}  +  right:${translateRect.right}" +
                                    "  +  bottom:${translateRect.bottom}"
                        )
                        Log.e("ztzt", "barcode.rawValue:${barcode.rawValue}")
                        strList.add(barcode.rawValue ?: "No Value")
                    }
                }
                judgeIntent(strList)
                binding.scanView.setRectList(list)

            })
        binding.previewView.controller = lifecycleCameraController

注意:由于一个画面中可能有多个二维码,所以在监听中我们需要循环解析返回的barcode

最后Demo奉上:
https://github.com/cgztzero/KotlinCameraXDemo

写的不好,欢迎各位多多交流~

你可能感兴趣的:(Kotlin+Jecpack的CameraX+MLKit实现Android手机扫描二维码功能)