@iotize/device-com-nfc.cordova 3.2.4 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/plugin.xml CHANGED
@@ -1,97 +1,99 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
3
- xmlns:android="http://schemas.android.com/apk/res/android" id="@iotize/device-com-nfc.cordova" version="3.0.1">
4
-
5
- <name>@iotize/device-com-nfc.cordova</name>
6
-
7
- <description>Near Field Communication (NFC) Plugin. Read and write NDEF messages to NFC tags and share NDEF messages with peers.</description>
8
-
9
- <license>MIT</license>
10
- <keywords>nfc, NFC, NDEF</keywords>
11
- <repo>https://github.com/iotize-sas/device-com-nfc.cordova.git</repo>
12
- <issue>https://github.com/iotize-sas/device-com-nfc.cordova/issues</issue>
13
-
14
- <platform name="android">
15
- <js-module src="www/phonegap-nfc.js" name="NFC">
16
- <runs />
17
- </js-module>
18
-
19
- <config-file target="res/xml/config.xml" parent="/*">
20
- <feature name="NfcPlugin">
21
- <param name="android-package" value="com.chariotsolutions.nfc.plugin.NfcPlugin"/>
22
- <param name="onload" value="true" />
23
- </feature>
24
- <feature name="NFCCom">
25
- <param name="android-package" value="com.iotize.android.communication.nfc.cordovaplugin.NFCCom"/>
26
- </feature>
27
- </config-file>
28
-
29
- <framework src="src/android/build.gradle" custom="true" type="gradleReference" />
30
-
31
- <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
32
- <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/Util.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
33
- <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/JSONBuilder.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
34
- <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/PluginResponse.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
35
- <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/NfcPluginError.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
36
-
37
- <config-file target="AndroidManifest.xml" parent="/manifest">
38
- <uses-permission android:name="android.permission.NFC"/>
39
- <uses-feature android:name="android.hardware.nfc" android:required="false"/>
40
- </config-file>
41
-
42
- <config-file parent="/manifest/application/activity[@android:name='MainActivity']" target="AndroidManifest.xml"
43
- xmlns:android="http://schemas.android.com/apk/res/android">
44
- <intent-filter>
45
- <action android:name="android.nfc.action.NDEF_DISCOVERED" />
46
- <category android:name="android.intent.category.DEFAULT" />
47
- <data android:mimeType="application/$PACKAGE_NAME" />
48
- </intent-filter>
49
- </config-file>
50
-
51
- </platform>
52
-
53
- <platform name="ios">
54
- <dependency id="cordova-plugin-add-swift-support"/>
55
- <js-module src="www/phonegap-nfc.js" name="NFC">
56
- <runs />
57
- </js-module>
58
-
59
- <config-file parent="/*" target="config.xml">
60
- <feature name="NfcPlugin">
61
- <param name="ios-package" value="NfcPlugin" />
62
- </feature>
63
- <preference name="deployment-target" value="11" />
64
- <preference name="SwiftVersion" value="4" />
65
-
66
- </config-file>
67
- <source-file src="src/ios/NFCTapPlugin.swift" />
68
- <source-file src="src/ios/ISO15Reader.swift" />
69
- <source-file src="src/ios/NFCNDEFDelegate.swift" />
70
- <source-file src="src/ios/AppDelegate+NFC.swift" />
71
- <source-file src="src/ios/NFCPlugin-Bridging-Header.h" />
72
-
73
-
74
- <config-file platform="ios" target="*-Debug.plist" parent="com.apple.developer.nfc.readersession.formats">
75
- <array>
76
- <string>NDEF</string>
77
- <string>TAG</string>
78
- </array>
79
- </config-file>
80
-
81
- <config-file platform="ios" target="*-Release.plist" parent="com.apple.developer.nfc.readersession.formats">
82
- <array>
83
- <string>NDEF</string>
84
- <string>TAG</string>
85
- </array>
86
- </config-file>
87
-
88
- <!-- frameworks -->
89
- <framework src="CoreNFC.framework" weak="true"/>
90
-
91
- <config-file target="*-Info.plist" parent="NFCReaderUsageDescription">
92
- <string>Communicate with IoTize NFC Tags</string>
93
- </config-file>
94
- </platform>
95
-
96
-
97
- </plugin>
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
3
+ xmlns:android="http://schemas.android.com/apk/res/android" id="@iotize/device-com-nfc.cordova" version="3.4.0">
4
+
5
+ <name>@iotize/device-com-nfc.cordova</name>
6
+
7
+ <description>Near Field Communication (NFC) Plugin. Read and write NDEF messages to NFC tags and share NDEF messages with peers.</description>
8
+
9
+ <license>MIT</license>
10
+ <keywords>nfc, NFC, NDEF</keywords>
11
+ <repo>https://github.com/iotize-sas/device-com-nfc.cordova.git</repo>
12
+ <issue>https://github.com/iotize-sas/device-com-nfc.cordova/issues</issue>
13
+
14
+ <platform name="android">
15
+ <js-module src="www/phonegap-nfc.js" name="NFC">
16
+ <runs />
17
+ </js-module>
18
+
19
+ <config-file target="res/xml/config.xml" parent="/*">
20
+ <feature name="NfcPlugin">
21
+ <param name="android-package" value="com.chariotsolutions.nfc.plugin.NfcPlugin"/>
22
+ <param name="onload" value="true" />
23
+ </feature>
24
+ <feature name="NFCCom">
25
+ <param name="android-package" value="com.iotize.android.communication.nfc.cordovaplugin.NFCCom"/>
26
+ </feature>
27
+ </config-file>
28
+
29
+ <framework src="src/android/build.gradle" custom="true" type="gradleReference" />
30
+
31
+ <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
32
+ <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/Util.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
33
+ <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/JSONBuilder.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
34
+ <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/PluginResponse.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
35
+ <source-file src="src/android/src/com/chariotsolutions/nfc/plugin/NfcPluginError.java" target-dir="src/com/chariotsolutions/nfc/plugin"/>
36
+
37
+ <config-file target="AndroidManifest.xml" parent="/manifest">
38
+ <uses-permission android:name="android.permission.NFC"/>
39
+ <uses-feature android:name="android.hardware.nfc" android:required="false"/>
40
+ </config-file>
41
+
42
+ <config-file parent="/manifest/application/activity[@android:name='MainActivity']" target="AndroidManifest.xml"
43
+ xmlns:android="http://schemas.android.com/apk/res/android">
44
+ <intent-filter>
45
+ <action android:name="android.nfc.action.NDEF_DISCOVERED" />
46
+ <category android:name="android.intent.category.DEFAULT" />
47
+ <data android:mimeType="application/$PACKAGE_NAME" />
48
+ </intent-filter>
49
+ </config-file>
50
+
51
+ </platform>
52
+
53
+ <platform name="ios">
54
+ <dependency id="cordova-plugin-add-swift-support"/>
55
+ <js-module src="www/phonegap-nfc.js" name="NFC">
56
+ <runs />
57
+ </js-module>
58
+
59
+ <config-file parent="/*" target="config.xml">
60
+ <feature name="NfcPlugin">
61
+ <param name="ios-package" value="NfcPlugin" />
62
+ </feature>
63
+ <preference name="deployment-target" value="11" />
64
+ <preference name="SwiftVersion" value="4" />
65
+
66
+ </config-file>
67
+ <source-file src="src/ios/NFCTapPlugin.swift" />
68
+ <source-file src="src/ios/ISO15Reader.swift" />
69
+ <source-file src="src/ios/NFCNDEFDelegate.swift" />
70
+ <source-file src="src/ios/AppDelegate+NFC.swift" />
71
+ <source-file src="src/ios/NFCHelpers.swift" />
72
+ <source-file src="src/ios/NFCTagReader.swift" />
73
+ <source-file src="src/ios/NFCPlugin-Bridging-Header.h" />
74
+
75
+
76
+ <config-file platform="ios" target="*-Debug.plist" parent="com.apple.developer.nfc.readersession.formats">
77
+ <array>
78
+ <string>NDEF</string>
79
+ <string>TAG</string>
80
+ </array>
81
+ </config-file>
82
+
83
+ <config-file platform="ios" target="*-Release.plist" parent="com.apple.developer.nfc.readersession.formats">
84
+ <array>
85
+ <string>NDEF</string>
86
+ <string>TAG</string>
87
+ </array>
88
+ </config-file>
89
+
90
+ <!-- frameworks -->
91
+ <framework src="CoreNFC.framework" weak="true"/>
92
+
93
+ <config-file target="*-Info.plist" parent="NFCReaderUsageDescription">
94
+ <string>Communicate with IoTize NFC Tags</string>
95
+ </config-file>
96
+ </platform>
97
+
98
+
99
+ </plugin>
@@ -16,6 +16,7 @@ import android.nfc.Tag;
16
16
  import android.nfc.TagLostException;
17
17
  import android.nfc.tech.Ndef;
18
18
  import android.nfc.tech.NdefFormatable;
19
+ import android.nfc.tech.TagTechnology;
19
20
  import android.os.Bundle;
20
21
  import android.os.Parcelable;
21
22
  import android.util.Log;
@@ -41,6 +42,7 @@ import org.json.JSONObject;
41
42
  import java.io.IOException;
42
43
  import java.lang.reflect.Field;
43
44
  import java.lang.reflect.InvocationTargetException;
45
+ import java.lang.reflect.Method;
44
46
  import java.util.ArrayList;
45
47
  import java.util.Arrays;
46
48
  import java.util.Iterator;
@@ -81,6 +83,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
81
83
  // TagTechnology IsoDep, NfcA, NfcB, NfcV, NfcF, MifareClassic, MifareUltralight
82
84
  private static final String CONNECT = "connect";
83
85
  private static final String CLOSE = "close";
86
+ private static final String TRANSCEIVE_TAP = "transceiveTap";
84
87
  private static final String TRANSCEIVE = "transceive";
85
88
 
86
89
  private static final String NFC_TAP_DEVICE = "nfc-tap-device";
@@ -90,10 +93,13 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
90
93
  private static final String PREF_ENABLE_ENCRYPTION_WITH_NFC = "EnableEncryptionWithNFC";
91
94
  private static final String PREF_NFC_PAIRING_DONE_TOAST_MESSAGE = "NFCParingDoneToastMessage";
92
95
  private static final String REGISTER_NFC_TAP_DEVICE = "registerTapDevice";
96
+ private static final String SET_TAP_DEVICE_DISCOVERY_ENABLED = "setTapDeviceDiscoveryEnabled";
93
97
 
94
- // @Nullable
95
- // private TagTechnology tagTechnology = null;
96
- // private Class<?> tagTechnologyClass;
98
+ @Nullable
99
+ private TagTechnology tagTechnology = null;
100
+
101
+ @Nullable
102
+ private Class<?> tagTechnologyClass;
97
103
 
98
104
  private static final String CHANNEL = "channel";
99
105
 
@@ -124,10 +130,12 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
124
130
  @Nullable
125
131
  private Intent mLastTapDiscoveredIntent;
126
132
 
133
+ private boolean _isTapDeviceDiscoveryEnabled = true;
134
+
127
135
  @Override
128
136
  public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
129
137
 
130
- Log.d(TAG, "execute " + action);
138
+ Log.d(TAG, "execute " + action);
131
139
 
132
140
  // showSettings can be called if NFC is disabled
133
141
  // might want to skip this if NO_NFC
@@ -219,13 +227,23 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
219
227
  CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
220
228
 
221
229
  byte[] command = args.getArrayBuffer(0);
222
- transceive(command, callbackContext);
230
+ transceiveRaw(command, callbackContext);
231
+
232
+ } else if (action.equalsIgnoreCase(TRANSCEIVE_TAP)) {
233
+ CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
234
+
235
+ byte[] command = args.getArrayBuffer(0);
236
+ transceiveTap(command, callbackContext);
223
237
 
224
238
  } else if (action.equalsIgnoreCase(CLOSE)) {
225
239
  close(callbackContext);
226
240
 
241
+ } else if (action.equalsIgnoreCase(SET_TAP_DEVICE_DISCOVERY_ENABLED)) {
242
+ CordovaArgs args = new CordovaArgs(data);
243
+ this._isTapDeviceDiscoveryEnabled = args.getBoolean(0);
227
244
  } else {
228
245
  // invalid action
246
+ callbackContext.error("Invalid NFC action \"" + action +"\"");
229
247
  return false;
230
248
  }
231
249
 
@@ -440,7 +458,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
440
458
  }
441
459
 
442
460
  private boolean isTapDeviceDiscoveryEnabled() {
443
- return preferences.getBoolean(PREF_ENABLE_TAP_DEVICE_DISCOVERY, false);
461
+ return this._isTapDeviceDiscoveryEnabled && preferences.getBoolean(PREF_ENABLE_TAP_DEVICE_DISCOVERY, false);
444
462
  }
445
463
 
446
464
  // Cheating and writing an empty record. We may actually be able to erase some tag types.
@@ -826,7 +844,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
826
844
  Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
827
845
  Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
828
846
 
829
- if (isTapDeviceDiscoveryEnabled() && tag != null) {
847
+ if (isTapDeviceDiscoveryEnabled() && isIoTizeTag(tag)) {
830
848
  onTapDeviceDiscoveredIntent(intent);
831
849
  }
832
850
 
@@ -856,8 +874,25 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
856
874
  });
857
875
  }
858
876
 
859
- private boolean notifyWhenNfcPairingDone() {
860
- return true; // TODO
877
+ private boolean isIoTizeTag(@Nullable Tag tag) {
878
+ if (tag == null) {
879
+ return false;
880
+ }
881
+ boolean hasNfcV = Arrays.stream(tag.getTechList()).anyMatch(s -> s.endsWith("NfcV"));
882
+ if (!hasNfcV) {
883
+ return false;
884
+ }
885
+ Ndef ndef = Ndef.get(tag);
886
+ if (ndef == null) {
887
+ return false;
888
+ }
889
+ NdefMessage ndefMessages = ndef.getCachedNdefMessage();
890
+ if (ndefMessages == null) {
891
+ return false;
892
+ }
893
+ NdefRecord[] records = ndefMessages.getRecords();
894
+
895
+ return records.length > 0;
861
896
  }
862
897
 
863
898
  private void sendEvent(String type, JSONObject tag, JSONObject tap) {
@@ -1077,29 +1112,9 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1077
1112
  final CallbackContext callbackContext) {
1078
1113
  this.cordova.getThreadPool().execute(() -> {
1079
1114
  try {
1115
+ this._initIntentTag(tech);
1080
1116
 
1081
- Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
1082
- if (tag == null) {
1083
- tag = savedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
1084
- }
1085
-
1086
- if (tag == null) {
1087
- Log.e(TAG, "No Tag");
1088
- callbackContext.error("No Tag");
1089
- return;
1090
- }
1091
-
1092
- // get technologies supported by this tag
1093
- List<String> techList = Arrays.asList(tag.getTechList());
1094
- if (techList.contains(tech)) {
1095
- // use reflection to call the static function Tech.get(tag)
1096
- // tagTechnologyClass = Class.forName(tech);
1097
- nfcProtocol = NFCProtocol.create(tag);
1098
- // Method method = tagTechnologyClass.getMethod("get", Tag.class);
1099
- // tagTechnology = (TagTechnology) method.invoke(null, tag);
1100
- }
1101
-
1102
- if (nfcProtocol == null) {
1117
+ if (nfcProtocol == null) {
1103
1118
  callbackContext.error("Tag does not support " + tech);
1104
1119
  return;
1105
1120
  }
@@ -1118,6 +1133,41 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1118
1133
  });
1119
1134
  }
1120
1135
 
1136
+ private void _initIntentTag() throws Exception {
1137
+ this._initIntentTag("android.nfc.tech.NfcV"); // TODO
1138
+ }
1139
+
1140
+ private void _initIntentTag(final String tech) throws Exception {
1141
+ Intent intent = getIntent();
1142
+ Tag tag = null;
1143
+ if (intent != null) {
1144
+ tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
1145
+ }
1146
+ if (tag == null && savedIntent != null) {
1147
+ tag = savedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
1148
+ }
1149
+
1150
+ if (tag == null) {
1151
+ Log.e(TAG, "No Tag");
1152
+ throw new Exception("No Tag");
1153
+ }
1154
+
1155
+ // get technologies supported by this tag
1156
+ List<String> techList = Arrays.asList(tag.getTechList());
1157
+ if (!techList.contains(tech)) {
1158
+ throw new Exception("Tech " + tech + " not available");
1159
+ }
1160
+ // use reflection to call the static function Tech.get(tag)
1161
+ tagTechnologyClass = Class.forName(tech);
1162
+ nfcProtocol = NFCProtocol.create(tag);
1163
+ Method method = tagTechnologyClass.getMethod("get", Tag.class);
1164
+ tagTechnology = (TagTechnology) method.invoke(null, tag);
1165
+ if (tagTechnology == null) {
1166
+ Log.e(TAG, "No Tag Technology");
1167
+ throw new Exception("No Tag");
1168
+ }
1169
+ }
1170
+
1121
1171
  private void setTimeout(int timeout) {
1122
1172
  if (timeout < 0) {
1123
1173
  return;
@@ -1144,6 +1194,11 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1144
1194
  Log.e(TAG, "Error closing nfc connection", ex);
1145
1195
  callbackContext.error("Error closing nfc connection " + ex.getLocalizedMessage());
1146
1196
  }
1197
+ finally {
1198
+ nfcProtocol = null;
1199
+ tagTechnology = null;
1200
+ tagTechnologyClass = null;
1201
+ }
1147
1202
  });
1148
1203
  }
1149
1204
 
@@ -1153,7 +1208,62 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1153
1208
  * @param data byte[] command to be passed to the tag
1154
1209
  * @param callbackContext Cordova callback context
1155
1210
  */
1156
- private void transceive(final byte[] data, final CallbackContext callbackContext) {
1211
+ private void transceiveRaw(final byte[] data, final CallbackContext callbackContext) {
1212
+ cordova.getThreadPool().execute(() -> {
1213
+ try {
1214
+ this._connectIntentTagIfNeeded();
1215
+ Method transceiveMethod = tagTechnologyClass.getMethod("transceive", byte[].class);
1216
+ try {
1217
+ @SuppressWarnings("PrimitiveArrayArgumentToVarargsMethod")
1218
+ byte[] response = (byte[]) transceiveMethod.invoke(tagTechnology, data);
1219
+ callbackContext.success(Helper.ByteArrayToHexString(response));
1220
+ }
1221
+ catch (InvocationTargetException e) {
1222
+ Throwable targetException = e.getTargetException();
1223
+ String errorMessage = targetException.getMessage();
1224
+ if (errorMessage != null && (errorMessage.endsWith("is out of date") ||
1225
+ errorMessage.contains("Call connect() first"))) {
1226
+ this._connectIntentTag();
1227
+ // Retry
1228
+ byte[] response = (byte[]) transceiveMethod.invoke(tagTechnology, data);
1229
+ callbackContext.success(Helper.ByteArrayToHexString(response));
1230
+ }
1231
+ else {
1232
+ throw e;
1233
+ }
1234
+ }
1235
+ }
1236
+ catch (InvocationTargetException e) {
1237
+ String msg = e.getTargetException().getMessage();
1238
+ Log.e(TAG, msg, e);
1239
+ callbackContext.error(msg);
1240
+ }
1241
+ catch (Throwable e) {
1242
+ Log.e(TAG, e.getMessage(), e);
1243
+ callbackContext.error(e.getMessage());
1244
+ }
1245
+ });
1246
+ }
1247
+
1248
+ private void _connectIntentTag() throws Exception {
1249
+ this._initIntentTag();
1250
+ tagTechnology.connect();
1251
+ }
1252
+
1253
+ private void _connectIntentTagIfNeeded() throws Exception {
1254
+ if (tagTechnology == null) {
1255
+ this._initIntentTag();
1256
+ tagTechnology.connect();
1257
+ }
1258
+ }
1259
+
1260
+ /**
1261
+ * Send raw commands to the tag and receive the response.
1262
+ *
1263
+ * @param data byte[] command to be passed to the tag
1264
+ * @param callbackContext Cordova callback context
1265
+ */
1266
+ private void transceiveTap(final byte[] data, final CallbackContext callbackContext) {
1157
1267
  cordova.getThreadPool().execute(() -> {
1158
1268
  try {
1159
1269
  if (nfcProtocol == null) {
@@ -1166,11 +1276,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1166
1276
  callbackContext.error("Not connected");
1167
1277
  return;
1168
1278
  }
1169
-
1170
- // Use reflection so we can support many tag types
1171
- //Method transceiveMethod = tagTechnologyClass.getMethod("transceive", byte[].class);
1172
- // @SuppressWarnings("PrimitiveArrayArgumentToVarargsMethod")
1173
- // byte[] response = (byte[]) transceiveMethod.invoke(tagTechnology, data);
1174
1279
  byte[] response = nfcProtocol.send(data);
1175
1280
  callbackContext.success(Helper.ByteArrayToHexString(response));
1176
1281
  } catch (Exception e) {
@@ -1179,5 +1284,4 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1179
1284
  }
1180
1285
  });
1181
1286
  }
1182
-
1183
1287
  }