안드로이드에서 QR 코드를 쉽게 사용할 수 있는 라이브러리.
카메라를 호출하고 액티비티에서 결과를 받는 방법과 레이아웃에 뷰를 사용해서 스캔하는 방법이 있다.
본 글에서는 레이아웃에 뷰를 사용해서 스캔하는 방법을 설명한다.
<androidx.constraintlayout.widget.ConstraintLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.journeyapps.barcodescanner.DecoratedBarcodeView
android:id="@+id/barcode_scanner"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:zxing_scanner_layout="@layout/custom_barcode_scanner" />
</androidx.constraintlayout.widget.ConstraintLayout>
DecoratedBarcodeView 를 QR 스캔할 화면에 추가하면 해당 화면에서 QR 스캔을 할 수 있다.
그리고 QR 스캔 UI 세부 설정을 해야 한다.
app:zxing_scanner_layout 속성에 세부 레이아웃을 설정한다.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.journeyapps.barcodescanner.BarcodeView
android:id="@+id/zxing_barcode_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="250dp"
app:zxing_framing_rect_width="250dp" />
<View
android:layout_width="250dp"
android:layout_height="250dp"
android:background="@drawable/qr_background"
android:layout_gravity="center"/>
<com.journeyapps.barcodescanner.ViewfinderView
android:id="@+id/zxing_viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_possible_result_points="@color/possible_result_point"
app:zxing_result_view="@color/result"
app:zxing_viewfinder_mask="@color/viewfinder_mask"
app:zxing_viewfinder_laser="@color/viewfinder_laser"
app:zxing_viewfinder_laser_visibility="true" />
</merge>
레이아웃에서 View 는 스캔 화면에서 영역을 표시하기 위해 추가한 것으로 없어도 상관 없다.
android:background 에 사용할 UI를 추가하면 되는데, 작성자는 stackoverflow의 질문을 참조했다.
BarcodeView 는 스캔 영역의 크기를 지정할 수 있으며, 코드에서는 카메라 설정 등을 할 수 있다.
ViewfinderView 는 스캔과 관련된 UI를 설정할 수 있다.
app:zxing_viewfinder_mask : 스캔 영역을 제외한 영역의 배경색
app:zxing_viewfinder_laser : 스캔 시 나타나는 선의 색상
주의해야 할 점은 BarcodeView와 ViewfinderView 의 id는 라이브러리에서 제시하는 id를 사용해야 QR 기능을 사용할 수 있다.
id를 다른 이름으로 사용한 경우, 해당 리소스를 찾지 못하는 오류가 발생한다.
<uses-permission android:name="android.permission.CAMERA" />
카메라를 사용하기 때문에, AndroidManifest.xml 파일에서 카메라 권한을 설정해야 한다.
사용자 권한 요청 기능은 이 글에서 설명하지 않음.
this.scanView = findViewById(R.id.barcode_scanner)
with(this.scanView) {
barcodeView.decoderFactory =
DefaultDecoderFactory(arrayListOf(BarcodeFormat.QR_CODE, BarcodeFormat.EAN_13))
barcodeView.cameraSettings.requestedCameraId = 1
barcodeView.cameraSettings.isAutoFocusEnabled = true
decodeContinuous(callback)
}
설정은 대부분 BarcodeBiew를 통해서 한다. 해당 설정 외에도 다른 설정이 많기 때문에 라이브러리를 참고하는 것을 추천
decoderFactory: 스캔할 코드의 형식을 설정
cameraSettings.requestedCameraId: 사용한 카메라 설정, 대부분의 경우 1은 전면 카메라
cameraSettings.isAutoFocusEnabled: 오토 포커스 모드 사용 여부
decodeContinuous: 스캔을 시작, 이때 결과를 받을 콜백 메서드를 전달해야 한다.
private val callback = BarcodeCallback { result ->
if (System.currentTimeMillis() - this.currentTime >= 3000) {
result?.let { it ->
this.createRequest(it.text)
}
}
this.currentTime = System.currentTimeMillis()
}
BarcodeCallback 를 구현하는 것으로 콜백 메서드를 만든다.
BarcodeResult 타입은 result 데이터를 원하는 형태로 처리하면 QR 스캔 기능을 만들 수 있다.
해당 예제 코드는 QR 코드가 계속 스캔되는 것을 방지하기 위해 추가한 코드로 없어도 된다.