前两篇文章介绍了使用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<Barcode>, 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<RectF>()
val strList = ArrayList<String>()
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
写的不好,欢迎各位多多交流~