1

I am using the quickstart-android code provided by google but after many attempts I cam unable to find a context that is not returning null. The BarcodeScannerProcessor is not itself an Activity, so I have attempted to create an instance of the LivePreviewActivity and use that as the context in the intent, but it's null.

The goal is to once a valid barcode is recognized I want to open a new activity that allows a user to verify value and on the push of a button call a webservice to post the barcode to a database via API. I am having a hard time finding a valid context and the app is crashing when it trys to execute the Intent.

Starting at line 97-107:

https://github.com/jamiekeefer/quickstart-android/blob/master/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java/barcodescanning/BarcodeScanningProcessor.java

        for (int i = 0; i < barcodes.size(); ++i) {
        FirebaseVisionBarcode barcode = barcodes.get(i);
        BarcodeGraphic barcodeGraphic = new BarcodeGraphic(graphicOverlay, barcode);
        graphicOverlay.add(barcodeGraphic);

        System.out.println(barcode.getRawValue());

        if (!barcode.getRawValue().equals("") ) {

            System.out.println("Got the number:" + barcode.getRawValue() + " Context: " + mContext); //OLD SCHOOL DEBUG OUTPUT

            //enter code to start activity

                Intent intent = new Intent(mContext, SendScannedBarcode.class);
                String message = scannedBarcode;
                intent.putExtra(EXTRA_MESSAGE, message);
                mContext.startActivity(intent);
        }


    }

You can back up in the repo to see the instance of the LivePreviewActivity where I trying to get context.

I have tried a number of things and read about Context, Views and Activities and basically have completely confused myself. The only tuts I can find are using Kotlin, which is not helping clarify things.

I appreacite any help in indentifying or contruting a valid Intent from this Context. Thank you.

Ben Weiss
  • 17,182
  • 6
  • 67
  • 87

4 Answers4

1

So I am assuming that in your LivePreviewActivity you are creating an object of the class BarcodeScanningProcessor. What you can do is change the constructor in the BarcodeScanningProcessor class to accept a context and then you pass in your LivePreviewActivity's context.

This is what the code should look like:

In BarcodeScanningProcessor:

  public BarcodeScanningProcessor(Context context) {
    // Note that if you know which format of barcode your app is dealing with, detection will be
    // faster to specify the supported barcode formats one by one, e.g.
    // new FirebaseVisionBarcodeDetectorOptions.Builder()
    // .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE)
    // .build();
    detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
    this.mContext = context;
}

Then in LivePreviewActivity:

In the particular case of your activity you would do:

  case BARCODE_DETECTION:
          Log.i(TAG, "Using Barcode Detector Processor");
          cameraSource.setMachineLearningFrameProcessor(new BarcodeScanningProcessor(getApplicationContext()));
          break;

Or if you just wanted to create an object of the class you could do: BarcodeScanningProcessor bsp = new BarcodeScanningProcessor(getApplicationContext());

This should now give your BarcodeScanningProcessor class the context of your activity. Now, in BarcodeScanningProcessor, mContext should not be null and will have the context of your activity. I hope this answers your question.

Ishaan Javali
  • 1,711
  • 3
  • 13
  • 23
  • So I am assuming that in your LivePreviewActivity you are creating an object of the class BarcodeScanningProcessor. What you can do is change the constructor in the BarcodeScanningProcessor class to accept a context and then you pass in your LivePreviewActivity's context. --- AHH! Let me give that a try. That makes sense. – Jamie Keefer Nov 20 '18 at 17:05
  • Yes. Try the code above. I am certain that it should work now that your `BarcodeScanningProcessor` class will have the context of your activity. If it works, please mark this answer as accepted so that those with similar problems can refer to it and get help as well. – Ishaan Javali Nov 20 '18 at 17:08
  • Ishaan, I can not thank you enough for answering so quickly. I will certainly mark as accepted once I can verify it works, which I am confident it will. My android studio install needs to patch so it may be a while, I am about get on an airplane and this network is not patching very well :/. I will be sure follow up. Thank you very much. – Jamie Keefer Nov 20 '18 at 17:22
  • You are welcome. I hope that when you land and test it, it works. Make sure that you are on a good network though! – Ishaan Javali Nov 20 '18 at 23:21
  • Hello Jamie. Have you been able to test my solution? If it didn't work, just post the problem you got below. – Ishaan Javali Nov 21 '18 at 17:20
  • Hello Jamie, have you been able to test my answer yet? – Ishaan Javali Nov 22 '18 at 17:48
  • I am having to delete and reinstall gradle...there is something wrong with my android studio install on this machine and can't build the executable. I will be sure to let you know. – Jamie Keefer Nov 23 '18 at 20:23
  • Just reiterating this solution worked and was the simplest to implement. – Jamie Keefer Nov 24 '18 at 22:12
1

try this create Application class

import android.app.Application;

public class MyApplication  extends Application {
    static MyApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance=this;
    }

    public static MyApplication getInstance() {
        return instance;
    }
}

Register in manifest file

<application
        ..
        android:name="com.yourpackage.MyApplication"
        ..>
.
.
.
</application>

start activity using this MyApplication.

Intent intent = new Intent(MyApplication.getInstance(), SendScannedBarcode.class);
                String message = scannedBarcode;
                intent.putExtra(EXTRA_MESSAGE, message);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
               MyApplication. getInstance().startActivity(intent);
Mr X
  • 1,053
  • 2
  • 11
  • 24
1

Another way of handling the issue is create new constructor of BarcodeScanningProcessor which takes interface call back and once processing is done pass back result to caller.

   public interface BarcodeUpdateListener {
      @UiThread
      void onBarcodeDetected(Barcode barcode);
   } 


   private BarcodeUpdateListener callback;

   public BarcodeScanningProcessor(BarcodeUpdateListener callback){
      this.callback = callback;
      detector = FirebaseVision.getInstance().getVisionBarcodeDetector();
   } 

Once you get the result pass result to caller

callback.onBarcodeDetected(<Barcode>)
Ramesh Yankati
  • 1,197
  • 9
  • 13
1

You can get the context from graphicOverlay:

Context context = graphicOverlay.getContext();