728x90
반응형
갑자기 QR 코드 스캐너를 만들어야 했다.
순간 막막했다.
카메라 모듈도 잘 못다루는데.
그래서 자료를 찾아보니깐 묘한 단어가 눈에 띈다.
Zxing. Zebra Crossing
Barcode scanning library for Java, Android
"이런건(QR 코드 스캐너) 날로 먹어도 된다고 허락받은 느낌이다."
튜토리얼에 해당하는게 정말 많다.
그래서 쉽게 찾을 수 있는 것들은 아주 심플하게 작성하고 넘어가겠다.
1. build.gradle (app)
1 2 3 | // Zxing android embedded. From version 3.6.0, only Android SDK 19+ is supported by default. implementation 'com.journeyapps:zxing-android-embedded:3.6.0' // implementation 'com.google.zxing:core:3.3.0' // if Android 14+ support | cs |
2. AndroidManifest.xml
hardwareAccelerated 부분 추가
1 2 3 4 | <application android:allowBackup="true" android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" | cs |
3. WebViewActivity
본 Activity에서 카메라 버튼을 누르면 Scanner Activity로 넘어간다.
카메라 버튼을 누르면 다음과 같은 method가 작동되도록 하였다.
1 2 3 4 5 6 7 8 9 10 | private void onQrcodeScanner() { LogcatLogger.d(TAG, "* * * * Camera"); Toast.makeText(this, "Camera", Toast.LENGTH_SHORT).show(); IntentIntegrator integrator = new IntentIntegrator(this); integrator.setBeepEnabled(false); integrator.setCaptureActivity(CustomScannerActivity.class); integrator.initiateScan(); } | cs |
CustomScannerActivity이 바로 Scanner activity 이다.
CustomScannerActivity에서 정상적으로 Scan이 완료되면 다시 본 activity로 돌아온다.
이 때, onActivityResult로 결과를 받는다.
1 2 3 4 5 6 7 8 9 10 11 | @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == Activity.RESULT_OK) { IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); String re = scanResult.getContents(); LogcatLogger.d(TAG, "* * * * onActivityResult: ." + re); Toast.makeText(this, "Zxing Custom operating :::: " + re, Toast.LENGTH_LONG).show(); } else { super.onActivityResult(requestCode, resultCode, data); } } | cs |
4. CustomScannerActivity
이 부분부터는 dolsanta님 github를 거의 copy하다싶이 하였다.
(이 자리를 빌어서 감사드립니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | public class CustomScannerActivity extends BaseActivity implements DecoratedBarcodeView.TorchListener { protected final String TAG = "CustomScannerActivity"; private CaptureManager capture; private DecoratedBarcodeView barcodeScannerView; private ImageButton btnSetting,btnSwitchFlash; private Boolean switchFlashlightButtonCheck; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_scanner); switchFlashlightButtonCheck = true; btnSetting = findViewById(R.id.btn_setting); btnSwitchFlash = findViewById(R.id.btn_switch_flash); barcodeScannerView = findViewById(R.id.zxing_barcode_scanner); if (!hasFlash()) { btnSwitchFlash.setVisibility(View.GONE); } barcodeScannerView.setTorchListener(this); capture = new CaptureManager(this, barcodeScannerView); capture.initializeFromIntent(getIntent(), savedInstanceState); capture.decode(); btnSwitchFlash.setOnClickListener(v -> { if (switchFlashlightButtonCheck) { barcodeScannerView.setTorchOn(); } else { barcodeScannerView.setTorchOff(); } }); } @Override protected String createTag() { return TAG; } @Override protected void onResume() { super.onResume(); capture.onResume(); } @Override protected void onPause() { super.onPause(); capture.onPause(); } @Override protected void onDestroy() { super.onDestroy(); capture.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); capture.onSaveInstanceState(outState); } private boolean hasFlash() { return getApplicationContext().getPackageManager() .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH); } /** * TorchListener */ @Override public void onTorchOn() { btnSwitchFlash.setImageResource(R.drawable.ic_menu_flash); switchFlashlightButtonCheck = false; } @Override public void onTorchOff() { btnSwitchFlash.setImageResource(R.drawable.ic_menu_flash); switchFlashlightButtonCheck = true; } } | cs |
다음은 zxing에서 지원되는 기능이다.
- TorchListener : flash를 관리한다. override된 곳에서 turn on/off별 상태를 제어할 수 있다.
- CaptureManager : BarcodeView를 제어한다. 여기서는 DecoratedBarcodeView를 제어한다.
- DecoratedBarcodeView : Custom된 스캐너 레이아웃을 넣기 위한 뷰
5. activity_custom_scanner.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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=".webview.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"> </com.journeyapps.barcodescanner.DecoratedBarcodeView> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#578e5d"> </LinearLayout> <ImageButton android:padding="7dp" android:background="@null" android:src="@drawable/ic_menu_manage" android:id="@+id/setting_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <ImageButton android:onClick="switchFlashlight" android:padding="7dp" android:background="@null" android:src="@drawable/ic_menu_flash" android:id="@+id/switch_flashlight" android:scaleType="fitXY" android:layout_width="@dimen/dp_42" android:layout_height="@dimen/dp_42" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> <LinearLayout android:gravity="center_horizontal" android:layout_width="match_parent" android:layout_height="250dp" android:background="#578e5d" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"> <TextView android:id="@+id/zxing_status_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/zxing_transparent" android:text="@string/zxing_msg_default_status" android:textColor="@color/zxing_status_text" /> </LinearLayout> </RelativeLayout> | cs |
6. custom_barcode_scanner.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"> <com.journeyapps.barcodescanner.BarcodeView android:layout_marginBottom="200dp" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/zxing_barcode_surface" app:zxing_framing_rect_width="250dp" app:zxing_framing_rect_height="100dp"/> <com.journeyapps.barcodescanner.ViewfinderView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/zxing_viewfinder_view" app:zxing_possible_result_points="@color/zxing_custom_possible_result_points" app:zxing_result_view="@color/zxing_custom_result_view" app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser" app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/> </merge> | cs |
- BarcodeView : 스캐너 화면, zxing_framing_rect_width/height로 바코드 애니메이션 효과존을 설정 할 수 있다.
- ViewfinderView : 카메라의 뷰파인더와 같은 역할. 일반적으로 BarcodeView보다 큰 사이즈를 가진다.
728x90
반응형
'Android, iOS' 카테고리의 다른 글
[Gradle] 다 같은 Implementation이 아닌가? (0) | 2018.06.29 |
---|---|
Gradle - buildTypes 옵션 (0) | 2018.06.25 |
WebView size 문제로 빡칠 때 (2) | 2018.06.08 |
Toolbar를 만들었는데 Statusbar가 가리고 있다면?? (0) | 2018.06.07 |
intent.addFlags로 자주 쓰는 상수 세트 (0) | 2018.05.31 |
Comment