웹뷰에서 qr인식을 위해 zxing

1 minute read

웹뷰로 이로어진 하이브리드 앱을 제작중인데 qr리더기가 필요했다.

구글 검색을 통해 zxing 라이브러리를 알아냈고 해당 라이브러리를 적용하여 웹뷰에서 QR인식을 하는 방법을 소개한다.

아래와 같은 작업이 필요하다.

  • 안드로이드에서 처리할 부분
    • build.gradle에서 모듈 추가
    • Androidmanifests.xml 에 관련태그 및 액티비티추가.
    • zxing 의 CaptureActivity 을 상속받는 빈 액티비티 추가
    • 웹에서 호출할 qr리더기 함수 선언
    • qr인식 결과 처리
  • 웹에서 처리할 부분
    • 웹페이지 소스에서 javascript로 큐알리더기 호출!
    • 웹페이지에서 qr인식 결과처리

안드로이드에서 처리할 부분

build.gradle 모듈 추가

먼저 buildgradle zxing 모듈을 추가한다.

    implementation 'com.journeyapps:zxing-android-embedded:4.0.0'
    implementation 'com.google.zxing:core:3.3.0'

Androidmanifests.xml

그리고 Androidmanifests.xml 에 sdk 를 쓰겠다고 선언하고

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

만약 tools 에서 에러가 난다면 상단에 xmlns를 추가한다

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="your.package">

그리고 카메라를 이용할것이기 때문에 해당 권한을 추가한다.

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

또 세로처리및 결과인식시 웹뷰가 뒤로 가지 않으려면 액티비티를 추가하여 지정해준다.

        <activity
            android:name=".CaptureAForm"
            android:screenOrientation="portrait"
            android:stateNotNeeded="true"
            tools:replace="android:screenOrientation"></activity>

CaptureActivity 를 상속받는 빈 activity

xml 은 없다 kotlin 파일을 만들어서 상속만 받았다.
여기서는 위 액티비티 name에 나와 있듯이 CaptureAForm 이다.
당신이 지정한 이름을 사용하면 된다.

package com.mnmsoft.congestionadmin
import com.journeyapps.barcodescanner.CaptureActivity
class CaptureAForm : CaptureActivity() {
}

웹에서 호출할 바코드리더기 호출 구현부

웹에서 호출할것이기 때문에 @javascriptInterface 어노테이션을 지정하고

    @JavascriptInterface
    fun qrRead(){
        val integrator = IntentIntegrator(this)
        integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
        integrator.setPrompt("바코드를 스캔하세요")
        integrator.setCameraId(0) // Use a specific camera of the device

        integrator.setBeepEnabled(false)
        integrator.setBarcodeImageEnabled(true)
        integrator.captureActivity = CaptureAForm::class.java
//        integrator.setOrientationLocked(false);
//        integrator.setRequestCode(200)
        integrator.initiateScan()
    }

웹뷰를 로드 할때 아래와 같이 선언

webView.addJavascriptInterface(this, "Android")

바코드 결과값 처리

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.d(TAG, "onActivityResult requestCode : ${requestCode} resultCode : ${resultCode}")
        val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
        if (result.contents == null) {
            Toast.makeText(this, "취소", Toast.LENGTH_LONG).show()
        } else {
            webView.loadUrl("javascript:qrScanResult('" + result.contents + "')"); // 웹javascript함수호출
        }
    }

웹에서 처리할 부분

웹페이지 소스에서 javascript로 큐알리더기 호출!

    Android.qrRead();

웹페이지에서 qr인식 결과처리

    function qrScanResult(result){
        console.log(result);
        alert(result);
    }

기타사항

이렇게 웹뷰에서 qr리더기를 동작시켜보았다. 다행히 잘 동작된다.

integrator.captureActivity = CaptureAForm::class.java

qr리더기를 호출하기 위해 지정된 activity를 사용하지 않으니 qr리더완료후 웹뷰가 첫 화면으로 가는 문제가 있었으니 꼭 사용해야 할듯 하다.

해당 모듈 github 링크
zxing github

끝.

Tags:

Categories:

Updated:

Leave a comment