Skip to content

Commit

Permalink
✨ feat: add support for specifying specific targeted formats (capacit…
Browse files Browse the repository at this point in the history
…or-community#19)

* ♻️ [android] refactor dismantling related code

* ✨ [android] add support for specifying formats

* ✨ [ios] add support for specifying formats

* ✨ add TypeScript definitions

* ✨ add TypeScript definitions

* 🔖 v1.2.0-alpha.0

* 🔖 v1.2.0-alpha.1

* 🔖 v1.2.0-alpha.2

* 📝 update readme (capacitor-community#18)

* 📝 update readme

* 📝 update readme
  • Loading branch information
tafelnl authored Mar 16, 2021
1 parent cbae5b7 commit 0006029
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 39 deletions.
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

0 comments on commit 0006029

Please sign in to comment.