Search code examples
zxingandroid-jetpack-compose

Using Zxing Library with Jetpack compose


I am trying to implement qr scanner using zxing library. For this, i have added a button on screen, and on click of it, i am launching scanner as below

Button(
        onClick = {
            val intentIntegrator = IntentIntegrator(context)
            intentIntegrator.setPrompt(QrScanLabel)
            intentIntegrator.setOrientationLocked(true)
            intentIntegrator.initiateScan()
        },
        modifier = Modifier
            .fillMaxWidth()
    ) {
        Text(
            text = QrScanLabel
        )
    }

but, it launches an intent, which expects onActivityResult method to get back the results. And Jetpack compose uses rememberLauncherForActivityResult like below

val intentLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
    ) {
        if (it.resultCode != RESULT_OK) {
            return@rememberLauncherForActivityResult
        }
        ...
    }

but how do we integrate both things together here?


Solution

  • I make a provisional solution with same library: Gradle dependencies:

    implementation('com.journeyapps:zxing-android-embedded:4.1.0') { transitive = false }
    implementation 'com.google.zxing:core:3.4.0'
    

    My new Screen with jetpack compose and camera capture, that works for my app:

    @Composable
    fun AdminClubMembershipScanScreen(navController: NavHostController) {
        val context = LocalContext.current
        var scanFlag by remember {
            mutableStateOf(false)
        }
    
        val compoundBarcodeView = remember {
            CompoundBarcodeView(context).apply {
                val capture = CaptureManager(context as Activity, this)
                capture.initializeFromIntent(context.intent, null)
                this.setStatusText("")
                capture.decode()
                this.decodeContinuous { result ->
                    if(scanFlag){
                        return@decodeContinuous
                    }
                    scanFlag = true
                    result.text?.let { barCodeOrQr->
                        //Do something and when you finish this something
                        //put scanFlag = false to scan another item
                        scanFlag = false
                    }
                    //If you don't put this scanFlag = false, it will never work again.
                    //you can put a delay over 2 seconds and then scanFlag = false to prevent multiple scanning 
                    
                }
            }
        }
    
        AndroidView(
            modifier = Modifier,
            factory = { compoundBarcodeView },
        )
    }