ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • zxing 라이브러리 1편 (QR 스캔)
    회사 생활/QR 코드 인식 2023. 8. 14. 11:30

    1편 : zxing 라이브러리 1편 (QR 스캔)

    2편 : zxing 라이브러리 2편 (QR 만들기)

     

    회사에서 외국이 등록증에 있는 QR 데이터를 스캔하는 부분을 만들어야 한다는 업무를 받았다.

     

    구형 외국인 등록증에는 qr같은 것이 없었던 것으로 보이나 올해에 바뀐 신형 외국인 등록증에는 qr이 생겼고 이것으로 정보를 바로 가져올수 있다.

     

    관련 기사: https://www.korea.kr/news/policyNewsView.do?newsId=148913232

     

    여러가지 있는 것들중' zxing 라이브러리'이 많이 쓰이는 것으로 보이고 이것을 추천받아서 찾아보게 되었다.

     

    Zxing 라이브러리는

    구글에서 제공하는 오픈소스로 Zebra Crossing의 약자. QR코드 스캔 애플리케이션의 대다수가 이 애플리케이션을 이용했다고 해도 과언이 아닐정도로 널리 쓰이고 있는 코드다. 다양한 바코드를 인식할 수 있다. 인식할 수 있는 바코드 종류는 총 15가지. -나무위키 

     

    Zxing 라이브러리는 QR 스캔과 QR 코드를 만드는 기능을 쉽게 하도록 지원해준다.

     

    라이브러리 Github 주소 : https://github.com/zxing/zxing

    플레이 스토어 : https://play.google.com/store/apps/details?id=com.google.zxing.client.android

     

     

    zxing 라이브러리에서 주어진 것을 사용하는 방법과 custom 하는 방법 2가지로 나뉜다. 여기서 진행하면서 간단하게 설명하고자 한다. 

    1. dependency 세팅

    build.gradle(app)

    // zxing
     implementation 'com.journeyapps:zxing-android-embedded:4.3.0'

    AndroidManifest.xml

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

    2. 코드들 

    ZxingScan.java

    public class ZxingScan extends AppCompatActivity {
    
        private ActivityZxingScanBinding binding;
        private static final int CAMERA_PERMISSION_REQUEST_CODE = 100;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityZxingScanBinding.inflate(getLayoutInflater()); // 1
            setContentView(binding.getRoot()); // 2
    
            binding.button.setOnClickListener(view -> {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
                } else {
                    zxingScan();  //스캔
                }
            });
        }
        
        private ActivityResultLauncher<Intent> zxingActivityResultLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    IntentResult intentResult = IntentIntegrator.parseActivityResult(result.getResultCode(), result.getData());
                    if (intentResult.getContents() != null) {
                        binding.textview.setText(intentResult.getContents());
                    }
                }
        );
    
        private void zxingScan(){
            IntentIntegrator integrator = new IntentIntegrator(this);
            integrator.setPrompt("QR 코드를 스캔해주세요.");
            integrator.setCaptureActivity(CustomScannerActivity.class);
            integrator.setBeepEnabled(false);
            integrator.setBarcodeImageEnabled(false); //스캔 된 이미지 가져올 지
            zxingActivityResultLauncher.launch(integrator.createScanIntent());
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    zxingScan();  // 카메라 권한이 허용된 경우 스캔 화면으로 이동
                } else {
                    Toast.makeText(ZxingScan.this, "카메라 권한을 허가하셔야 합니다.", Toast.LENGTH_LONG).show();  // 카메라 권한이 거부된 경우
                }
            }
        }
    }

     

    // 여기서 스캔화면을 커스텀하게 귀찮다면 아랫부분을 주석 처리하면 된다

    //integrator.setCaptureActivity(CustomScannerActivity.class);
    

     

    activity_zxing_scan.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".zxingScan.ZxingScan">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/guideline"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
            <TextView
                android:id="@+id/textview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.5"/>
    
        <Button
            android:id="@+id/button"
            android:text="스캔"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="80dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    ---------------------------- 위에서 커스텀 하는 부분을 안했다면 여기까지 ----------------------------

     

    CustomScannerActivity.java

    public class CustomScannerActivity extends AppCompatActivity {
    
        private ActivityCustomScannerBinding binding;
        private CaptureManager capture;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityCustomScannerBinding.inflate(getLayoutInflater()); // 1
            setContentView(binding.getRoot()); // 2
    
            capture = new CaptureManager(this, binding.zxingBarcodeScanner);
            capture.initializeFromIntent(getIntent(), savedInstanceState);
            capture.decode();
    
            //---- 레이저 라인 없애는 코드 ----
            ViewfinderView viewfinderview = binding.zxingBarcodeScanner.getViewFinder();
            Field scannerAlphaField = null;
            try {
                scannerAlphaField = viewfinderview.getClass().getDeclaredField("SCANNER_ALPHA");
                scannerAlphaField.setAccessible(true);
                scannerAlphaField.set(viewfinderview, new int[1]);
            } catch (Exception e) {
                Log.e("eTag", "e : "+e.getMessage());
            }
        }
    }

     

    activity_custom_scanner.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".zxingScan.CustomScannerActivity">
    
        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/zxing_barcode_scanner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:zxing_scanner_layout="@layout/custom_barcode_scanner" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

     

    custom_barcode_scanner.xml

    <?xml version="1.0" encoding="utf-8"?>
    <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <com.journeyapps.barcodescanner.BarcodeView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:zxing_framing_rect_width="800dp"
            app:zxing_framing_rect_height="800dp"
            app:zxing_preview_scaling_strategy="fitCenter"
            android:id="@+id/zxing_barcode_surface" />
    
        <com.journeyapps.barcodescanner.ViewfinderView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/zxing_viewfinder_view"
            app:zxing_viewfinder_laser="@color/zxing_transparent"
            app:zxing_viewfinder_mask="@color/zxing_transparent"/>
    
    </merge>

     

    zxing_framing_rect_width : 스캔 인식 너비

    zxing_framing_rect_height : 스캔 인식 높이 

     

    zxing_viewfinder_laser: 레이저 색상!!! 그러나 투명도는 적용 안된다고...

    zxing_viewfinder_mask : 바코드 인식의 바깥부분

     

     

     

    '회사 생활 > QR 코드 인식' 카테고리의 다른 글

    zxing 라이브러리 2편 (QR 만들기)  (0) 2023.08.14
Designed by Tistory.