javaandroidxmllayoutzxing

Android XzingScanner : How to customise ZxingScanner layout ? (add button)


I'm realising a barcode scanner using Zxing Scanner, everything is working for this part but now I would like to add one button on the layout (to toggle on/off flashlight). I checked everywhere on the internet but found nothing.

So, here is my questions :

This is how I'm calling ZXingScannerView :

scannerView = new ZXingScannerView(this);
setContentView(scannerView);

Solution

  • This is good to customize QR/Barcode scanner with ZXing library

    https://github.com/journeyapps/zxing-android-embedded

    You can see sample app project there and customize (add button, set flash on/off) in yourself.

    Also there is another library, but it's not using ZXing.

    https://github.com/googlesamples/android-vision

    It's deprecated, is now a part of ML Kit, but still is available to use.

    [Update]

    Please import this library into your project. (You can see how can import it from below link.)

    https://github.com/journeyapps/zxing-android-embedded#adding-aar-dependency-with-gradle

    After imported, you can update the layout.xml of your barcode scanner's activity.

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/topLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true">
    
        <com.journeyapps.barcodescanner.DecoratedBarcodeView
            android:id="@+id/barcode_scanner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center" />
        
        <Button
            android:id="@+id/btn_flash"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center"
            android:text="Flash"/>
        
    </FrameLayout>
    

    com.journeyapps.barcodescanner.DecoratedBarcodeView is BarcodeScanner view. And Button is just to turn on/off flash.

    This is BarcodeScanner's Activity.

    public class ScanQRActivity extends BaseActivity {
    
        private static final String TAG = "ScanQRActivity";
    
        private DecoratedBarcodeView barcodeView;
    
        private boolean isFlashOn;
    
        /**
         * Initializes the UI and creates the detector pipeline.
         */
        @Override
        public void onCreate(Bundle bundle) {
            super.onCreate(bundle);
            setContentView(R.layout.activity_scan_qr);
    
            isFlashOn = false;
    
            barcodeView = findViewById(R.id.barcode_scanner);
            Collection<BarcodeFormat> formats = Arrays.asList(BarcodeFormat.CODE_39); // Set barcode type
            barcodeView.getBarcodeView().setDecoderFactory(new DefaultDecoderFactory(formats));
            barcodeView.initializeFromIntent(getIntent());
            barcodeView.decodeContinuous(callback);
    
            Button btnFlash = findViewById(R.id.btn_flash);
            if (!hasFlash()) {
                btnFlash.setVisibility(View.GONE);
            }
            btnFlash.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switchFlashlight();
                }
            });
        }
    
        private BarcodeCallback callback = new BarcodeCallback() {
            @Override
            public void barcodeResult(BarcodeResult result) {
                Log.e(TAG, result.getText()); // QR/Barcode result
            }
    
            @Override
            public void possibleResultPoints(List<ResultPoint> resultPoints) {
            }
        };
    
        /**
         * Check if the device's camera has a Flashlight.
         *
         * @return true if there is Flashlight, otherwise false.
         */
        private boolean hasFlash() {
            return getApplicationContext().getPackageManager()
                    .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
        }
    
        public void switchFlashlight() {
            if (isFlashOn) {
                isFlashOn = false;
                barcodeView.setTorchOff();
            } else {
                isFlashOn = true;
                barcodeView.setTorchOn();
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            barcodeView.resume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            barcodeView.pause();
        }
    }
    

    When QR/Barcode is scanned, you can get result from BarcodeCallback.barcodeResult function.