Notice
Recent Posts
Recent Comments
Link
투케이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()
}
}
}
}
반응형
'Kotlin' 카테고리의 다른 글
Comments