Android/Kotlin) ZXing(QR Scanner) 사용하기

Simon
7 min readAug 15, 2021

--

안녕하세요 안드로이드 개발자 simon 입니다.

코로나 시국이라 조심스럽지만서도 성인이 된 이후로 혼자 여행을 가본 적이 없어서 기회삼아 제주도 다녀왔습니다. 어제 돌아와서 면세점에서 산 위스키 좀 먹고 오늘은 본가에서 부모님과 식사하고 지금 자리에 앉아서 스터디 중입니다…ㅎㅎ

새로운 프로젝트를 준비하면서 QR 코드를 스캔을 알아보다가 주로 ZXing이라는 바코드 스캐너 라이브러리를 많이 사용한다고 하더라구요. 적용 방법도 어렵지 않아서 바로 적용해보고 이렇게 글로써 남기고자 합니다.

라이브러리 추가

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

권한 설정

QR 코드를 스캔하기 위해서는 카메라 권한이 필요합니다. 또한, sdk overrideLibrary 코드도 추가해주세요.

<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
<uses-permission android:name="android.permission.INTERNET" />

레이아웃 적용하기

저는 화면 전체가 아닌 일부 화면에 정방형으로 QR 스캐너 레이아웃을 적용하였습니다. 간단하게도 라이브러리에서 뷰를 지원합니다.

적용 예시
적용 예시

초기 셋팅(initiate)

val integrator = IntentIntegrator(this) //context를 넣어줍니다
integrator.setBarcodeImageEnabled(false) //스캔 된 이미지 가져올 지
integrator.setBeepEnabled(true)//스캔 시 삡 소리 ON/OFF
integrator.setPrompt("QR 코드를 읽어주세요")//QR 스캐너 하단 메세지 셋팅
integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
integrator.captureActivity = ScanActivity::class.java
//스캐너가 있는 액티비티 적용(불필요 시 적용 안하셔도 됩니다)
integrator.initiateScan() //초기화

Activity Settings

  • 초기 셋팅에 있는 integrator.captureActivity 를 보시다시피 액티비티를 따로 생성하여 적용하였는데요. 기존 사용과 번거로운 점은 있습니다만, UI 적용 가능한지에 대해 테스트하고자 따로 생성하였습니다.
private lateinit var binding: ActivityScanBinding
private lateinit var capture: CaptureManager

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityScanBinding.inflate(layoutInflater)
setContentView(binding.root)
// CaptureManager에 context와 xml에서 적용한 레이아웃을 넣어줍니다.
capture = CaptureManager(this, binding.decoratedBarcodeView)
// intent와 savedInstanceState를 넣어줍니다.
capture.initializeFromIntent(intent, savedInstanceState)
capture.decode() //decode
}
  • 또한 액티비티 생명주기에 capture(CaptureManager)를 셋팅하였습니다.
override fun onResume() {
super.onResume()
capture.onResume()
}
override fun onPause() {
super.onPause()
capture.onPause()
}
override fun onDestroy() {
super.onDestroy()
capture.onDestroy()
}
  • onRequestPermissionsResult()라는 오버라이딩 함수를 통해 권한 허용 요청을 셋팅합니다.
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
capture.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

스캔된 값 전달받기

  • ScanActivity에서 스캔이 완료되면 해당 액티비티가 종료되면서 MainActivity로 돌아오게 되는데요. 스캔 값을 받아오기 위해서는 onActivityResult 오버라이딩 함수를 통해 전달 받습니다.
  • 값은 result 변수의 contents를 통해 스캔된 정보를 확인할 수 있습니다.
  • 또한 초기 셋팅에서 integrator.setBarcodeImageEnabled(false) 를 true 로 바꿔주시면 값을 전달 받을 때 촬영됬던 이미지까지 전달 받을 수 있습니다. 비트맵 형식으로 전달되기에 비트맵으로 받아서 처리하시면 됩니다. 저는 Glide를 통해 이미지를 출력하였습니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)

if (result != null) {
if (result.contents != null) {
Log.e("INFO: ", "${result.contents}")
} else {
Toast.makeText(this, "Canceled", Toast.LENGTH_SHORT).show()
}

if (result.barcodeImagePath != null) { //스캔한 이미지 가져오기
val bm = BitmapFactory.decodeFile(result.barcodeImagePath)
Glide.with(this).load(bm).into(binding.scannedImage)
}else{
Log.e("getImage", "BitmapNull")
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}

포스팅이 생각보다 길게 나오긴 했지만 절대로! 어렵지는 않은 QR코드 스캐너입니다. 해보시면 금방 하실 수 있을거에요.

피드백과 팔로우는 🖤입니다!

감사합니다🥑

--

--