I created a sample application that uses Google MLKit to scan barcode using CameraX api. I am able to scan barcode. But the scanning is very fast and when there are multiple barcodes to be scanned (example if there are multiple barcodes at same position) the scanner scan single barcode multiple times and then proceeds to next barcode.
What I am trying is my layout contains a Preview and TextView where the scanned barcode is updated to TextView. The updation on TextView is so fast that I can't see the value of barcode scanned. Is there a way can I pause for some seconds and then start scanning or else if the same barcode is scanned multiple times can we try skipping updating TextView with that value?
I will share my code below and please help me in resolving this issue?
private fun bindCameraUseCases() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
// setting up the preview use case
val previewUseCase = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
val options = BarcodeScannerOptions.Builder()
.enableAllPotentialBarcodes()
.build()
val scanner = BarcodeScanning.getClient(options)
// setting up the analysis use case
val analysisUseCase = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
val cameraExecutor = Executors.newSingleThreadExecutor()
analysisUseCase.setAnalyzer(
Executors.newSingleThreadExecutor()
) { imageProxy ->
processImageProxy(scanner, imageProxy)
}
// configure to use the back camera
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
cameraProvider.bindToLifecycle(
this,
cameraSelector,
previewUseCase,
analysisUseCase)
} catch (illegalStateException: IllegalStateException) {
// If the use case has already been bound to another lifecycle or method is not called on main thread.
Log.e("MainActivity", illegalStateException.message.orEmpty())
} catch (illegalArgumentException: IllegalArgumentException) {
// If the provided camera selector is unable to resolve a camera to be used for the given use cases.
Log.e("MainActivity", illegalArgumentException.message.orEmpty())
}
}, ContextCompat.getMainExecutor(this))
}
Image Processing and value is updated to TextView in the below method:
@SuppressLint("UnsafeOptInUsageError")
private fun processImageProxy(
barcodeScanner: BarcodeScanner,
imageProxy: ImageProxy
) {
imageProxy.image?.let { image ->
val inputImage =
InputImage.fromMediaImage(
image,
imageProxy.imageInfo.rotationDegrees
)
barcodeScanner.process(inputImage)
.addOnSuccessListener { barcodeList ->
val barcode = barcodeList.getOrNull(0)
// `rawValue` is the decoded value of the barcode
**if (lastScannedBarcodeValue != barcode?.rawValue) {
barcode?.rawValue?.let { value ->
barCodeResult.text = value
}
}**
}
.addOnFailureListener {
// This failure will happen if the barcode scanning model
// fails to download from Google Play Services
Log.e("MainActivity", it.message.orEmpty())
}.addOnCompleteListener {
// When the image is from CameraX analysis use case, must
// call image.close() on received images when finished
// using them. Otherwise, new images may not be received
// or the camera may stall.
imageProxy.image?.close()
imageProxy.close()
}
}
}
I am updating to TextView in addSuccess()... block.
Please help me in resolving this issue?
// Camera API
implementation("androidx.camera:camera-camera2:1.2.1")
implementation("androidx.camera:camera-lifecycle:1.2.1")
implementation("androidx.camera:camera-view:1.2.1")
// MLKit
implementation("com.google.mlkit:barcode-scanning:17.1.0")