투케이2K

531. (kotlin/코틀린) [유틸 파일] 기능 보완 - observable_Qr_Barcode_Scan : QR 및 Barcode 스캔 팝업창 호출 본문

Kotlin

531. (kotlin/코틀린) [유틸 파일] 기능 보완 - observable_Qr_Barcode_Scan : QR 및 Barcode 스캔 팝업창 호출

투케이2K 2024. 10. 31. 20:11

[개발 환경 설정]

개발 툴 : AndroidStudio

개발 언어 : Kotlin

 

[소스 코드]

 

        // -----------------------------------------------------------------------------------------
        // TODO [SEARCH FAST] : [Observable] : [QR 및 Barcode 스캔 팝업창 호출 메소드]
        // -----------------------------------------------------------------------------------------
        // TODO [필요 퍼미션] : 카메라 퍼미션
        // -----------------------------------------------------------------------------------------
        // TODO [필요 설치 라이브러리] :
        // -----------------------------------------------------------------------------------------
        /*
        * implementation 'com.journeyapps:zxing-android-embedded:3.5.0'
        * implementation "com.google.zxing:core:3.3.0"
        * */
        // -----------------------------------------------------------------------------------------
        // TODO [호출 방법 소스 코드]
        // -----------------------------------------------------------------------------------------
        /*
        try {

            // [팝업창 활성 수행]
            C_Ui_View.observable_Qr_Barcode_Scan(A_Intro@this, R.drawable.loading_bg, "Qr 및 Barcode 스캔", "닫기")
                .subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
                .observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
                .subscribe(
                    { value ->
                        S_Log._D_("Qr 및 Barcode 스캔 결과 확인", arrayOf(value.toString()))
                    },
                    { error ->
                        S_Log._E_("Qr 및 Barcode 스캔 에러 확인", arrayOf(error.message.toString()))
                    }
                )
                {
                }

        }
        catch (e : Exception) {
            e.printStackTrace()
        }
        */
        // ----------------------------------------------------------------------------------
        var camera_scan_alert: AlertDialog? = null
        fun observable_Qr_Barcode_Scan(mContext: Activity, icon: Int, title: String, ok: String): Observable<String> {

            // [로직 처리 실시]
            return Observable.create { subscriber: ObservableEmitter<String> ->
                try {
                    // ===============================================================
                    S_Log._F_(mContext, "Qr 및 Barcode 스캔 팝업창 호출 수행 실시", null)
                    // ===============================================================


                    // [변수 선언]
                    if (camera_scan_alert != null) {
                        camera_scan_alert = null
                    }
                    val scanFlag = booleanArrayOf(false) // [연속 스캔 콜백 방어]


                    // TODO [UI 생성 실시] : [커스텀 뷰]
                    val barcodeScannerView = DecoratedBarcodeView(mContext)
                    barcodeScannerView.setPadding(70, 70, 70, 70)
                    val cameraSettings = CameraSettings() // [카메라 설정 관련]
                    //cameraSettings.setRequestedCameraId(1); // [전방 카메라]
                    cameraSettings.requestedCameraId = 0 // [후방 카메라]
                    barcodeScannerView.barcodeView.cameraSettings = cameraSettings
                    barcodeScannerView.initializeFromIntent(mContext.intent)
                    barcodeScannerView.resume() // [수행]


                    // TODO [UI 생성 실시] : [기본 사용]
                    /*
                    IntentIntegrator intentIntegrator = new IntentIntegrator(mContext);
                    intentIntegrator.setPrompt("QR 및 Barcode 를 읽어주세요");
                    intentIntegrator.initiateScan();
                    // */


                    // TODO [Qr 및 바코드 스캔 이벤트 지정]

                    barcodeScannerView.decodeContinuous(object : BarcodeCallback {
                        override fun barcodeResult(result: BarcodeResult) {
                            try {
                                if (scanFlag[0] == false) { //TODO [최초 1번 스캔된 경우]

                                    val result_data = result.toString() // [스캔 결과]

                                    S_Log._F_(mContext, "Qr 및 Barcode 스캔 결과 확인", arrayOf(result_data))

                                    scanFlag[0] = true // [플래그 값 변경]

                                    // [팝업창 생성 실시]
                                    Handler(Looper.getMainLooper()).postDelayed({

                                        // [알림 팝업창 표시]
                                        C_Ui_View.observableAlert(mContext, icon, "Qr 및 Barcode 스캔 결과", result_data, "결과 확인", "다시 스캔")
                                            .subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
                                            .observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
                                            .subscribe(
                                                { value ->
                                                    if (value == true) { // [확인 클릭]

                                                        // -----------------------------------------
                                                        // TODO [리턴 데이터 반환]
                                                        // -----------------------------------------
                                                        try {
                                                            subscriber.onNext(result_data)
                                                            subscriber.onComplete()

                                                            Handler(Looper.getMainLooper()).postDelayed({

                                                                if (barcodeScannerView != null){
                                                                    barcodeScannerView.pause()
                                                                }

                                                            }, 0)

                                                            if (camera_scan_alert != null) {
                                                                camera_scan_alert!!.dismiss()
                                                                camera_scan_alert = null
                                                            }

                                                        } catch (ex: Exception) {
                                                            ex.printStackTrace()
                                                        }

                                                    } else { // [취소 클릭]

                                                        // -----------------------------------------
                                                        // TODO [다시 스캔 시도]
                                                        // -----------------------------------------
                                                        scanFlag[0] = false // [플래그 값 변경]
                                                    }
                                                },
                                                { error ->

                                                }
                                            )
                                            {
                                            }

                                    }, 0)
                                }

                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                        }

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


                    // [팝업창 생성 실시]
                    Handler(Looper.getMainLooper()).postDelayed({
                        if (mContext != null) {

                            // [AlertDialog 팝업창 생성]
                            camera_scan_alert = AlertDialog.Builder(mContext)
                                .setTitle(title) //[팝업창 타이틀 지정]
                                .setIcon(icon) //[팝업창 아이콘 지정]
                                //.setMessage("\n") //[팝업창 내용 지정]
                                .setView(barcodeScannerView)
                                .setCancelable(false) //[외부 레이아웃 클릭시도 팝업창이 사라지지않게 설정]
                                .setPositiveButton(ok) { dialog, which ->
                                    // -----------------------------------------
                                    // TODO [버튼 클릭 이벤트 처리]
                                    // -----------------------------------------
                                    S_Log._F_(mContext, "Qr 및 Barcode 스캔 팝업창 [$ok] 클릭", null)
                                    // -----------------------------------------


                                    // -----------------------------------------
                                    // TODO [리턴 데이터 반환]
                                    // -----------------------------------------
                                    try {
                                        subscriber.onNext("")
                                        subscriber.onComplete()

                                        Handler(Looper.getMainLooper()).postDelayed({

                                            if (barcodeScannerView != null){
                                                barcodeScannerView.pause()
                                            }

                                        }, 0)

                                        if (camera_scan_alert != null) {
                                            camera_scan_alert!!.dismiss()
                                            camera_scan_alert = null
                                        }

                                    } catch (ex: Exception) {
                                        ex.printStackTrace()
                                    }
                                    // -----------------------------------------
                                }
                                .show()


                            // [팝업창 레이아웃 사이즈 변경]
                            //*
                            val lp = WindowManager.LayoutParams()
                            val window = camera_scan_alert!!.window
                            lp.copyFrom(window!!.attributes)

                            //lp.width = WindowManager.LayoutParams.MATCH_PARENT;
                            //lp.height = WindowManager.LayoutParams.MATCH_PARENT;

                            //lp.width =  (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350, mContext.getResources().getDisplayMetrics());
                            //lp.height = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 350, mContext.getResources().getDisplayMetrics());
                            val display = (mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
                            val outMetrics = DisplayMetrics()
                            display.getMetrics(outMetrics)

                            val density = mContext.resources.displayMetrics.density
                            val dpHeight = outMetrics.heightPixels / density
                            val dpWidth = outMetrics.widthPixels / density

                            val dpWidthValue = dpWidth.toInt()
                            val dpHeightValue = dpHeight.toInt()

                            val width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpWidthValue.toFloat(), mContext.resources.displayMetrics).toInt()
                            val height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (dpHeightValue - 50).toFloat(), mContext.resources.displayMetrics).toInt()

                            lp.width = width
                            lp.height = height
                            window.attributes = lp
                            // */


                            // TODO [카메라 권한 부여 상태 확인]
                            if (C_Permission.getCameraPermissionEnable(mContext) === true) {
                                S_Log._F_(mContext, "Qr 및 Barcode 스캔 : 카메라 권한 상태 확인 : 정상", null)
                            } else {
                                S_Log._F_(mContext, "Qr 및 Barcode 스캔 : 카메라 권한 상태 확인 : 비정상", null)

                                showAlert(mContext, icon, 0, "알 림", "카메라 권한이 비활성 상태입니다. 카메라 권한 활성 후 해당 기능을 사용해주세요.", "확인", "")
                            }

                        }
                    }, 0)

                } catch (e: Exception) {
                    e.printStackTrace()

                    // ------------------------------------------------------
                    // TODO [리턴 데이터 반환]
                    // ------------------------------------------------------
                    try {
                        subscriber.onNext("")
                        subscriber.onComplete()
                    } catch (ex: Exception) {
                        ex.printStackTrace()
                    }
                }
            }
        }

 

반응형
Comments