I want to create a modular class that I can use anytime I want to scan a barcode. Is this possible using Firebase ML Kit?
This is what I've got so far:
public List<FirebaseVisionBarcode> ScanBarcode(int... barcodeFormats)
{
//region Init, config and execution of the barcode scanning
final FirebaseVisionBarcodeDetectorOptions.Builder BUILDER =
new FirebaseVisionBarcodeDetectorOptions.Builder();
//Set barcode formats based on arguments
for (int formats : barcodeFormats)
{
BUILDER.setBarcodeFormats(formats);
}
final FirebaseVisionBarcodeDetectorOptions OPTIONS = BUILDER.build();
final FirebaseVisionImage IMAGE = FirebaseVisionImage.fromBitmap(bitmap);
final FirebaseVisionBarcodeDetector DETECTOR = FirebaseVision.getInstance()
.getVisionBarcodeDetector(OPTIONS);
DETECTOR.detectInImage(IMAGE)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>()
{
@Override
public void onSuccess(List<FirebaseVisionBarcode> _barcodes)
{
barcodes = _barcodes;
}
})
.addOnFailureListener(new OnFailureListener()
{
@Override
public void onFailure(@NonNull Exception e)
{
barcodes = new ArrayList<>();
}
});
//endregion
return barcodes;
Mostly taken from https://firebase.google.com/docs/ml-kit/
The problem here is that the listener, for the DETECTOR
, is some kind of async call. Which means that it will return before onSuccess
is called.
The barcode scanning part works, but I'm having a hard time wrapping it in a class of it's own.
Thanks.
I figured it out. Not sure if it's the best approach class structure wise, but it works quite nice.
public Task<List<FirebaseVisionBarcode>> ScanBarcode(int... barcodeFormats)
{
//region Init, config and execution of the barcode scanning. Mostly taken from https://firebase.google.com/docs/ml-kit/
final FirebaseVisionBarcodeDetectorOptions.Builder BUILDER =
new FirebaseVisionBarcodeDetectorOptions.Builder();
//Set barcode formats based on arguments
for (int formats : barcodeFormats)
{
BUILDER.setBarcodeFormats(formats);
}
final FirebaseVisionBarcodeDetectorOptions OPTIONS = BUILDER.build();
final FirebaseVisionImage IMAGE = FirebaseVisionImage.fromBitmap(bitmap);
final FirebaseVisionBarcodeDetector DETECTOR = FirebaseVision.getInstance()
.getVisionBarcodeDetector(OPTIONS);
final Task<List<FirebaseVisionBarcode>> DETECT_IMG_TASK = DETECTOR.detectInImage(IMAGE)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>()
{
@Override
public void onSuccess(List<FirebaseVisionBarcode> _barcodes)
{
barcodes = _barcodes;
}
})
.addOnFailureListener(new OnFailureListener()
{
@Override
public void onFailure(@NonNull Exception e)
{
barcodes = new ArrayList<>();
}
});
return DETECT_IMG_TASK;
//endregion
}
public List<FirebaseVisionBarcode> GetBarcodes()
{
return barcodes;
}
detectInImage
returns a Task
. What I did was return this task. Once this task completes, you can call GetBarcodes
to obtain the parsed data. I hate to force calling additional methods to get the final results, but it was the only way I could get it to work.