본문 바로가기

Android/Utility

[Android] Zxing 라이브러리를 사용하여 QR 코드를 읽어보자

728x90

QR 코드를 사용할 일이 생겨서 알아보던 와중, ZXing이라는 라이브러리를 사용하면 쉽게 QR 코드에 대한 정보를 가져올 수 있다고 하여 해당 라이브러리를 사용해 보았다.

 

적용하는 방법도 아주 간단하고, QR 코드를 인식하고, 데이터를 제대로 가져오는지만 확인하면 되는 간단한 작업이라 쉽게 적용하고 사용해 볼 수 있었다.


우선,

Module 범위의 Gradle에 해당 라이브러리를 추가해주어야 한다.

 

// zxing
implementation 'com.journeyapps:zxing-android-embedded:4.1.0'

 

위의 버전이 아래에 설명할 코드를 사용할 경우 가장 최신 버전으로, Min SDK Version이 24 미만인 경우에는 추가적으로 implementation 해야 하는 부분이 있지만, 필자는 Min SDK Version이 24이므로 위와 같이 라이브러리를 추가해 주었다.

 

Min SDK Version이 24미만인 경우에는 다음과 같이 추가하면 사용할 수 있다니 참고하길 바란다.

 

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

 

라이브러리를 추가해주었으니, QR 코드를 사용할 Activity 하나 만들고 그곳에서 추가하여 사용하면 된다.

 

우선,

Activity를 추가하기 전에 Manifest에 Camera에 대한 권한을 추가해주도록 한다.

 

<uses-permission android:name="android.permission.CAMERA" />

 

QR 코드는 카메라를 사용하는 것이다보니 반드시 카메라에 대한 권한을 줘야 한다.

 

권한을 추가하고, Activity 또한 추가하여 사용해보도록 하자.

 

private fun initQrCode() {
    val integrator = IntentIntegrator(this)
    integrator.setPrompt("Barcode or QR Code")
    integrator.setOrientationLocked(false)
    integrator.setBeepEnabled(true)
    integrator.initiateScan()
}

 

위와 같이 몇 줄을 추가하기만 하면 QR 코드를 찍기 위한 카메라가 오픈되게 된다.

다양한 옵션이 있지만 필자는 기본적으로 사용할 법한 옵션을 선언해보았다.

 

  • setPrompt : QR 코드를 찍는 카메라 화면 하단에 나올 Text
  • setOrientationLocked :  화면의 가로, 세로 고정 여부
  • setBeepEnabled : QR 코드 스캔 시 Beep 소리의 여부
  • initiateScan : Camera 실행

 

이러한 옵션들 외에도,

 

 

자동 완성 기능을 통해 다양한 옵션을 확인하고 설정할 수 있다.

 

 

이렇게 QR 코드를 확인할 수 있는 카메라를 오픈하고, 카메라를 통해 QR 코드를 리딩 하였으면, 그 결과를 받아와야 한다.

따라서, onActivityResult를 override하여 데이터를 가져오도록 하자.

 

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)

    if (result != null) {
        binding.qrText.text = result.toString()
    } else {
        super.onActivityResult(requestCode, resultCode, data)
    }
}

 

이처럼 카메라를 통해 읽은 QR 코드의 데이터를 가져와서 텍스트 뷰에 뿌려주도록 하자.

 

 

이처럼 데이터가 정상적으로 들어오는 것을 볼 수 있다.

아마도 여기서 실제로 사용하는 데이터는 Contents에 대한 값만 사용하면 될 것으로 보인다.

QR 코드를 테스트하기 위해 사용했던 QR 코드 생성 사이트는 이곳에서 확인하면 된다.


여기까지는, 다른 블로그에서 찾아볼 수 있는 소스코드였다.

하지만 필자가 ZXing Github에 들어가서 확인해본 결과, 최신 버전에서는 달라진 부분이 보였다.

 

implementation 'com.journeyapps:zxing-android-embedded:4.3.0'

 

위에서 언급하였듯이, 4.1.0은 위에 작성한 코드를 사용할 경우의 최신 버전이고 실제로 가장 최신 버전은 4.3.0 버전이다.

 

 Github 내용을 확인해보니 이러한 글이 있었다.

 

Note: startActivityForResult is deprecated, so this example uses registerForActivityResult instead. See for details: https://developer.android.com/training/basics/intents/result

startActivityForResult can still be used via IntentIntegrator, but that is not recommended anymore.

 

위의 버전에서 사용했던 startActivityForResult가 Deprecated 되어서 해당 코드를 사용하는 것을 추천하지 않는다고 한다.

 

이것은,

 

integrator.initiateScan()

 

해당 라이브러리를 초기화 하는 부분에서 마지막에 카메라를 호출시키는 부분인데,

 

 

해당 함수를 통해 startActivityForResult를 호출하고 있기 때문이다.

 

따라서, 최신 버전에서는 다음과 같이 사용하고 있다.

우선 위와 마찬가지로 Init 함수부터 확인해보자.

 

private fun launcherQrCode() {
    val options = ScanOptions()
    options.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
    options.setPrompt("Scan a barcode")
    options.setBeepEnabled(false)
    options.setBarcodeImageEnabled(true)
    barcodeLauncher.launch(options)
}

 

사용하는 옵션은 달라진것이 없으며, 이 또한 자동완성 기능을 통해 확인할 수 있다.

 

 

setDesiredBarcodeFormats에서 설정하는 값을 제대로 설정하지 않으면, QR Code를 인식할 수 없으니 해당 옵션을 통해 어떤 것을 확인하려고 하는지 명시해 주는 것이 좋다.

 

마지막 줄인 barcodeLauncher를 통해 호출된 부분을 확인해보자.

 

private val barcodeLauncher: ActivityResultLauncher<ScanOptions> =
    registerForActivityResult<ScanOptions, ScanIntentResult>(
        ScanContract(),
        ActivityResultCallback { result: ScanIntentResult ->
            if (result.contents == null) {
                Toast.makeText(this@QrCodeActivity, "Cancelled", Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(
                    this@QrCodeActivity,
                    "Scanned: " + result.contents,
                    Toast.LENGTH_LONG
                ).show()
            }
        })

 

결과적으로 달라지기는 했지만, 카메라에서 콜백을 받아 처리하는 부분은 동일하다.

registerForActivityResult 라는 함수를 통해 받아도록 변경이 되었는데,  Developers 문서를 확인해보니

 

 

라고 한다.

즉, 위에서 Deprecated된 함수의 역할을 하는 것이 registerForActivityResult라고 생각하면 될 것이다.

 

따라서 이와 같이 코드를 구현하고, QR 코드를 확인해보면 정상적으로 동작하는 것을 볼 수 있다.


처음에 간단하게 적용해볼 때는, zxing 라이브러리의 github 문서를 보지 않고 다른 블로그 가이드만 보고 따라서 작성했었는데,

역시 무엇이든지 공식 문서를 보고 공부를 하는것이 좋은 것 같다.

 

이전 버전의 코드라고해서 정상적으로 동작하지 않는 것이 아니지만, 그래도 역시 최신 버전에 맞춰서 코드를 변경해 주는 것이 안정성을 높이는데 도움을 줄 것이라고 생각한다.

 

뭐, 사실상 사용하는 라이브러리가 많으면 정상 동작을 하지 않을 때가 되서야 왜 이러지 하고 찾아볼 것 같지만 말이다.

 

해당 게시글에 사용한 예제는 다음 Github에 올려두었다.

https://github.com/HeeGyeong/CleanArchitectureSample

 

GitHub - HeeGyeong/CleanArchitectureSample

Contribute to HeeGyeong/CleanArchitectureSample development by creating an account on GitHub.

github.com

 

728x90