ravi8x / Barcode-Reader

Android barcode reader using google vision library
BSD 3-Clause "New" or "Revised" License
294 stars 183 forks source link

Google Vision Api Camera preview issue #37

Open Maheswaran140387 opened 4 years ago

Maheswaran140387 commented 4 years ago

I am facing the below issue while using the google vision api for scanning qr code.

Detector processor must first be set with setProcessor in order to receive detection results. site:stackoverflow.com

can you please help me on this?

The camera preview is not opening at the first time, also I am unable to update the UI once the scan is successful.

Below is my code

{

private BusinessModel bmodel;
private DisplayMetrics displaymetrics;
private boolean is7InchTablet;
private SurfaceView surfaceView;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
private Button startVisit,btn_scan;
private Spinner reasonSpinnerForScanFailed,qrcodeTypeSpinner;
private boolean isScanSuccussfull;
private ArrayAdapter<ReasonMaster> reasonAdapterForScanFailed,adapterqrtype;
private String type = "0",reason = "0";
private SparseArray<Barcode> response;
private TextView tvresult;
private AlertDialog.Builder builder;
private AlertDialog alertDialog;
private static String TAG = "XCYCLE";
private boolean isCameraEnabled;

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

    bmodel = (BusinessModel) getApplicationContext();
    bmodel.setContext(this);
    Log.i(TAG, "onCreate()");
    overridePendingTransition(R.anim.trans_left_in, R.anim.trans_left_out);
    displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    is7InchTablet = this.getResources().getConfiguration().isLayoutSizeAtLeast(SCREENLAYOUT_SIZE_LARGE);

    Toolbar toolbar = findViewById(R.id.toolbar);
    if (toolbar != null) {
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayShowTitleEnabled(false);
            setScreenTitle("QR Code Scan");
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        }
    }

    startVisit = (Button)findViewById(R.id.save);
    btn_scan = (Button)findViewById(R.id.scan);
    tvresult = (TextView)findViewById(R.id.tvresult);
    surfaceView = (SurfaceView)findViewById(R.id.cameraview);
    reasonSpinnerForScanFailed = (Spinner)findViewById(R.id.reasonspinnerforscanfailed);
    qrcodeTypeSpinner = (Spinner)findViewById(R.id.qrcodetypespinner);
    startVisit.setOnClickListener(this);
    btn_scan.setOnClickListener(this);
    if(getIntent().getExtras() != null)
        type = getIntent().getExtras().getString("type");

    if(checkAndRequestPermissionAtRunTime(2))
        startScan();
}

@Override
protected void onStart() {
    super.onStart();
    Log.i(TAG, "onStart()");
    loadTypeSpinner();
    loadReasonSpinner();

    qrcodeTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            ReasonMaster qrtype = (ReasonMaster) adapterView.getSelectedItem();
            type = qrtype.getReasonID();
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

    reasonSpinnerForScanFailed.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            ReasonMaster reasonMaster = (ReasonMaster) adapterView.getSelectedItem();
            reason = reasonMaster.getReasonID();
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

}

private void startScan() {

    try {

        barcodeDetector = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.QR_CODE).build();
        cameraSource = new CameraSource.Builder(QRCodeScan.this, barcodeDetector)
                .setRequestedPreviewSize(400, 400)
                .build();

        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback2() {
            @Override
            public void surfaceRedrawNeeded(SurfaceHolder surfaceHolder) {
                Toast.makeText(QRCodeScan.this, "surfaceRedrawNeeded()", Toast.LENGTH_LONG).show();
            }

            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                try {
                    Toast.makeText(QRCodeScan.this, "surfaceCreated()", Toast.LENGTH_LONG).show();
                    cameraSource.start(surfaceView.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
                Toast.makeText(QRCodeScan.this, "surfaceChanged()", Toast.LENGTH_LONG).show();
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                Toast.makeText(QRCodeScan.this, "surfaceDestroyed()", Toast.LENGTH_LONG).show();
                cameraSource.stop();
            }
        });

        barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
            @Override
            public void release() {
            }

            @Override
            public void receiveDetections(Detector.Detections<Barcode> detections) {

                try
                {
                    response = detections.getDetectedItems();
                    if (response != null && response.size() > 0) {
                        barcodeDetector.release();
                        isScanSuccussfull = true;
                        if (validateAndSave()) {
                            moveToHomeScreenTwo();
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }catch (Exception e){
        e.printStackTrace();
    }
}

@Override
protected void onResume() {
    super.onResume();
    Log.i(TAG, "onResume()");
    checkAndRequestPermissionAtRunTime(2);
    int permissionStatus = ContextCompat.checkSelfPermission(this,
            Manifest.permission.CAMERA);
    if (permissionStatus == PackageManager.PERMISSION_GRANTED) {
        startScan();
    } else {
        Toast.makeText(this,
                getResources().getString(R.string.permission_enable_msg)
                        + " " + getResources().getString(R.string.permission_camera)
                , Toast.LENGTH_LONG).show();
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == android.R.id.home) {
        startActivity(new Intent(this, ProfileActivity.class));
        overridePendingTransition(R.anim.trans_right_in, R.anim.trans_right_out);
        finish();
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View view) {
    switch (view.getId()) {

        case R.id.save: {
            if (type.equals("0"))
                Toast.makeText(QRCodeScan.this, getResources().getString(R.string.qr_type_alert), Toast.LENGTH_LONG).show();
            else if(reason.equals("0")){
                Toast.makeText(QRCodeScan.this, getResources().getString(R.string.qr_reason), Toast.LENGTH_LONG).show();
            }else {
                if(validateAndSave())
                    moveToHomeScreenTwo();
                else
                    Toast.makeText(QRCodeScan.this, getResources().getString(R.string.qr_try_again), Toast.LENGTH_LONG).show();
            }
        }

        case R.id.scan: {
            if(checkAndRequestPermissionAtRunTime(2)) {
                if (!type.isEmpty() && !type.equals("0"))
                    startScan();
                else
                    Toast.makeText(QRCodeScan.this, getResources().getString(R.string.qr_type_alert), Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(this,getResources().getString(R.string.qr_camera_permission),Toast.LENGTH_LONG).show();
            }
        }
    }
}

private void moveToHomeScreenTwo(){
    Toast.makeText(QRCodeScan.this, "Scanned Success", Toast.LENGTH_LONG);
    Intent i = new Intent(this, HomeScreenTwo.class);
    i.putExtra("isLocDialog", true);
    i.putExtra("isMandatoryDialog", true);
    i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    startActivity(i);
    finish();
}

private boolean validateAndSave(){
    String val = "";
    try{
        if(isScanSuccussfull)
            val = response.valueAt(0).displayValue;

        if(bmodel.getAppDataProvider().getRetailMaster().getListOfQRCodeValues() == null)
            return bmodel.qrCodeHelper.saveQRCodeScannedData(type, val, reason , "I");
        else if(!val.isEmpty() && !bmodel.getAppDataProvider().getRetailMaster().getListOfQRCodeValues().contains(val)) {
            isScanSuccussfull = false;
            return false;
        }else
            return bmodel.qrCodeHelper.saveQRCodeScannedData(type, val, reason, "A");
    }catch (Exception e){
        e.printStackTrace();
        return false;
    }
}

private void loadReasonSpinner(){
    try{
        reasonAdapterForScanFailed = new ArrayAdapter<>(this,
                R.layout.call_analysis_spinner_layout);
        reasonAdapterForScanFailed.add(new ReasonMaster(0 + "", getResources().getString(R.string.select_reason)));
        if (bmodel.qrCodeHelper.getQrCodeReasons() != null) {
            for (ReasonMaster temp : bmodel.qrCodeHelper.getQrCodeReasons())
                reasonAdapterForScanFailed.add(temp);

            reasonAdapterForScanFailed.add(new ReasonMaster(-1 + "", getResources().getString(R.string.other_reason)));
        }
        reasonAdapterForScanFailed.setDropDownViewResource(R.layout.call_analysis_spinner_list_item);
        reasonSpinnerForScanFailed.setAdapter(reasonAdapterForScanFailed);
    }catch (Exception e){
        e.printStackTrace();
    }
}

private void loadTypeSpinner(){
    try{
        adapterqrtype = new ArrayAdapter<>(this,
                R.layout.call_analysis_spinner_layout);
        adapterqrtype.add(new ReasonMaster(0 + "", getResources().getString(R.string.qr_hint_type)));
        if (bmodel.qrCodeHelper.getQrCodeReasons() != null) {
            for (ReasonMaster temp : bmodel.qrCodeHelper.getQrCodeTypes())
                adapterqrtype.add(temp);
        }
        adapterqrtype.setDropDownViewResource(R.layout.call_analysis_spinner_list_item);
        qrcodeTypeSpinner.setAdapter(adapterqrtype);
    }catch (Exception e){
        e.printStackTrace();
    }
}

private void openCamera(){
    try{
        cameraSource.start(surfaceView.getHolder());
    }catch (Exception e){
        e.printStackTrace();
    }
}

}

simiyu1 commented 4 years ago

This would be better handled in Stackoverflow... it is not an error within the API but with your code. As pointed out when you set the processor

barcodeDetector.setProcessor(new Detector.Processor<Barcode>() 

should be something like

BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(context).build();
        BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(mGraphicOverlay, this);
        barcodeDetector.setProcessor(
                new MultiProcessor.Builder<>(barcodeFactory).build())

and then to get the results

@Override
    public void onBarcodeDetected(Barcode barcode) {
        //do something with barcode data returned
    }

checkout out this Google sample on this class.