commit a5841aa9dd0fe971771508be9ddf6cccd85d6bed
Author: langxiankui <33216671+langxiankui@users.noreply.github.com>
Date: Tue Jul 20 14:26:11 2021 +0800
Add files via upload
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..05960d8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "cordova-plugin-uhf",
+ "version": "0.0.1",
+ "description": "",
+ "cordova": {
+ "id": "cordova-plugin-uhf",
+ "platforms": [
+ "android"
+ ]
+ },
+ "keywords": [
+ "ecosystem:cordova",
+ "cordova-android"
+ ],
+ "author": "",
+ "license": "ISC"
+}
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..853f021
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,46 @@
+
+
+ Cordova UHF Plugin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/android/ModuleAPI_J.jar b/src/android/ModuleAPI_J.jar
new file mode 100644
index 0000000..b231d74
Binary files /dev/null and b/src/android/ModuleAPI_J.jar differ
diff --git a/src/android/cordova/plugin/uhf/UHF.java b/src/android/cordova/plugin/uhf/UHF.java
new file mode 100644
index 0000000..c0aee53
--- /dev/null
+++ b/src/android/cordova/plugin/uhf/UHF.java
@@ -0,0 +1,283 @@
+package cordova.plugin.uhf;
+
+import android.os.Message;
+import android.util.Log;
+import cn.pda.serialport.Tools;
+import com.handheld.uhfr.UHFRManager;
+import com.uhf.api.cls.Reader;
+import org.apache.cordova.CallbackContext;
+import org.apache.cordova.CordovaPlugin;
+import org.apache.cordova.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.*;
+
+
+/**
+ * 超高频(UHF)读写卡插件。
+ * 因不同的机型使用的so库不同,故无法适配所有机型。
+ */
+public class UHF extends CordovaPlugin {
+ private UHFRManager manager;
+ private String selectedEpc = "";
+ private byte[] password = Tools.HexString2Bytes("00000000");
+ private boolean threadFlag;
+
+ @Override
+ protected void pluginInitialize() {
+ super.pluginInitialize();
+ manager = UHFRManager.getInstance();
+ }
+
+ @Override
+ public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+ switch (action) {
+ case "readCard":
+ this.readCard(callbackContext);
+ return true;
+ case "searchCard":
+ this.searchCard(callbackContext);
+ return true;
+ case "stopSearchCard":
+ this.stopSearchCard(callbackContext);
+ return true;
+ case "writeCard":
+ this.writeCard(args, callbackContext);
+ return true;
+ case "setPower":
+ this.setPower(args, callbackContext);
+ return true;
+ case "startWork":
+ this.startWork(callbackContext);
+ return true;
+ case "endWork":
+ this.endWork(callbackContext);
+ return true;
+ case "selectCard":
+ this.selectCard(args, callbackContext);
+ break;
+ case "inventoryCard":
+ this.inventoryCard(callbackContext);
+ return true;
+ case "stopInventoryCard":
+ this.stopInventoryCard(callbackContext);
+ return true;
+ }
+ return false;
+ }
+
+
+ private void startWork(CallbackContext callbackContext) {
+ if (this.manager == null) {
+ manager = UHFRManager.getInstance();
+ }
+ callbackContext.success();
+ }
+
+ private void endWork(CallbackContext callbackContext) {
+ if (this.manager != null) {
+ this.manager.close();
+ this.manager = null;
+ }
+ callbackContext.success();
+ }
+
+
+ private void stopInventoryCard(CallbackContext callbackContext) {
+ threadFlag = false;
+ manager.asyncStopReading();
+ callbackContext.success("停止");
+ }
+
+ private void inventoryCard(CallbackContext callbackContext) {
+ threadFlag = true;
+ manager.asyncStartReading();
+ Thread thread = new InventoryThread(callbackContext);
+ thread.start();
+ }
+
+
+ /**
+ * 巡卡,每执行一次,就扫描一次范围内的卡片,将巡到的卡片信息以json数组的形式返回
+ */
+ private void searchCard(CallbackContext callbackContext) {
+ manager.asyncStartReading();
+ try {
+ Thread.sleep(100);
+ JSONArray ja = onceSearchCard();
+ manager.asyncStopReading();
+ callbackContext.success(ja);
+ } catch (Exception e) {
+ callbackContext.error(e.getMessage());
+ }
+ }
+
+ private JSONArray onceSearchCard() throws JSONException {
+ List list1;
+ list1 = manager.tagInventoryRealTime();
+ String data;
+ JSONArray ja = new JSONArray();
+ JSONObject jo;
+ if (list1 != null && list1.size() > 0) {
+ for (Reader.TAGINFO tfs : list1) {
+ jo = new JSONObject();
+ byte[] epcdata = tfs.EpcId;
+ data = Tools.Bytes2HexString(epcdata, epcdata.length);
+ int rssi = tfs.RSSI;
+ jo = new JSONObject();
+ jo.put("mEpcBytes", data);
+ jo.put("mRssi", rssi);
+ ja.put(jo);
+ }
+ }
+ return ja;
+ }
+
+ private class InventoryThread extends Thread {
+
+ private CallbackContext cb;
+
+ public InventoryThread(CallbackContext cb) {
+ super();
+ this.cb = cb;
+ }
+
+ public InventoryThread() {
+ super();
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ try {
+ while (threadFlag) {
+ JSONArray ja = onceSearchCard();
+ PluginResult pr = new PluginResult(PluginResult.Status.OK, ja);
+ pr.setKeepCallback(true);
+ cb.sendPluginResult(pr);
+ Thread.sleep(100);
+ }
+ } catch (Exception e) {
+ cb.error(e.getMessage());
+ }
+ }
+ }
+
+ private void stopSearchCard(CallbackContext callbackContext) {
+ manager.asyncStopReading();
+ callbackContext.success("巡卡停止");
+ }
+
+ /**
+ * 读卡,将USER区的hex字符串转换为ascii读取,因EPC区与TID区不能写入,故暂时只读取USER区,注释掉的部分为适应EPC区与TID区读取的代码
+ * 将注释解开后应抛出JSONException
+ */
+ private void readCard(CallbackContext callbackContext) {
+// JSONObject obj = message.getJSONObject(0);
+// int site = obj.getInt("site");
+// int addr = obj.getInt("addr");
+// if (site == 1) {
+// addr = 2;
+// length = 6;
+// } else if (site == 3) {
+// addr = 0;
+// length = 32;
+// } else if (site == 2) {
+// addr = 0;
+// length = 12;
+// }
+// manager.selectEPC(Tools.HexString2Bytes(this.selectedEpc));
+ int length = 32;
+// byte[] data = manager.readFrom6C(3, 0, length, password);
+ byte[] data = new byte[length * 2];
+ if (this.selectedEpc.length() == 0) {
+ manager.getTagData(3, 0, length, data, password, (short) 1000);
+ } else {
+ data = manager.getTagDataByFilter(3, 0, length, password, (short) 1000, Tools.HexString2Bytes(this.selectedEpc), 1, 0, true);
+ }
+ if (data != null && data.length >= 1) {
+ String msg;
+// if (site == 3) { // 读取User区的时候,将16进制字符串转换为ascii
+ msg = Util.bytes2Str(data);
+// } else { // 因EPC区与TID区不能写入,故读取时不转码
+// msg = Tools.Bytes2HexString(data, data.length);
+// }
+ callbackContext.success(msg);
+ } else {
+ callbackContext.error("读取失败");
+ }
+ }
+
+ /**
+ * 选卡,将选到的卡储存在this.selectedEpc中
+ */
+ private void selectCard(JSONArray message, CallbackContext callbackContext) throws JSONException {
+ JSONObject obj = message.getJSONObject(0);
+ String epc = obj.getString("epc");
+// manager.selectEPC(Tools.HexString2Bytes(epc));
+ this.selectedEpc = epc;
+ callbackContext.success();
+ }
+
+ /**
+ * 写卡,将ascii转换为bytes并写入
+ */
+ private void writeCard(JSONArray message, CallbackContext callbackContext) {
+// manager.selectEPC(Tools.HexString2Bytes(this.selectedEpc));
+ String _data = null;
+ try {
+ JSONObject obj = message.getJSONObject(0);
+ _data = Util.str2HexStr(obj.getString("data"));
+ } catch (JSONException e) {
+ callbackContext.error("JSON解析失败");
+ }
+ // 处理_data,将ascii转换为16进制字符串,超过32 * 4位的16进制字符串报错,小于32 * 4时在16进制字符串末位补0x00作为完结标记,再转换为bytes
+ if (_data != null && _data.length() > 32 * 4) {
+ callbackContext.error("数据过长");
+ return;
+ }
+ if (_data.length() < 32 * 4) {
+ _data += "00";
+ }
+ byte[] dataBytes = Util.hexStringToBytes(_data);
+ boolean writeFlag = false;
+ Reader.READER_ERR er = null;
+ if (dataBytes != null) {
+ if (this.selectedEpc.length() > 0) {
+ er = manager.writeTagDataByFilter((char) 3, 0, dataBytes, dataBytes.length / 2, password, (short) 1000, Tools.HexString2Bytes(this.selectedEpc), 1, 0, true);
+ } else {
+ er = manager.writeTagData((char) 3, 0, dataBytes, dataBytes.length / 2, password, (short) 1000);
+ }
+// writeFlag = manager.writeTo6C(password, 3, 0, dataBytes.length / 2, dataBytes);
+ }
+ if (er == Reader.READER_ERR.MT_OK_ERR) {
+ callbackContext.success("写入成功");
+ } else {
+ callbackContext.error("写入失败");
+ }
+ }
+
+ private void setPower(JSONArray message, CallbackContext callbackContext) throws JSONException {
+ int power = message.getInt(0);
+ if (power > 30) {
+ power = 30;
+ } else if (power < 5) {
+ power = 5;
+ }
+ Reader.READER_ERR err = manager.setPower(power, power);
+ if (err == Reader.READER_ERR.MT_OK_ERR) {
+ callbackContext.success("设置成功");
+ } else {
+ callbackContext.error("设置失败");
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (this.manager != null) {
+ this.manager.close();
+ }
+ }
+}
diff --git a/src/android/cordova/plugin/uhf/Util.java b/src/android/cordova/plugin/uhf/Util.java
new file mode 100644
index 0000000..ee1de93
--- /dev/null
+++ b/src/android/cordova/plugin/uhf/Util.java
@@ -0,0 +1,77 @@
+package cordova.plugin.uhf;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.util.Log;
+
+/**
+ * 工具类,主要用于实现各类字符串之间的转换
+ */
+public class Util {
+
+ public static String str2HexStr(String origin) {
+ byte[] bytes = origin.getBytes();
+ String hex = bytesToHexString(bytes, bytes.length);
+ return hex;
+ }
+
+ public static String hexStr2Str(String hex) {
+ byte[] bb = hexStringToBytes(hex);
+ String rr = new String(bb);
+ return rr;
+ }
+
+ public static String bytes2Str(byte[] src) {
+ String rr = bytesToHexString(src, src.length);
+ String str = new String(hexStr2Str(rr));
+ return str;
+ }
+
+ private static String bytesToHexString(byte[] src, int size) {
+ StringBuilder stringBuilder = new StringBuilder("");
+ if (src == null || size <= 0) {
+ return null;
+ }
+ for (int i = 0; i < size; i++) {
+ int v = src[i] & 0xFF;
+ String hv = Integer.toHexString(v);
+ if (hv.length() < 2) {
+ stringBuilder.append(0);
+ }
+ stringBuilder.append(hv);
+ }
+ String str = stringBuilder.toString();
+ if (str.length() < 128) {
+ str += "00";
+ }
+ return str;
+ }
+
+ public static byte[] hexStringToBytes(String hexString) {
+ if (hexString == null || hexString.equals("")) {
+ return null;
+ }
+ hexString = hexString.toUpperCase();
+ int length = hexString.length() / 2;
+ char[] hexChars = hexString.toCharArray();
+ byte[] d = new byte[length];
+ for (int i = 0; i < length; i++) {
+ int pos = i * 2;
+ // 以0x00为分界线,不读取后面的数据
+ if ((byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])) == 00) {
+ break;
+ }
+ d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+ }
+ return d;
+ }
+
+ private static byte charToByte(char c) {
+ return (byte) "0123456789ABCDEF".indexOf(c);
+ }
+}
diff --git a/src/android/jxl.jar b/src/android/jxl.jar
new file mode 100644
index 0000000..daf1158
Binary files /dev/null and b/src/android/jxl.jar differ
diff --git a/src/android/libs/arm64-v8a/libModuleAPIJni.so b/src/android/libs/arm64-v8a/libModuleAPIJni.so
new file mode 100644
index 0000000..4072ad2
Binary files /dev/null and b/src/android/libs/arm64-v8a/libModuleAPIJni.so differ
diff --git a/src/android/libs/arm64-v8a/libSerialPort.so b/src/android/libs/arm64-v8a/libSerialPort.so
new file mode 100644
index 0000000..18949be
Binary files /dev/null and b/src/android/libs/arm64-v8a/libSerialPort.so differ
diff --git a/src/android/libs/arm64-v8a/libdevapi.so b/src/android/libs/arm64-v8a/libdevapi.so
new file mode 100644
index 0000000..4e65b7e
Binary files /dev/null and b/src/android/libs/arm64-v8a/libdevapi.so differ
diff --git a/src/android/libs/arm64-v8a/libirdaSerialPort.so b/src/android/libs/arm64-v8a/libirdaSerialPort.so
new file mode 100644
index 0000000..8c43d80
Binary files /dev/null and b/src/android/libs/arm64-v8a/libirdaSerialPort.so differ
diff --git a/src/android/libs/armeabi-v7a/libModuleAPIJni.so b/src/android/libs/armeabi-v7a/libModuleAPIJni.so
new file mode 100644
index 0000000..7e07755
Binary files /dev/null and b/src/android/libs/armeabi-v7a/libModuleAPIJni.so differ
diff --git a/src/android/libs/armeabi-v7a/libSerialPort.so b/src/android/libs/armeabi-v7a/libSerialPort.so
new file mode 100644
index 0000000..d7eb1f9
Binary files /dev/null and b/src/android/libs/armeabi-v7a/libSerialPort.so differ
diff --git a/src/android/libs/armeabi-v7a/libdevapi.so b/src/android/libs/armeabi-v7a/libdevapi.so
new file mode 100644
index 0000000..4ce4fc6
Binary files /dev/null and b/src/android/libs/armeabi-v7a/libdevapi.so differ
diff --git a/src/android/libs/armeabi-v7a/libirdaSerialPort.so b/src/android/libs/armeabi-v7a/libirdaSerialPort.so
new file mode 100644
index 0000000..d1c5202
Binary files /dev/null and b/src/android/libs/armeabi-v7a/libirdaSerialPort.so differ
diff --git a/src/android/libs/armeabi/libModuleAPIJni.so b/src/android/libs/armeabi/libModuleAPIJni.so
new file mode 100644
index 0000000..e837b9d
Binary files /dev/null and b/src/android/libs/armeabi/libModuleAPIJni.so differ
diff --git a/src/android/libs/armeabi/libSerialPort.so b/src/android/libs/armeabi/libSerialPort.so
new file mode 100644
index 0000000..dc3c956
Binary files /dev/null and b/src/android/libs/armeabi/libSerialPort.so differ
diff --git a/src/android/libs/armeabi/libdevapi.so b/src/android/libs/armeabi/libdevapi.so
new file mode 100644
index 0000000..4ce4fc6
Binary files /dev/null and b/src/android/libs/armeabi/libdevapi.so differ
diff --git a/src/android/libs/armeabi/libirdaSerialPort.so b/src/android/libs/armeabi/libirdaSerialPort.so
new file mode 100644
index 0000000..b8a8974
Binary files /dev/null and b/src/android/libs/armeabi/libirdaSerialPort.so differ
diff --git a/src/android/uhfr_v1.9.jar b/src/android/uhfr_v1.9.jar
new file mode 100644
index 0000000..79b553e
Binary files /dev/null and b/src/android/uhfr_v1.9.jar differ
diff --git a/www/cordova-plugin-UHF.js b/www/cordova-plugin-UHF.js
new file mode 100644
index 0000000..704cb08
--- /dev/null
+++ b/www/cordova-plugin-UHF.js
@@ -0,0 +1,41 @@
+var exec = require('cordova/exec');
+
+var coolMethod = function () {};
+
+coolMethod.readCard = function (success, error) {
+ exec(success, error, 'UHF', 'readCard', []);
+}
+
+coolMethod.inventoryCard = function (success, error) {
+ exec(success, error, 'UHF', 'inventoryCard', []);
+}
+
+coolMethod.stopInventoryCard = function (success, error) {
+ exec(success, error, 'UHF', 'stopInventoryCard', []);
+}
+
+coolMethod.searchCard = function (success, error) {
+ exec(success, error, 'UHF', 'searchCard', []);
+}
+
+coolMethod.writeCard = function (arg, success, error) {
+ exec(success, error, 'UHF', 'writeCard', [arg]);
+}
+
+coolMethod.setPower = function (arg, success, error) {
+ exec(success, error, 'UHF', 'setPower', [arg]);
+}
+
+coolMethod.startWork = function (success, error) {
+ exec(success, error, 'UHF', 'startWork', []);
+}
+
+coolMethod.endWork = function (success, error) {
+ exec(success, error, 'UHF', 'endWork', []);
+}
+
+coolMethod.selectCard = function (arg, success, error) {
+ exec(success, error, 'UHF', 'selectCard', [arg]);
+}
+
+module.exports = coolMethod;