반응형
안녕하세요.
이번 포스팅에서는 다른 포스팅에서 구현한 QR scan 기능에 EventBus를 달아보겠습니다.
아래 포스팅에서 구현한 소스를 refactoring 하겠습니다.
https://it-of-fortune.tistory.com/28
언어: 코틀린
sdk vsersion
- compile: 33
- min: 21
- target: 33
먼저, dependency를 추가합니다.
build.gradle(:app)
dependencies {
...
implementation 'org.greenrobot:eventbus:3.2.0'
...
}
QrScanner 클래스를 Activity로부터 분리하겠습니다.
QrScanner.kt
class QrScanner : ImageAnalysis.Analyzer {
@ExperimentalGetImage
override fun analyze(image: ImageProxy) {
val mediaImage = image.image
if (mediaImage != null) {
val inputImage =
InputImage.fromMediaImage(mediaImage, image.imageInfo.rotationDegrees)
val scanner = BarcodeScanning.getClient(
BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_QR_CODE,
Barcode.FORMAT_AZTEC
)
.build()
)
scanner.process(inputImage)
.addOnSuccessListener { barcodes ->
scanCode(barcodes)
}
image.close()
}
}
private fun scanCode(barcodes: List<Barcode>) {
for (barcode in barcodes) {
when (barcode.valueType) {
Barcode.TYPE_URL -> {
val url = barcode.url!!.url
}
}
}
}
}
Event를 담을 data class를 생성합니다.
QrInformation.kt
data class QrInformation(
val url: String?
)
Activity에 event subscriber를 달아주겠습니다.
QrScanActivity.kt
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onUrlScan(qrInformation: QrInformation?) {
if (qrInformation != null) moveToQrContents(qrInformation.url)
}
이제 event를 post해주는 코드를 작성합니다.
QrScanner.kt
private fun scanCode(barcodes: List<Barcode>) {
for (barcode in barcodes) {
when (barcode.valueType) {
Barcode.TYPE_URL -> {
val url = barcode.url!!.url
EventBus.getDefault().post(QrInformation(url))
}
}
}
}
전체적인 Activity 소스입니다.
QrScanActivity.kt
class QrScanActivity : AppCompatActivity() {
private var _binding: ActivityQrScanBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityQrScanBinding.inflate(layoutInflater)
setContentView(binding.root)
checkCameraPermission()
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onUrlScan(qrInformation: QrInformation?) {
if (qrInformation != null) moveToQrContents(qrInformation.url)
}
private fun checkCameraPermission() {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), 1)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
) {
startCamera()
}
}
private fun startCamera() {
ProcessCameraProvider.getInstance(this).addListener({
try {
val processCameraProvider =
ProcessCameraProvider.getInstance(this).get() as ProcessCameraProvider
bindPreview(processCameraProvider)
} catch (e: Exception) {
e.printStackTrace()
}
}, ContextCompat.getMainExecutor(this))
}
private fun bindPreview(processCameraProvider: ProcessCameraProvider) {
processCameraProvider.unbindAll()
processCameraProvider.bindToLifecycle(
this,
CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build(),
Preview.Builder().build().apply {
setSurfaceProvider(binding.cameraPreview.surfaceProvider)
},
ImageCapture.Builder().build(),
ImageAnalysis.Builder()
.setTargetRotation(Surface.ROTATION_270)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build().apply {
setAnalyzer(Executors.newSingleThreadExecutor()!!, QrScanner())
}
)
}
private fun moveToQrContents(contents: String?) {
if (contents != null) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(contents)))
}
}
}
몇 번의 작업으로 간단하게 끝이 났습니다.
이제 테스트를 해보겠습니다.
구글 페이지로 이동하는 QR code를 사용합니다(figure1 참조).
무사히 refactoring 되었습니다.
이상 포스팅을 마치겠습니다.
감사합니다.
728x90
반응형
'Android Application > 기초 사용법' 카테고리의 다른 글
안드로이드 스피너(spinner) 사용 (0) | 2023.04.03 |
---|---|
안드로이드 retrofit2 사용(with Coroutine) - 로또 api 요청 (0) | 2023.04.02 |
안드로이드 ML Kit - QR scan 구현 (0) | 2023.04.01 |
안드로이드 힐트(hilt) 의존성 주입 사용 (1) | 2023.03.31 |
안드로이드 리사이클러뷰(recyclerview) 사용(with DiffUtil) (0) | 2023.03.30 |