Home > OS >  zxing with compose for qr scan
zxing with compose for qr scan

Time:10-05

I want to implemented qr scanner using zxing and compose. I tried it many times but fail. How can I implemented it?

This code didn't work for me.

@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 },
    )
}

CodePudding user response:

From Compose interop documentation:

Note: Constructing the view in the AndroidView viewBlock is the best practice. Do not hold or remember a direct view reference outside AndroidView.

Instead you should create your view inside factory - it also will give you the context, so you don't need LocalContext.

But main problem why it doesn't work for you, is that you're not starting the camera. You should call resume() to do so. So final code can look like this:

var scanFlag by remember {
    mutableStateOf(false)
}

AndroidView(
    factory = { context ->
        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
                }
                println("scanFlag true")
                scanFlag = true
                result.text?.let { barCodeOrQr ->
                    println("$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
            }
            this.resume()
        }
    },
    modifier = Modifier
)
  • Related