Dima
Dima

Reputation: 707

ZXing double image/overlay after scan

I am using the ZXing library, fully integrated with jar files, in my Android app and have the following problem:

Problem:

After scanning a barcode, the scanned image stays on top on the live camera feed at about 50% transparency for about 1-2 seconds.

Question:

Is there any way to have just the scanned image appear at 0% transparency, instead of the strange overlay? Or, even better, can it show a custom fragment?

Thank you.

Code: [w/o unrelated parts]

public static void initiateScan(Fragment fragment) {
    IntentIntegrator ii = new IntentIntegrator(fragment);
    DisplayMetrics dm = fragment.getResources().getDisplayMetrics();
    ii.addExtra("SCAN_WIDTH", dm.heightPixels);
    ii.addExtra("SCAN_HEIGHT", dm.widthPixels / 4);
    ii.addExtra("SCAN_MODE", "ONE_D_MODE");

    List<String> c = new ArrayList<String>();
    c.add("CODE_39");

    ii.initiateScan(c, -1);
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode==IntentIntegrator.REQUEST_CODE) { // scan from ZXing
        String raw_vin=null;
        String vin = null;
        boolean success=false;

        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, 
                                resultCode, data);
        if(result!=null)
        {
            String content = result.getContents();
            if(content!=null)
            {
                raw_vin=content;
                vin=raw_vin;
                success=true;
            }
        }
    }
}

Example:

Example of double image

Upvotes: 5

Views: 1587

Answers (3)

Andrei T
Andrei T

Reputation: 3083

My approach is the following:

//start the scanning
public void startQRCodeScanning() {
    IntentIntegrator integrator = IntentIntegrator.forFragment(this);
    integrator.setCaptureActivity(ScanActivity);
    integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
    integrator.setBeepEnabled(false);
    integrator.setOrientationLocked(true);
    integrator.initiateScan();
}

//onActivityResult:
 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
    if (result != null) {
        if (result.getContents() == null) {
            Log.d(TAG, "Cancelled scan");
            //we want to finish the current activity
            //as it does not make sense to do anything else
            finishActivity();
        } else {
            Log.d(TAG, "Scanned " + result.getContents());
            setConnectionString(result.getContents());
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

//next I have the QRCodeScanningActivity

    public class QRCodeScannerActivity extends Activity {

    private CaptureManager capture;
    private CompoundBarcodeView barcodeScannerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_scanner);

        if (getResources().getBoolean(R.bool.portrait_only)) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }

        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
        }

        barcodeScannerView = (CompoundBarcodeView)findViewById(R.id.zxing_barcode_scanner);

        capture = new CaptureManager(this, barcodeScannerView);
        capture.initializeFromIntent(getIntent(), savedInstanceState);
        capture.decode();
    }

    @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);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
 }

 //Next you need to define the layouts and everything.
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/black">

    <com.journeyapps.barcodescanner.CompoundBarcodeView
            android:id="@+id/zxing_barcode_scanner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:zxing_scanner_layout="@layout/barcode_scanner_layout"/>

    </FrameLayout>
</RelativeLayout>

Upvotes: 0

Neo
Neo

Reputation: 1469

I am not able to explain why this problem happen, but I am using ZXing for my barcode scanner application without 50% transparent as you. The following is my solution:

Layout:

<com.journeyapps.barcodescanner.CompoundBarcodeView
    android:id="@+id/barcode_scanner"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_margin="2dp">

</com.journeyapps.barcodescanner.CompoundBarcodeView>

In fragment:

private CompoundBarcodeView barcodeView;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }

        View v = inflater.inflate(R.layout.webservice_layout, container, false);

        barcodeView = (CompoundBarcodeView) v.findViewById(R.id.barcode_scanner);

        barcodeView.decodeContinuous(callback);
......
}

Callback function:

private BarcodeCallback callback = new BarcodeCallback() {
        @Override
        public void barcodeResult(BarcodeResult result) {

            if (SOAP_ACTION.equals("") || SOAP_METHOD.equals("") || soapProperty.equals("")) {
                barcodeView.pause();
            } else {
                if (result.getText() != null) {
                    barcodeView.setStatusText(result.getText());

                    barcodeView.pause();

                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            barcodeView.resume();
                        }
                    }, 1000);
                }
            }
        }
};

Hope this help!

Upvotes: 0

Ray Hunter
Ray Hunter

Reputation: 15557

Here is what I have in the build.gradle file for dependencies:

compile 'com.google.zxing:core:3.2.1'
compile 'com.journeyapps:zxing-android-embedded:3.0.3@aar'

Try this in the initiateScan method:

public static void initiateScan(Fragment fragment) {
    IntentIntegrator ii = IntentIntegrator.forSupportFragment(fragment);
    DisplayMetrics dm = fragment.getResources().getDisplayMetrics();
    ii.addExtra("SCAN_WIDTH", dm.heightPixels);
    ii.addExtra("SCAN_HEIGHT", dm.widthPixels / 4);
    ii.addExtra("SCAN_MODE", "ONE_D_MODE");
    ii.initiateScan(Collections.singletonList("CODE_39"));
}

Let me know how that works for you.

Upvotes: 1

Related Questions