Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: add support for specifying specific targeted formats #19

Merged
merged 9 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 132 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ const didUserGrantPermission = async () => {
return false;
};

checkPermission();
didUserGrantPermission();
```

If a user denied the permission for good, `status.denied` will be set to true. On Android this will happen only when the user checks the box `never ask again`. To get the permission anyway you will have to redirect the user to the settings of the app. This can be done simply be doing the following:
Expand All @@ -377,13 +377,142 @@ const checkPermission = async () => {
};
```

### Target only specific barcodes

You can setup the scanner to only recognize specific types of barcodes like this:

`BarcodeScanner.startScan({ targetedFormats: ['QR_CODE'] })`

If `targetedFormats` is _not specified_ or _left empty_, _all types_ of barcodes will be targeted.

The following types are supported:

<table>
<thead>
<tr>
<th>Category</th>
<th>Type</th>
<th>Android</th>
<th>iOS</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="6">1D Product</td>
</tr>
<tr>
<td>UPC_A</td>
<td>✔</td>
<td>✔**</td>
</tr>
<tr>
<td>UPC_E</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>UPC_EAN_EXTENSION</td>
<td>✔</td>
<td>✖</td>
</tr>
<tr>
<td>EAN_8</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>EAN_13</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td rowspan="8">1D Industrial</td>
</tr>
<tr>
<td>CODE_39</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>CODE_39_MOD_43</td>
<td>✖</td>
<td>✔</td>
</tr>
<tr>
<td>CODE_93</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>CODE_128</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>CODABAR</td>
<td>✔</td>
<td>✖</td>
</tr>
<tr>
<td>ITF</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>ITF_14</td>
<td>✖</td>
<td>✔</td>
</tr>
<tr>
<td rowspan="8">2D</td>
</tr>
<tr>
<td>AZTEC</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>DATA_MATRIX</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>MAXICODE</td>
<td>✔</td>
<td>✖</td>
</tr>
<tr>
<td>PDF_417</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>QR_CODE</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>RSS_14</td>
<td>✔</td>
<td>✖</td>
</tr>
<tr>
<td>RSS_EXPANDED</td>
<td>✔</td>
<td>✖</td>
</tr>
</tbody>
</table>

\*\* `UPC_A` is supported on iOS, but according to the offical [Apple docs](https://developer.apple.com/documentation/avfoundation/avmetadataobject/objecttype/1618807-ean13) it is part of `EAN_13`. So you should specify `EAN_13` to be able to scan this. If you want to distinguish them from one another, you should manually do so after getting the result.

## Troubleshooting

1. I have a `Error: Plugin BarcodeScanner does not respond to method call` error message on iOS
### I have a `Error: Plugin BarcodeScanner does not respond to method call` error message on iOS

In Xcode click on `Product` > `Clean Build Folder` and try to build again.

2. I have a `Cannot resolve symbol BarcodeScanner` error message in Android Studio
### I have a `Cannot resolve symbol BarcodeScanner` error message in Android Studio

In Android Studio click `File` > `Sync Project with Gradle Files` and try to build again.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,25 @@
import android.util.Log;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.NativePlugin;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.ResultPoint;
import com.journeyapps.barcodescanner.BarcodeCallback;
import com.journeyapps.barcodescanner.BarcodeResult;
import com.journeyapps.barcodescanner.BarcodeView;
import com.journeyapps.barcodescanner.DefaultDecoderFactory;
import com.journeyapps.barcodescanner.camera.CameraSettings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONException;

@NativePlugin(permissionRequestCode = BarcodeScanner.REQUEST_CODE)
public class BarcodeScanner extends Plugin implements BarcodeCallback {
Expand All @@ -38,7 +46,34 @@ public class BarcodeScanner extends Plugin implements BarcodeCallback {
private boolean didRunCameraSetup = false;
private boolean didRunCameraPrepare = false;
private boolean isBackgroundHidden = false;
private String actionOnResume = null;

// declare a map constant for allowed barcode formats
private static final Map<String, BarcodeFormat> supportedFormats = supportedFormats();

private static Map<String, BarcodeFormat> supportedFormats() {
Map<String, BarcodeFormat> map = new HashMap<>();
// 1D Product
map.put("UPC_A", BarcodeFormat.UPC_A);
map.put("UPC_E", BarcodeFormat.UPC_E);
map.put("UPC_EAN_EXTENSION", BarcodeFormat.UPC_EAN_EXTENSION);
map.put("EAN_8", BarcodeFormat.EAN_8);
map.put("EAN_13", BarcodeFormat.EAN_13);
// 1D Industrial
map.put("CODE_39", BarcodeFormat.CODE_39);
map.put("CODE_93", BarcodeFormat.CODE_93);
map.put("CODE_128", BarcodeFormat.CODE_128);
map.put("CODABAR", BarcodeFormat.CODABAR);
map.put("ITF", BarcodeFormat.ITF);
// 2D
map.put("AZTEC", BarcodeFormat.AZTEC);
map.put("DATA_MATRIX", BarcodeFormat.DATA_MATRIX);
map.put("MAXICODE", BarcodeFormat.MAXICODE);
map.put("PDF_417", BarcodeFormat.PDF_417);
map.put("QR_CODE", BarcodeFormat.QR_CODE);
map.put("RSS_14", BarcodeFormat.RSS_14);
map.put("RSS_EXPANDED", BarcodeFormat.RSS_EXPANDED);
return Collections.unmodifiableMap(map);
}

private boolean hasCamera() {
// @TODO(): check: https://stackoverflow.com/a/57974578/8634342
Expand Down Expand Up @@ -83,7 +118,7 @@ private void setupCamera() {
didRunCameraSetup = true;
}

private void dismantleCamera(Boolean freeSavedCallFlag) {
private void dismantleCamera() {
// opposite of setupCamera

getActivity()
Expand All @@ -102,15 +137,15 @@ private void dismantleCamera(Boolean freeSavedCallFlag) {
didRunCameraPrepare = false;

// If a call is saved and a scan will not run, free the saved call
if (freeSavedCallFlag && getSavedCall() != null && !shouldRunScan) {
if (getSavedCall() != null && !shouldRunScan) {
freeSavedCall();
}
}

private void prepare() {
// undo previous setup
// because it may be prepared with a different config
dismantleCamera(true);
dismantleCamera();

// setup camera with new config
setupCamera();
Expand All @@ -126,7 +161,46 @@ private void prepare() {
private void destroy() {
showBackground();

dismantleCamera(true);
dismantleCamera();
}

private void configureCamera() {
getActivity()
.runOnUiThread(
() -> {
PluginCall call = getSavedCall();

if (call == null || mBarcodeView == null) {
Log.d("scanner", "Something went wrong with configuring the BarcodeScanner.");
return;
}

if (call.hasOption("targetedFormats")) {
JSArray targetedFormats = call.getArray("targetedFormats");
ArrayList<BarcodeFormat> formatList = new ArrayList<>();

if (targetedFormats != null && targetedFormats.length() > 0) {
for (int i = 0; i < targetedFormats.length(); i++) {
try {
String targetedFormat = targetedFormats.getString(i);
BarcodeFormat targetedBarcodeFormat = supportedFormats.get(targetedFormat);
if (targetedBarcodeFormat != null) {
formatList.add(targetedBarcodeFormat);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}

if (formatList.size() > 0) {
mBarcodeView.setDecoderFactory(new DefaultDecoderFactory(formatList));
} else {
Log.d("scanner", "The property targetedFormats was not set correctly.");
}
}
}
);
}

private void scan() {
Expand All @@ -144,6 +218,8 @@ private void scan() {

shouldRunScan = false;

configureCamera();

final BarcodeCallback b = this;
getActivity()
.runOnUiThread(
Expand Down Expand Up @@ -202,20 +278,15 @@ public void barcodeResult(BarcodeResult barcodeResult) {

@Override
public void handleOnPause() {
if (isScanning) {
actionOnResume = "scan";
} else {
actionOnResume = null;
if (mBarcodeView != null) {
mBarcodeView.pause();
}
dismantleCamera(false);
}

@Override
public void handleOnResume() {
if (actionOnResume != null) {
if (actionOnResume.equals("scan")) {
scan();
}
if (mBarcodeView != null) {
mBarcodeView.resume();
}
}

Expand Down
Loading