웹뷰에서 qr인식을 위해 zxing
웹뷰로 이로어진 하이브리드 앱을 제작중인데 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
끝.
Leave a comment