community-cordova-plugin-nfc 1.3.0 → 1.4.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # [1.4.0](https://github.com/EYALIN/community-admob-plus/compare/admob-plus-cordova@1.31.0...admob-plus-cordova@1.32.0) (2024-07-19)
7
+
8
+ ### Features
9
+
10
+ * change Android code to support SDK 34
11
+ * share, unshare, handover,stopHandover functions are now deprecated
12
+ * organize the code
13
+
package/README.md CHANGED
@@ -99,11 +99,11 @@ Writing NFC tags on iOS uses the same [nfc.write](#nfcwrite) function as other p
99
99
  - [nfc.addNdefFormatableListener](#nfcaddndefformatablelistener)
100
100
  - [nfc.write](#nfcwrite)
101
101
  - [nfc.makeReadOnly](#nfcmakereadonly)
102
- - [nfc.share](#nfcshare)
103
- - [nfc.unshare](#nfcunshare)
102
+ - [~~nfc.share~~](#nfcshare)
103
+ - [~~nfc.unshare~~](#nfcunshare)
104
104
  - [nfc.erase](#nfcerase)
105
- - [nfc.handover](#nfchandover)
106
- - [nfc.stopHandover](#nfcstophandover)
105
+ - [~~nfc.handover~~](#nfchandover)
106
+ - [~~nfc.stopHandover~~](#nfcstophandover)
107
107
  - [nfc.enabled](#nfcenabled)
108
108
  - [nfc.showSettings](#nfcshowsettings)
109
109
  - [~~nfc.beginSession~~](#nfcbeginsession)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "community-cordova-plugin-nfc",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Near Field Communication (NFC) Plugin. Read and write NDEF messages to NFC tags and share NDEF messages with peers.",
5
5
  "cordova": {
6
6
  "id": "phonegap-nfc",
package/plugin.xml CHANGED
@@ -3,7 +3,7 @@
3
3
  xmlns="http://www.phonegap.com/ns/plugins/1.0"
4
4
  xmlns:android="http://schemas.android.com/apk/res/android"
5
5
  id="community-cordova-plugin-nfc"
6
- version="1.3.0">
6
+ version="1.4.0">
7
7
 
8
8
  <name>NFC</name>
9
9
 
@@ -5,11 +5,14 @@ import java.lang.reflect.InvocationTargetException;
5
5
  import java.lang.reflect.Method;
6
6
  import java.util.ArrayList;
7
7
  import java.util.Arrays;
8
+ import java.util.Date;
8
9
  import java.util.Iterator;
9
10
  import java.util.List;
10
11
 
11
- // using wildcard imports so we can support Cordova 3.x
12
- import org.apache.cordova.*; // Cordova 3.x
12
+ import org.apache.cordova.CallbackContext;
13
+ import org.apache.cordova.CordovaArgs;
14
+ import org.apache.cordova.CordovaPlugin;
15
+ import org.apache.cordova.PluginResult;
13
16
 
14
17
  import org.json.JSONArray;
15
18
  import org.json.JSONException;
@@ -35,7 +38,7 @@ import android.os.Bundle;
35
38
  import android.os.Parcelable;
36
39
  import android.util.Log;
37
40
 
38
- public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCompleteCallback {
41
+ public class NfcPlugin extends CordovaPlugin {
39
42
  private static final String REGISTER_MIME_TYPE = "registerMimeType";
40
43
  private static final String REMOVE_MIME_TYPE = "removeMimeType";
41
44
  private static final String REGISTER_NDEF = "registerNdef";
@@ -62,7 +65,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
62
65
  private static final String READER_MODE = "readerMode";
63
66
  private static final String DISABLE_READER_MODE = "disableReaderMode";
64
67
 
65
- // TagTechnology IsoDep, NfcA, NfcB, NfcV, NfcF, MifareClassic, MifareUltralight
66
68
  private static final String CONNECT = "connect";
67
69
  private static final String CLOSE = "close";
68
70
  private static final String TRANSCEIVE = "transceive";
@@ -87,111 +89,149 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
87
89
 
88
90
  private CallbackContext readerModeCallback;
89
91
  private CallbackContext channelCallback;
90
- private CallbackContext shareTagCallback;
91
- private CallbackContext handoverCallback;
92
+
93
+ private PostponedPluginResult postponedPluginResult = null;
94
+
95
+ class PostponedPluginResult {
96
+ private Date moment;
97
+ private PluginResult pluginResult;
98
+
99
+ PostponedPluginResult(Date moment, PluginResult pluginResult) {
100
+ this.moment = moment;
101
+ this.pluginResult = pluginResult;
102
+ }
103
+
104
+ boolean isValid() {
105
+ return this.moment.after(new Date(new Date().getTime() - 30000));
106
+ }
107
+ }
92
108
 
93
109
  @Override
94
110
  public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
95
-
96
111
  Log.d(TAG, "execute " + action);
97
112
 
98
- // showSettings can be called if NFC is disabled
99
- // might want to skip this if NO_NFC
100
113
  if (action.equalsIgnoreCase(SHOW_SETTINGS)) {
101
114
  showSettings(callbackContext);
102
115
  return true;
103
116
  }
104
117
 
105
- // the channel is set up when the plugin starts
106
118
  if (action.equalsIgnoreCase(CHANNEL)) {
107
119
  channelCallback = callbackContext;
108
- return true; // short circuit
120
+ if (postponedPluginResult != null) {
121
+ Log.i(TAG, "Postponed plugin result available");
122
+
123
+ if (postponedPluginResult.isValid()) {
124
+ Log.i(TAG, "Postponed plugin result is valid, resending it now");
125
+ channelCallback.sendPluginResult(postponedPluginResult.pluginResult);
126
+ } else {
127
+ Log.i(TAG, "Postponed plugin result not valid anymore, so ignoring it");
128
+ }
129
+
130
+ postponedPluginResult = null;
131
+ }
132
+ return true;
109
133
  }
110
134
 
111
- // allow reader mode to be disabled even if nfc is disabled
112
135
  if (action.equalsIgnoreCase(DISABLE_READER_MODE)) {
113
136
  disableReaderMode(callbackContext);
114
- return true; // short circuit
137
+ return true;
115
138
  }
116
139
 
117
140
  if (!getNfcStatus().equals(STATUS_NFC_OK)) {
118
141
  callbackContext.error(getNfcStatus());
119
- return true; // short circuit
142
+ return true;
120
143
  }
121
144
 
122
145
  createPendingIntent();
123
146
 
124
- if (action.equalsIgnoreCase(READER_MODE)) {
125
- int flags = data.getInt(0);
126
- readerMode(flags, callbackContext);
127
-
128
- } else if (action.equalsIgnoreCase(REGISTER_MIME_TYPE)) {
129
- registerMimeType(data, callbackContext);
130
-
131
- } else if (action.equalsIgnoreCase(REMOVE_MIME_TYPE)) {
132
- removeMimeType(data, callbackContext);
133
-
134
- } else if (action.equalsIgnoreCase(REGISTER_NDEF)) {
135
- registerNdef(callbackContext);
136
-
137
- } else if (action.equalsIgnoreCase(REMOVE_NDEF)) {
138
- removeNdef(callbackContext);
139
-
140
- } else if (action.equalsIgnoreCase(REGISTER_NDEF_FORMATABLE)) {
141
- registerNdefFormatable(callbackContext);
142
-
143
- } else if (action.equals(REGISTER_DEFAULT_TAG)) {
144
- registerDefaultTag(callbackContext);
145
-
146
- } else if (action.equals(REMOVE_DEFAULT_TAG)) {
147
- removeDefaultTag(callbackContext);
148
-
149
- } else if (action.equalsIgnoreCase(WRITE_TAG)) {
150
- writeTag(data, callbackContext);
151
-
152
- } else if (action.equalsIgnoreCase(MAKE_READ_ONLY)) {
153
- makeReadOnly(callbackContext);
154
-
155
- } else if (action.equalsIgnoreCase(ERASE_TAG)) {
156
- eraseTag(callbackContext);
157
-
158
- } else if (action.equalsIgnoreCase(SHARE_TAG)) {
159
- shareTag(data, callbackContext);
160
-
161
- } else if (action.equalsIgnoreCase(UNSHARE_TAG)) {
162
- unshareTag(callbackContext);
163
-
164
- } else if (action.equalsIgnoreCase(HANDOVER)) {
165
- handover(data, callbackContext);
166
-
167
- } else if (action.equalsIgnoreCase(STOP_HANDOVER)) {
168
- stopHandover(callbackContext);
169
-
170
- } else if (action.equalsIgnoreCase(INIT)) {
171
- init(callbackContext);
172
-
173
- } else if (action.equalsIgnoreCase(ENABLED)) {
174
- // status is checked before every call
175
- // if code made it here, NFC is enabled
176
- callbackContext.success(STATUS_NFC_OK);
177
-
178
- } else if (action.equalsIgnoreCase(CONNECT)) {
179
- String tech = data.getString(0);
180
- int timeout = data.optInt(1, -1);
181
- connect(tech, timeout, callbackContext);
182
-
183
- } else if (action.equalsIgnoreCase(TRANSCEIVE)) {
184
- CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
185
-
186
- byte[] command = args.getArrayBuffer(0);
187
- transceive(command, callbackContext);
188
-
189
- } else if (action.equalsIgnoreCase(CLOSE)) {
190
- close(callbackContext);
191
-
192
- } else {
193
- // invalid action
194
- return false;
147
+ switch (action) {
148
+ case READER_MODE:
149
+ int flags = data.getInt(0);
150
+ readerMode(flags, callbackContext);
151
+ break;
152
+
153
+ case REGISTER_MIME_TYPE:
154
+ registerMimeType(data, callbackContext);
155
+ break;
156
+
157
+ case REMOVE_MIME_TYPE:
158
+ removeMimeType(data, callbackContext);
159
+ break;
160
+
161
+ case REGISTER_NDEF:
162
+ registerNdef(callbackContext);
163
+ break;
164
+
165
+ case REMOVE_NDEF:
166
+ removeNdef(callbackContext);
167
+ break;
168
+
169
+ case REGISTER_NDEF_FORMATABLE:
170
+ registerNdefFormatable(callbackContext);
171
+ break;
172
+
173
+ case REGISTER_DEFAULT_TAG:
174
+ registerDefaultTag(callbackContext);
175
+ break;
176
+
177
+ case REMOVE_DEFAULT_TAG:
178
+ removeDefaultTag(callbackContext);
179
+ break;
180
+
181
+ case WRITE_TAG:
182
+ writeTag(data, callbackContext);
183
+ break;
184
+
185
+ case MAKE_READ_ONLY:
186
+ makeReadOnly(callbackContext);
187
+ break;
188
+
189
+ case ERASE_TAG:
190
+ eraseTag(callbackContext);
191
+ break;
192
+
193
+ case SHARE_TAG:
194
+ shareTag(data, callbackContext);
195
+ break;
196
+
197
+ case UNSHARE_TAG:
198
+ unshareTag(callbackContext);
199
+ break;
200
+
201
+ case HANDOVER:
202
+ handover(data, callbackContext);
203
+ break;
204
+
205
+ case STOP_HANDOVER:
206
+ stopHandover(callbackContext);
207
+ break;
208
+
209
+ case INIT:
210
+ init(callbackContext);
211
+ break;
212
+
213
+ case ENABLED:
214
+ callbackContext.success(STATUS_NFC_OK);
215
+ break;
216
+
217
+ case CONNECT:
218
+ String tech = data.getString(0);
219
+ int timeout = data.optInt(1, -1);
220
+ connect(tech, timeout, callbackContext);
221
+ break;
222
+
223
+ case TRANSCEIVE:
224
+ CordovaArgs args = new CordovaArgs(data);
225
+ byte[] command = args.getArrayBuffer(0);
226
+ transceive(command, callbackContext);
227
+ break;
228
+
229
+ case CLOSE:
230
+ close(callbackContext);
231
+ break;
232
+
233
+ default:
234
+ return false;
195
235
  }
196
236
 
197
237
  return true;
@@ -209,13 +249,16 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
209
249
  }
210
250
 
211
251
  private void readerMode(int flags, CallbackContext callbackContext) {
212
- Bundle extras = new Bundle(); // not used
252
+ Bundle extras = new Bundle();
213
253
  readerModeCallback = callbackContext;
214
254
  getActivity().runOnUiThread(() -> {
215
255
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
216
- nfcAdapter.enableReaderMode(getActivity(), callback, flags, extras);
256
+ if (nfcAdapter != null) {
257
+ nfcAdapter.enableReaderMode(getActivity(), callback, flags, extras);
258
+ } else {
259
+ callbackContext.error("NFC Adapter not available");
260
+ }
217
261
  });
218
-
219
262
  }
220
263
 
221
264
  private void disableReaderMode(CallbackContext callbackContext) {
@@ -229,33 +272,26 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
229
272
  });
230
273
  }
231
274
 
232
- private NfcAdapter.ReaderCallback callback = new NfcAdapter.ReaderCallback() {
233
- @Override
234
- public void onTagDiscovered(Tag tag) {
235
-
236
- JSONObject json;
237
-
238
- // If the tag supports Ndef, try and return an Ndef message
239
- List<String> techList = Arrays.asList(tag.getTechList());
240
- if (techList.contains(Ndef.class.getName())) {
241
- Ndef ndef = Ndef.get(tag);
242
- json = Util.ndefToJSON(ndef);
243
- } else {
244
- json = Util.tagToJSON(tag);
245
- }
246
-
247
- Intent tagIntent = new Intent();
248
- tagIntent.putExtra(NfcAdapter.EXTRA_TAG, tag);
249
- setIntent(tagIntent);
275
+ private final NfcAdapter.ReaderCallback callback = tag -> {
276
+ JSONObject json;
277
+ List<String> techList = Arrays.asList(tag.getTechList());
278
+ if (techList.contains(Ndef.class.getName())) {
279
+ Ndef ndef = Ndef.get(tag);
280
+ json = Util.ndefToJSON(ndef);
281
+ } else {
282
+ json = Util.tagToJSON(tag);
283
+ }
250
284
 
251
- PluginResult result = new PluginResult(PluginResult.Status.OK, json);
252
- result.setKeepCallback(true);
253
- if (readerModeCallback != null) {
254
- readerModeCallback.sendPluginResult(result);
255
- } else {
256
- Log.i(TAG, "readerModeCallback is null - reader mode probably disabled in the meantime");
257
- }
285
+ Intent tagIntent = new Intent();
286
+ tagIntent.putExtra(NfcAdapter.EXTRA_TAG, tag);
287
+ setIntent(tagIntent);
258
288
 
289
+ PluginResult result = new PluginResult(PluginResult.Status.OK, json);
290
+ result.setKeepCallback(true);
291
+ if (readerModeCallback != null) {
292
+ readerModeCallback.sendPluginResult(result);
293
+ } else {
294
+ Log.i(TAG, "readerModeCallback is null - reader mode probably disabled in the meantime");
259
295
  }
260
296
  };
261
297
 
@@ -290,15 +326,11 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
290
326
  }
291
327
 
292
328
  private void unshareTag(CallbackContext callbackContext) {
293
- p2pMessage = null;
294
- stopNdefPush();
295
- shareTagCallback = null;
296
329
  callbackContext.success();
297
330
  }
298
331
 
299
332
  private void init(CallbackContext callbackContext) {
300
333
  Log.d(TAG, "Enabling plugin " + getIntent());
301
-
302
334
  startNfc();
303
335
  if (!recycledIntent()) {
304
336
  parseMessage();
@@ -325,17 +357,16 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
325
357
  }
326
358
  }
327
359
 
328
- // Cheating and writing an empty record. We may actually be able to erase some tag types.
329
360
  private void eraseTag(CallbackContext callbackContext) {
330
361
  Tag tag = savedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
331
362
  NdefRecord[] records = {
332
- new NdefRecord(NdefRecord.TNF_EMPTY, new byte[0], new byte[0], new byte[0])
363
+ new NdefRecord(NdefRecord.TNF_EMPTY, new byte[0], new byte[0], new byte[0])
333
364
  };
334
365
  writeNdefMessage(new NdefMessage(records), tag, callbackContext);
335
366
  }
336
367
 
337
368
  private void writeTag(JSONArray data, CallbackContext callbackContext) throws JSONException {
338
- if (getIntent() == null) { // TODO remove this and handle LostTag
369
+ if (getIntent() == null) {
339
370
  callbackContext.error("Failed to write tag, received null intent");
340
371
  }
341
372
 
@@ -344,50 +375,47 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
344
375
  writeNdefMessage(new NdefMessage(records), tag, callbackContext);
345
376
  }
346
377
 
347
- private void writeNdefMessage(final NdefMessage message, final Tag tag, final CallbackContext callbackContext) {
348
- cordova.getThreadPool().execute(() -> {
349
- try {
350
- Ndef ndef = Ndef.get(tag);
351
- if (ndef != null) {
352
- ndef.connect();
353
-
354
- if (ndef.isWritable()) {
355
- int size = message.toByteArray().length;
356
- if (ndef.getMaxSize() < size) {
357
- callbackContext.error("Tag capacity is " + ndef.getMaxSize() +
358
- " bytes, message is " + size + " bytes.");
359
- } else {
360
- ndef.writeNdefMessage(message);
361
- callbackContext.success();
362
- }
363
- } else {
364
- callbackContext.error("Tag is read only");
365
- }
366
- ndef.close();
367
- } else {
368
- NdefFormatable formatable = NdefFormatable.get(tag);
369
- if (formatable != null) {
370
- formatable.connect();
371
- formatable.format(message);
372
- callbackContext.success();
373
- formatable.close();
374
- } else {
375
- callbackContext.error("Tag doesn't support NDEF");
376
- }
377
- }
378
- } catch (FormatException e) {
379
- callbackContext.error(e.getMessage());
380
- } catch (TagLostException e) {
381
- callbackContext.error(e.getMessage());
382
- } catch (IOException e) {
383
- callbackContext.error(e.getMessage());
384
- }
385
- });
386
- }
378
+ private void writeNdefMessage(final NdefMessage message, final Tag tag, final CallbackContext callbackContext) {
379
+ cordova.getThreadPool().execute(() -> {
380
+ try {
381
+ Ndef ndef = Ndef.get(tag);
382
+ if (ndef != null) {
383
+ ndef.connect();
384
+ if (ndef.isWritable()) {
385
+ int size = message.toByteArray().length;
386
+ if (ndef.getMaxSize() < size) {
387
+ callbackContext.error("Tag capacity is " + ndef.getMaxSize() + " bytes, message is " + size + " bytes.");
388
+ } else {
389
+ ndef.writeNdefMessage(message);
390
+ callbackContext.success();
391
+ }
392
+ } else {
393
+ callbackContext.error("Tag is read only");
394
+ }
395
+ ndef.close();
396
+ } else {
397
+ NdefFormatable formatable = NdefFormatable.get(tag);
398
+ if (formatable != null) {
399
+ formatable.connect();
400
+ formatable.format(message);
401
+ callbackContext.success();
402
+ formatable.close();
403
+ } else {
404
+ callbackContext.error("Tag doesn't support NDEF");
405
+ }
406
+ }
407
+ } catch (FormatException e) {
408
+ callbackContext.error(e.getMessage());
409
+ } catch (TagLostException e) {
410
+ callbackContext.error(e.getMessage());
411
+ } catch (IOException e) {
412
+ callbackContext.error(e.getMessage());
413
+ }
414
+ });
415
+ }
387
416
 
388
417
  private void makeReadOnly(final CallbackContext callbackContext) {
389
-
390
- if (getIntent() == null) { // Lost Tag
418
+ if (getIntent() == null) {
391
419
  callbackContext.error("Failed to make tag read only, received null intent");
392
420
  return;
393
421
  }
@@ -406,7 +434,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
406
434
 
407
435
  try {
408
436
  if (ndef != null) {
409
-
410
437
  ndef.connect();
411
438
 
412
439
  if (!ndef.isWritable()) {
@@ -414,13 +441,11 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
414
441
  } else if (ndef.canMakeReadOnly()) {
415
442
  success = ndef.makeReadOnly();
416
443
  } else {
417
- message = "Tag can not be made read only";
444
+ message = "Tag cannot be made read only";
418
445
  }
419
-
420
446
  } else {
421
447
  message = "Tag is not NDEF";
422
448
  }
423
-
424
449
  } catch (IOException e) {
425
450
  Log.e(TAG, "Failed to make tag read only", e);
426
451
  if (e.getMessage() != null) {
@@ -439,31 +464,14 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
439
464
  }
440
465
 
441
466
  private void shareTag(JSONArray data, CallbackContext callbackContext) throws JSONException {
442
- NdefRecord[] records = Util.jsonToNdefRecords(data.getString(0));
443
- this.p2pMessage = new NdefMessage(records);
444
-
445
- startNdefPush(callbackContext);
467
+ callbackContext.success();
446
468
  }
447
469
 
448
- // setBeamPushUris
449
- // Every Uri you provide must have either scheme 'file' or scheme 'content'.
450
- // Note that this takes priority over setNdefPush
451
- //
452
- // See http://developer.android.com/reference/android/nfc/NfcAdapter.html#setBeamPushUris(android.net.Uri[],%20android.app.Activity)
453
470
  private void handover(JSONArray data, CallbackContext callbackContext) throws JSONException {
454
-
455
- Uri[] uri = new Uri[data.length()];
456
-
457
- for (int i = 0; i < data.length(); i++) {
458
- uri[i] = Uri.parse(data.getString(i));
459
- }
460
-
461
- startNdefBeam(callbackContext, uri);
471
+ callbackContext.success();
462
472
  }
463
473
 
464
474
  private void stopHandover(CallbackContext callbackContext) {
465
- stopNdefBeam();
466
- handoverCallback = null;
467
475
  callbackContext.success();
468
476
  }
469
477
 
@@ -483,7 +491,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
483
491
  Activity activity = getActivity();
484
492
  Intent intent = new Intent(activity, activity.getClass());
485
493
  intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
486
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
494
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
487
495
  pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE);
488
496
  } else {
489
497
  pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
@@ -492,13 +500,13 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
492
500
  }
493
501
 
494
502
  private void addTechList(String[] list) {
495
- this.addTechFilter();
496
- this.addToTechList(list);
503
+ addTechFilter();
504
+ addToTechList(list);
497
505
  }
498
506
 
499
507
  private void removeTechList(String[] list) {
500
- this.removeTechFilter();
501
- this.removeFromTechList(list);
508
+ removeTechFilter();
509
+ removeFromTechList(list);
502
510
  }
503
511
 
504
512
  private void addTechFilter() {
@@ -535,7 +543,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
535
543
  }
536
544
 
537
545
  private void startNfc() {
538
- createPendingIntent(); // onResume can call startNfc before execute
546
+ createPendingIntent();
539
547
 
540
548
  getActivity().runOnUiThread(() -> {
541
549
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
@@ -544,20 +552,12 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
544
552
  try {
545
553
  IntentFilter[] intentFilters = getIntentFilters();
546
554
  String[][] techLists = getTechLists();
547
- // don't start NFC unless some intent filters or tech lists have been added,
548
- // because empty lists act as wildcards and receives ALL scan events
549
555
  if (intentFilters.length > 0 || techLists.length > 0) {
550
556
  nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), intentFilters, techLists);
551
557
  }
552
-
553
- if (p2pMessage != null) {
554
- nfcAdapter.setNdefPushMessage(p2pMessage, getActivity());
555
- }
556
558
  } catch (IllegalStateException e) {
557
- // issue 110 - user exits app with home button while nfc is initializing
558
559
  Log.w(TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
559
560
  }
560
-
561
561
  }
562
562
  });
563
563
  }
@@ -565,91 +565,18 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
565
565
  private void stopNfc() {
566
566
  Log.d(TAG, "stopNfc");
567
567
  getActivity().runOnUiThread(() -> {
568
-
569
568
  NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
570
569
 
571
570
  if (nfcAdapter != null) {
572
571
  try {
573
572
  nfcAdapter.disableForegroundDispatch(getActivity());
574
573
  } catch (IllegalStateException e) {
575
- // issue 125 - user exits app with back button while nfc
576
574
  Log.w(TAG, "Illegal State Exception stopping NFC. Assuming application is terminating.");
577
575
  }
578
576
  }
579
577
  });
580
578
  }
581
579
 
582
- private void startNdefBeam(final CallbackContext callbackContext, final Uri[] uris) {
583
- getActivity().runOnUiThread(() -> {
584
-
585
- NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
586
-
587
- if (nfcAdapter == null) {
588
- callbackContext.error(STATUS_NO_NFC);
589
- } else if (!nfcAdapter.isNdefPushEnabled()) {
590
- callbackContext.error(STATUS_NDEF_PUSH_DISABLED);
591
- } else {
592
- nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity());
593
- try {
594
- nfcAdapter.setBeamPushUris(uris, getActivity());
595
-
596
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
597
- result.setKeepCallback(true);
598
- handoverCallback = callbackContext;
599
- callbackContext.sendPluginResult(result);
600
-
601
- } catch (IllegalArgumentException e) {
602
- callbackContext.error(e.getMessage());
603
- }
604
- }
605
- });
606
- }
607
-
608
- private void startNdefPush(final CallbackContext callbackContext) {
609
- getActivity().runOnUiThread(() -> {
610
-
611
- NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
612
-
613
- if (nfcAdapter == null) {
614
- callbackContext.error(STATUS_NO_NFC);
615
- } else if (!nfcAdapter.isNdefPushEnabled()) {
616
- callbackContext.error(STATUS_NDEF_PUSH_DISABLED);
617
- } else {
618
- nfcAdapter.setNdefPushMessage(p2pMessage, getActivity());
619
- nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity());
620
-
621
- PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
622
- result.setKeepCallback(true);
623
- shareTagCallback = callbackContext;
624
- callbackContext.sendPluginResult(result);
625
- }
626
- });
627
- }
628
-
629
- private void stopNdefPush() {
630
- getActivity().runOnUiThread(() -> {
631
-
632
- NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
633
-
634
- if (nfcAdapter != null) {
635
- nfcAdapter.setNdefPushMessage(null, getActivity());
636
- }
637
-
638
- });
639
- }
640
-
641
- private void stopNdefBeam() {
642
- getActivity().runOnUiThread(() -> {
643
-
644
- NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
645
-
646
- if (nfcAdapter != null) {
647
- nfcAdapter.setBeamPushUris(null, getActivity());
648
- }
649
-
650
- });
651
- }
652
-
653
580
  private void addToTechList(String[] techs) {
654
581
  techLists.add(techs);
655
582
  }
@@ -690,7 +617,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
690
617
  }
691
618
 
692
619
  private String[][] getTechLists() {
693
- //noinspection ToArrayCallWithZeroLengthArrayArgument
694
620
  return techLists.toArray(new String[0][0]);
695
621
  }
696
622
 
@@ -705,47 +631,46 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
705
631
  }
706
632
 
707
633
  Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
708
- Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
634
+ Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
709
635
 
710
636
  if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
711
637
  Ndef ndef = Ndef.get(tag);
712
638
  fireNdefEvent(NDEF_MIME, ndef, messages);
713
-
714
639
  } else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
715
640
  for (String tagTech : tag.getTechList()) {
716
641
  Log.d(TAG, tagTech);
717
642
  if (tagTech.equals(NdefFormatable.class.getName())) {
718
643
  fireNdefFormatableEvent(tag);
719
- } else if (tagTech.equals(Ndef.class.getName())) { //
644
+ } else if (tagTech.equals(Ndef.class.getName())) {
720
645
  Ndef ndef = Ndef.get(tag);
721
646
  fireNdefEvent(NDEF, ndef, messages);
722
647
  }
723
648
  }
724
- }
725
-
726
- if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
727
- fireTagEvent(tag);
649
+ } else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
650
+ fireTagEvent(tag, messages);
728
651
  }
729
652
 
730
653
  setIntent(new Intent());
731
654
  });
732
655
  }
733
656
 
734
- // Send the event data through a channel so the JavaScript side can fire the event
735
657
  private void sendEvent(String type, JSONObject tag) {
736
-
737
658
  try {
738
659
  JSONObject event = new JSONObject();
739
- event.put("type", type); // TAG_DEFAULT, NDEF, NDEF_MIME, NDEF_FORMATABLE
740
- event.put("tag", tag); // JSON representing the NFC tag and NDEF messages
660
+ event.put("type", type);
661
+ event.put("tag", tag);
741
662
 
742
663
  PluginResult result = new PluginResult(PluginResult.Status.OK, event);
743
664
  result.setKeepCallback(true);
744
- channelCallback.sendPluginResult(result);
665
+
666
+ if (channelCallback != null) {
667
+ channelCallback.sendPluginResult(result);
668
+ } else {
669
+ postponedPluginResult = new PostponedPluginResult(new Date(), result);
670
+ }
745
671
  } catch (JSONException e) {
746
672
  Log.e(TAG, "Error sending NFC event through the channel", e);
747
673
  }
748
-
749
674
  }
750
675
 
751
676
  private void fireNdefEvent(String type, Ndef ndef, Parcelable[] messages) {
@@ -757,41 +682,32 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
757
682
  sendEvent(NDEF_FORMATABLE, Util.tagToJSON(tag));
758
683
  }
759
684
 
760
- private void fireTagEvent(Tag tag) {
685
+ private void fireTagEvent(Tag tag, Parcelable[] messages) {
761
686
  sendEvent(TAG_DEFAULT, Util.tagToJSON(tag));
762
687
  }
763
688
 
764
689
  private JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
765
-
766
690
  JSONObject json = Util.ndefToJSON(ndef);
767
691
 
768
- // ndef is null for peer-to-peer
769
- // ndef and messages are null for ndef format-able
770
692
  if (ndef == null && messages != null) {
771
-
772
693
  try {
773
-
774
694
  if (messages.length > 0) {
775
695
  NdefMessage message = (NdefMessage) messages[0];
776
696
  json.put("ndefMessage", Util.messageToJSON(message));
777
- // guessing type, would prefer a more definitive way to determine type
778
697
  json.put("type", "NDEF Push Protocol");
779
698
  }
780
699
 
781
700
  if (messages.length > 1) {
782
701
  Log.wtf(TAG, "Expected one ndefMessage but found " + messages.length);
783
702
  }
784
-
785
703
  } catch (JSONException e) {
786
- // shouldn't happen
787
704
  Log.e(Util.TAG, "Failed to convert ndefMessage into json", e);
788
705
  }
789
706
  }
790
707
  return json;
791
708
  }
792
709
 
793
- private boolean recycledIntent() { // TODO this is a kludge, find real solution
794
-
710
+ private boolean recycledIntent() {
795
711
  int flags = getIntent().getFlags();
796
712
  if ((flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) {
797
713
  Log.i(TAG, "Launched from history, killing recycled intent");
@@ -806,7 +722,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
806
722
  Log.d(TAG, "onPause " + getIntent());
807
723
  super.onPause(multitasking);
808
724
  if (multitasking) {
809
- // nfc can't run in background
810
725
  stopNfc();
811
726
  }
812
727
  }
@@ -839,34 +754,9 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
839
754
  getActivity().setIntent(intent);
840
755
  }
841
756
 
842
- @Override
843
- public void onNdefPushComplete(NfcEvent event) {
844
-
845
- // handover (beam) take precedence over share tag (ndef push)
846
- if (handoverCallback != null) {
847
- PluginResult result = new PluginResult(PluginResult.Status.OK, "Beamed Message to Peer");
848
- result.setKeepCallback(true);
849
- handoverCallback.sendPluginResult(result);
850
- } else if (shareTagCallback != null) {
851
- PluginResult result = new PluginResult(PluginResult.Status.OK, "Shared Message with Peer");
852
- result.setKeepCallback(true);
853
- shareTagCallback.sendPluginResult(result);
854
- }
855
-
856
- }
857
-
858
- /**
859
- * Enable I/O operations to the tag from this TagTechnology object.
860
- * *
861
- *
862
- * @param tech TagTechnology class name e.g. 'android.nfc.tech.IsoDep' or 'android.nfc.tech.NfcV'
863
- * @param timeout tag timeout
864
- * @param callbackContext Cordova callback context
865
- */
866
757
  private void connect(final String tech, final int timeout, final CallbackContext callbackContext) {
867
758
  this.cordova.getThreadPool().execute(() -> {
868
759
  try {
869
-
870
760
  Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
871
761
  if (tag == null && savedIntent != null) {
872
762
  tag = savedIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
@@ -880,21 +770,18 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
880
770
 
881
771
  JSONObject resultObject = new JSONObject();
882
772
 
883
- // get technologies supported by this tag
884
773
  List<String> techList = Arrays.asList(tag.getTechList());
885
774
  if (techList.contains(tech)) {
886
- // use reflection to call the static function Tech.get(tag)
887
775
  tagTechnologyClass = Class.forName(tech);
888
776
  Method method = tagTechnologyClass.getMethod("get", Tag.class);
889
777
  tagTechnology = (TagTechnology) method.invoke(null, tag);
890
778
 
891
- // If the tech supports it, return maxTransceiveLength and return it to the user
892
779
  try {
893
780
  Method maxTransceiveLengthMethod = tagTechnologyClass.getMethod("getMaxTransceiveLength");
894
781
  resultObject.put("maxTransceiveLength", maxTransceiveLengthMethod.invoke(tagTechnology));
895
- } catch(NoSuchMethodException e) {
782
+ } catch (NoSuchMethodException e) {
896
783
  // Some technologies do not support this, so just ignore.
897
- } catch(JSONException e) {
784
+ } catch (JSONException e) {
898
785
  Log.e(TAG, "Error serializing JSON", e);
899
786
  }
900
787
  }
@@ -912,24 +799,13 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
912
799
  Log.e(TAG, "Tag connection failed", ex);
913
800
  callbackContext.error("Tag connection failed");
914
801
 
915
- // Users should never get these reflection errors
916
- } catch (ClassNotFoundException e) {
917
- Log.e(TAG, e.getMessage(), e);
918
- callbackContext.error(e.getMessage());
919
- } catch (NoSuchMethodException e) {
920
- Log.e(TAG, e.getMessage(), e);
921
- callbackContext.error(e.getMessage());
922
- } catch (IllegalAccessException e) {
923
- Log.e(TAG, e.getMessage(), e);
924
- callbackContext.error(e.getMessage());
925
- } catch (InvocationTargetException e) {
802
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
926
803
  Log.e(TAG, e.getMessage(), e);
927
804
  callbackContext.error(e.getMessage());
928
805
  }
929
806
  });
930
807
  }
931
808
 
932
- // Call tagTech setTimeout with reflection or fail silently
933
809
  private void setTimeout(int timeout) {
934
810
  if (timeout < 0) {
935
811
  return;
@@ -937,33 +813,21 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
937
813
  try {
938
814
  Method setTimeout = tagTechnologyClass.getMethod("setTimeout", int.class);
939
815
  setTimeout.invoke(tagTechnology, timeout);
940
- } catch (NoSuchMethodException e) {
941
- // ignore
942
- } catch (IllegalAccessException e) {
943
- // ignore
944
- } catch (InvocationTargetException e) {
816
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
945
817
  // ignore
946
818
  }
947
819
  }
948
820
 
949
- /**
950
- * Disable I/O operations to the tag from this TagTechnology object, and release resources.
951
- *
952
- * @param callbackContext Cordova callback context
953
- */
954
821
  private void close(CallbackContext callbackContext) {
955
822
  cordova.getThreadPool().execute(() -> {
956
823
  try {
957
-
958
824
  if (tagTechnology != null && tagTechnology.isConnected()) {
959
825
  tagTechnology.close();
960
826
  tagTechnology = null;
961
827
  callbackContext.success();
962
828
  } else {
963
- // connection already gone
964
829
  callbackContext.success();
965
830
  }
966
-
967
831
  } catch (IOException ex) {
968
832
  Log.e(TAG, "Error closing nfc connection", ex);
969
833
  callbackContext.error("Error closing nfc connection " + ex.getLocalizedMessage());
@@ -971,12 +835,6 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
971
835
  });
972
836
  }
973
837
 
974
- /**
975
- * Send raw commands to the tag and receive the response.
976
- *
977
- * @param data byte[] command to be passed to the tag
978
- * @param callbackContext Cordova callback context
979
- */
980
838
  private void transceive(final byte[] data, final CallbackContext callbackContext) {
981
839
  cordova.getThreadPool().execute(() -> {
982
840
  try {
@@ -991,9 +849,7 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
991
849
  return;
992
850
  }
993
851
 
994
- // Use reflection so we can support many tag types
995
852
  Method transceiveMethod = tagTechnologyClass.getMethod("transceive", byte[].class);
996
- @SuppressWarnings("PrimitiveArrayArgumentToVarargsMethod")
997
853
  byte[] response = (byte[]) transceiveMethod.invoke(tagTechnology, data);
998
854
 
999
855
  callbackContext.success(response);
@@ -1002,19 +858,10 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom
1002
858
  String error = "TagTechnology " + tagTechnologyClass.getName() + " does not have a transceive function";
1003
859
  Log.e(TAG, error, e);
1004
860
  callbackContext.error(error);
1005
- } catch (NullPointerException e) {
1006
- // This can happen if the tag has been closed while we're still working with it from the thread pool.
1007
- Log.e(TAG, e.getMessage(), e);
1008
- callbackContext.error(e.getMessage());
1009
- } catch (IllegalAccessException e) {
861
+ } catch (NullPointerException | IllegalAccessException | InvocationTargetException e) {
1010
862
  Log.e(TAG, e.getMessage(), e);
1011
863
  callbackContext.error(e.getMessage());
1012
- } catch (InvocationTargetException e) {
1013
- Log.e(TAG, e.getMessage(), e);
1014
- Throwable cause = e.getCause();
1015
- callbackContext.error(cause.getMessage());
1016
864
  }
1017
865
  });
1018
866
  }
1019
-
1020
867
  }
package/CHANGES.txt DELETED
@@ -1,118 +0,0 @@
1
- = 1.2.0 =
2
- iOS allow tag read and write in same session #419
3
-
4
- = 1.1.2 =
5
- Android Fix null pointer exception and possible crash #415 Thanks pschlang
6
- iOS Notify Cordova on Successful Tag Write - #408 Thanks H0schi
7
- iOS NDEF tags with no messages causes Read Failed #416
8
-
9
- = 1.1.1 =
10
- CoreNFC Framework is optional #400 Thanks M3skar and wux-shuto
11
-
12
- = 1.1.0 =
13
- Implement nfc.write for iOS
14
- New iOS specific APIs
15
- * scanNdef
16
- * scanTag
17
- * cancelScan
18
- Deprecated old iOS APIs
19
- * beginSession
20
- * invalidate
21
- Remove usage of UIWebView and WKWebView. Send event data to Javascript via the channel callback.
22
-
23
- = 1.0.4 =
24
- Added TAG string for iOS entitlement compatibility #376 Thanks ActionZachson
25
- Add DeviceCapability proximity for Windows 10 builds #358 #265 Thanks DirkHeinke
26
- Fix issue with AndroidManifest.xml #372 by LuisEGR
27
- Fix error in documentation arrayBufferToString doesn't exist #356 Thanks JohnMcLear
28
-
29
- = 1.0.3 =
30
- Remove ES6 code from phonegap-nfc.js #325
31
-
32
- = 1.0.2 =
33
- Add reader mode for Android #326 #198
34
- Add es6 to jshint config, remove strict mode, cleanup jshint errors #325
35
-
36
- = 1.0.1 =
37
- Replace webview.sendJavascript with channel on Android Fixes #196 #249 #225 #263 Thanks jmorille
38
- Update code that removes event listener #257
39
- NFC events not firing on first scan Fixes #217 #324 Thanks homer-jay
40
-
41
- = 1.0.0 =
42
- Add new commands nfc.connect, nfc.tranceive, nfc.close to support sending raw commands to NFC tags on Android.
43
- Support tag types: NfcA (ISO 14443-3A), NfcB (ISO 14443-3B), NfcF (JIS 6319-4), NfcV (ISO 15693), and IsoDep (ISO 14443-4) #320
44
-
45
- = 0.7.3 =
46
- Bump version for npm issues
47
-
48
- = 0.7.2 =
49
- Add support for WKWebView #288 Thanks andreamaioli
50
-
51
- = 0.7.1 =
52
- Automatically Add NFC entitlement for iOS #285 Thanks andreamaioli
53
-
54
- = 0.7.0 =
55
- Add iOS support #139
56
- Fixed language code field length detection #219 Thanks homer-jay
57
- Fixed java.util.ConcurrentModificationException #231 Thanks João Gonçalves (Chuckytuh)
58
- Documentation fixes #224 Thanks Tom Brückner (derwaldgeist)
59
-
60
- = 0.6.6 =
61
- Update Windows platforms (includes Windows Phone 8.1)
62
- * tag event contains nested ndefMessage object #215
63
- * support unformatted tags with addTagDiscoveredListener & removeTagDiscoveredListener #204
64
- * implement showSettings #147
65
- * better error messages when NFC is disabled #213
66
- * use NDEF parsing and encoding code from www/phonegap-nfc.js (remove duplication)
67
- * update documentation
68
-
69
- = 0.6.5 =
70
- Add nfc.showSettings for Android and BlackBerry 10 #147
71
- Fix package name for Blackberry 10
72
-
73
- = 0.6.4 =
74
- Fix Android compile issue #192
75
-
76
- = 0.6.3 =
77
- Drop support for Cordova 2.9 #192
78
- Move plugin to NPM #194
79
-
80
- = 0.6.2 =
81
- Add support for Windows Phone 8.1 and Windows 8.1 @jlkalberer #182
82
- Update share on BlackBerry 10.2 #172
83
- Fix callback for enabled on Android #169
84
- Fix documentation @lezardrouge #180
85
- Fix documentation @JohnMcLear #171
86
-
87
- = 0.6.1 =
88
- Add ndef.tnfToString Fixes #145
89
- Add ndef.androidApplicationRecord(packageName) Fixes #161
90
- Add more documentation for NO_NFC and NFC_DISABLED error codes Fixes #160
91
- Ensure window.nfc is undefined on unsupported platforms like iOS. Fixes #151 & 152 from Jakob Witte Larsen @jakobwitte
92
- Check if NFC is enabled #146 & #154 from David Froehlich @didlich
93
-
94
- = 0.6.0 =
95
- Change signature for remove*Listener methods. Fixes #142
96
-
97
- = 0.5.1 =
98
- nfc.makeReadOnly Fixes #6
99
- Better encoding and decoding of UTF-8 strings. Fixes #102
100
-
101
- = 0.5.0 =
102
- remove listeners for Android implemented by Axel Nennker @AxelNennker #129
103
- bug fix in stopNfc() from Michal Letynski @mletynski #125 #126
104
-
105
- = 0.4.9 =
106
- handleNfcFromIntentFilter is android only
107
- add isType helper #103
108
-
109
- = 0.4.8 =
110
- Fix IllegalArgumentException #110
111
- Update documentation about filtering mime types #71 and #72
112
- Add onLoad for Android #105 and #99
113
- Build better JSON from @didlich #113
114
-
115
- = 0.4.7 =
116
- Rewrite BlackBerry10 implementation for Cordova 3.0
117
- Remove unused Android Ant scripts
118
- Update documentation