개발 공부 기록/04. Android

[Android][Kotlin] zxing 라이브러리를 이용해서 바코드 , QR코드를 인식해보자 (커스텀 진행)

박세류 2021. 3. 10. 14:38

0. 들어가기 앞서

zxing 이란? 

- 구글에서 제공하는 오픈소스로 Zebra Crossing의 약자이며, 다양한 바코드를 인식할 수 있다.

 

1. 시작

 

1-1. build.gradle 

implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
implementation 'com.google.zxing:core:3.4.0'

해당 라이브러리를 추가해준다.

 

1-2.  Manifest.xml 

 

 <uses-sdk tools:overrideLibrary="com.google.zxing.client.android"/> -- 라이브러리 추가
 <uses-permission android:name="android.permission.CAMERA"/> -- 카메라 권한

해당 권한을 추가해주어아 한다.

 

그리고,

    <activity android:name=".ui.scan.LabelContinuousCaptureActivity"/>

바코드스캔을 사용하고자 하는 액티비티도 추가해준다.

 

나는 스캔하고 원래 화면으로 돌아올 것이 아닌,

현재 식당등지에서 많이 쓰이는 qr체크인 방식처럼 계속 인식되게끔 만들어보았다. 

 

1-3. xml - 원하는 이름의 xml 추가

이와같이 화면을 만들어 주었다. 필자는 aac 를이용한 mvvm으로 만들기 위해 밑에 코드처럼 진행하였으나, 그럴 필요가 없다면 빼고 진행하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.micromos.knpmobile.ui.scan.LabelContinuousCaptureViewModel" />
    </data>


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/barcode_scanner"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_above="@+id/buttonsLayout"
            android:layout_alignParentTop="true">

        </com.journeyapps.barcodescanner.DecoratedBarcodeView>

        <LinearLayout
            android:id="@+id/buttonsLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_toLeftOf="@+id/centerHorizont"
            android:orientation="vertical">

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="pause"
                android:text="Pause" />

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:onClick="resume"
                android:text="Resume" />
        </LinearLayout>

        <View
            android:id="@+id/centerHorizont"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true" />

        <ImageView
            android:id="@+id/barcodePreview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/buttonsLayout"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_toRightOf="@id/centerHorizont" />

    </RelativeLayout>
</layout>

 

4. Activity 코드

class LabelContinuousCaptureActivity : AppCompatActivity() {
    private lateinit var beepManager: BeepManager
    private var lastText: String? = null

    private val formats: Collection<BarcodeFormat> = listOf(
        BarcodeFormat.QR_CODE,
        BarcodeFormat.CODE_39
    )


    private val callback: BarcodeCallback = object : BarcodeCallback {
        override fun barcodeResult(result: BarcodeResult) {
            if (result.text == null || result.text == lastText) {
                // Prevent duplicate scans
                return
            }
            lastText = result.text
            barcode_scanner.setStatusText(result.text)
            if(beepManager.isBeepEnabled)
                beepManager.playBeepSoundAndVibrate()
        }

        override fun possibleResultPoints(resultPoints: List<ResultPoint>) {}
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
   
        barcode_scanner.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
        barcode_scanner.initializeFromIntent(intent)
        barcode_scanner.decodeContinuous(callback)
        beepManager = BeepManager(this)
        }
      }

위와같은 방식으로 BarcodeView를 초기화 시켜주며,

BeepManager로 소리까지 넣어준다.

읽은 값을 lastText에 저장하여 읽고있는 값이 lastText와 같으면 처리하지 않는다

 

이런 방식으로 사용할시 스캔이 계속적으로 이루어진다.

본인의 입맛에 맞게 커스텀해서 사용할 방식이 많으니

github등지에 있는 여러가지의 코드를 참조하여 바꾸어보자.

728x90