react-native-nfc-manager 4.0.0-beta.7 → 4.0.0-beta.9
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/README.md +37 -3
- package/android/src/main/java/community/revteltech/nfc/MifareClassicHandler.java +419 -0
- package/android/src/main/java/community/revteltech/nfc/MifareUltralightHandler.java +84 -0
- package/android/src/main/java/community/revteltech/nfc/NdefHandler.java +373 -0
- package/android/src/main/java/community/revteltech/nfc/NfcAdapterStateChangedReceiver.java +48 -0
- package/android/src/main/java/community/revteltech/nfc/NfcErrorCodes.java +16 -0
- package/android/src/main/java/community/revteltech/nfc/NfcManager.java +333 -1119
- package/android/src/main/java/community/revteltech/nfc/NfcManagerIOSStubBase.java +130 -0
- package/android/src/main/java/community/revteltech/nfc/NfcTechIoRouter.java +258 -0
- package/android/src/main/java/community/revteltech/nfc/TagTechnologyRequest.java +19 -7
- package/android/src/main/java/community/revteltech/nfc/Util.java +201 -0
- package/dist/ndef-lib/constants.js +67 -0
- package/dist/ndef-lib/constants.js.map +1 -0
- package/dist/ndef-lib/index.js +79 -0
- package/dist/ndef-lib/index.js.map +1 -0
- package/dist/ndef-lib/ndef-text.js +29 -0
- package/dist/ndef-lib/ndef-text.js.map +1 -0
- package/dist/ndef-lib/ndef-uri.js +40 -0
- package/dist/ndef-lib/ndef-uri.js.map +1 -0
- package/dist/ndef-lib/ndef-wifi-simple.js +100 -0
- package/dist/ndef-lib/ndef-wifi-simple.js.map +1 -0
- package/dist/ndef-lib/ndef.js +153 -0
- package/dist/ndef-lib/ndef.js.map +1 -0
- package/dist/ndef-lib/stringifier.js +155 -0
- package/dist/ndef-lib/stringifier.js.map +1 -0
- package/dist/ndef-lib/util.js +126 -0
- package/dist/ndef-lib/util.js.map +1 -0
- package/dist/specs/NativeNfcManager.js +5 -0
- package/dist/specs/NativeNfcManager.js.map +1 -0
- package/dist/src/NativeNfcManager.js +55 -0
- package/dist/src/NativeNfcManager.js.map +1 -0
- package/dist/src/NfcError.js +220 -0
- package/dist/src/NfcError.js.map +1 -0
- package/dist/src/NfcManager.js +175 -0
- package/dist/src/NfcManager.js.map +1 -0
- package/dist/src/NfcManagerAndroid.js +112 -0
- package/dist/src/NfcManagerAndroid.js.map +1 -0
- package/dist/src/NfcManagerIOS.js +119 -0
- package/dist/src/NfcManagerIOS.js.map +1 -0
- package/dist/src/NfcTech/Iso15693HandlerIOS.js +99 -0
- package/dist/src/NfcTech/Iso15693HandlerIOS.js.map +1 -0
- package/dist/src/NfcTech/IsoDepHandler.js +29 -0
- package/dist/src/NfcTech/IsoDepHandler.js.map +1 -0
- package/dist/src/NfcTech/MifareClassicHandlerAndroid.js +68 -0
- package/dist/src/NfcTech/MifareClassicHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js +23 -0
- package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js +16 -0
- package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/NdefHandler.js +54 -0
- package/dist/src/NfcTech/NdefHandler.js.map +1 -0
- package/dist/src/NfcTech/NfcAHandler.js +16 -0
- package/dist/src/NfcTech/NfcAHandler.js.map +1 -0
- package/dist/src/NfcTech/NfcVHandler.js +33 -0
- package/dist/src/NfcTech/NfcVHandler.js.map +1 -0
- package/dist/src/index.js +53 -0
- package/dist/src/index.js.map +1 -0
- package/index.d.ts +76 -43
- package/ios/NfcManager.h +2 -10
- package/ios/NfcManager.mm +176 -434
- package/ios/RNNfcBridgeUtil.h +28 -0
- package/ios/RNNfcBridgeUtil.mm +52 -0
- package/ios/RNNfcManager+Felica.swift +61 -0
- package/ios/RNNfcManager+Iso15693.swift +895 -0
- package/ios/RNNfcManager+IsoDep.swift +145 -0
- package/ios/RNNfcManager+Mifare.swift +61 -0
- package/ios/RNNfcManager+Ndef.swift +120 -0
- package/ios/RNNfcManager.h +251 -0
- package/ios/RNNfcManager.swift +648 -0
- package/ios/RNNfcSessionDelegateProxy.swift +104 -0
- package/ios/RNNfcSwiftUtil.swift +34 -0
- package/ndef-lib/{constants.js → constants.ts} +2 -0
- package/ndef-lib/{index.js → index.ts} +23 -12
- package/ndef-lib/{ndef-text.js → ndef-text.ts} +7 -2
- package/ndef-lib/{ndef-uri.js → ndef-uri.ts} +8 -3
- package/ndef-lib/{ndef-wifi-simple.js → ndef-wifi-simple.ts} +34 -11
- package/ndef-lib/{ndef.js → ndef.ts} +49 -20
- package/ndef-lib/{stringifier.js → stringifier.ts} +27 -10
- package/ndef-lib/{util.js → util.ts} +13 -8
- package/package.json +21 -7
- package/react-native-nfc-manager.podspec +3 -2
- package/specs/NativeNfcManager.ts +17 -3
- package/src/NativeNfcManager.ts +84 -0
- package/src/{NfcError.js → NfcError.ts} +6 -17
- package/src/{NfcManager.js → NfcManager.ts} +49 -34
- package/src/{NfcManagerAndroid.js → NfcManagerAndroid.ts} +25 -8
- package/src/{NfcManagerIOS.js → NfcManagerIOS.ts} +31 -10
- package/src/NfcTech/{Iso15693HandlerIOS.js → Iso15693HandlerIOS.ts} +64 -36
- package/src/NfcTech/{IsoDepHandler.js → IsoDepHandler.ts} +8 -5
- package/src/NfcTech/{MifareClassicHandlerAndroid.js → MifareClassicHandlerAndroid.ts} +33 -24
- package/src/NfcTech/{MifareUltralightHandlerAndroid.js → MifareUltralightHandlerAndroid.ts} +14 -5
- package/src/NfcTech/{NdefFormatableHandlerAndroid.js → NdefFormatableHandlerAndroid.ts} +9 -2
- package/src/NfcTech/{NdefHandler.js → NdefHandler.ts} +19 -6
- package/src/NfcTech/{NfcAHandler.js → NfcAHandler.ts} +6 -3
- package/src/NfcTech/{NfcVHandler.js → NfcVHandler.ts} +8 -5
- package/src/__mocks__/{NativeNfcManager.js → NativeNfcManager.ts} +4 -1
- package/src/{index.js → index.ts} +1 -1
- package/android/src/main/java/community/revteltech/nfc/JsonConvert.java +0 -141
- package/android/src/main/java/community/revteltech/nfc/MifareUtil.java +0 -84
- package/ios/NfcManager+Felica.mm +0 -43
- package/ios/NfcManager+Iso15693.mm +0 -600
- package/ios/NfcManager+IsoDep.mm +0 -83
- package/ios/NfcManager+Mifare.mm +0 -43
- package/ios/Util.mm +0 -55
- package/specs/NativeNfcManager.js +0 -3
- package/specs/NativeNfcManager.js.map +0 -1
- package/src/NativeNfcManager.js +0 -37
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
package community.revteltech.nfc;
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import static community.revteltech.nfc.NfcErrorCodes.*;
|
|
4
|
+
|
|
4
5
|
import android.app.Activity;
|
|
5
|
-
import android.content.BroadcastReceiver;
|
|
6
|
-
import android.content.Context;
|
|
7
6
|
import android.content.Intent;
|
|
8
7
|
import android.content.IntentFilter;
|
|
9
8
|
import android.content.pm.PackageManager;
|
|
@@ -18,66 +17,31 @@ import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
|
|
|
18
17
|
|
|
19
18
|
import android.app.PendingIntent;
|
|
20
19
|
import android.content.IntentFilter.MalformedMimeTypeException;
|
|
21
|
-
import android.nfc.FormatException;
|
|
22
|
-
import android.nfc.NdefMessage;
|
|
23
20
|
import android.nfc.NfcAdapter;
|
|
24
21
|
import android.nfc.Tag;
|
|
25
|
-
import android.nfc.TagLostException;
|
|
26
|
-
import android.nfc.tech.TagTechnology;
|
|
27
22
|
import android.nfc.tech.Ndef;
|
|
28
|
-
import android.nfc.tech.NfcA;
|
|
29
|
-
import android.nfc.tech.NfcB;
|
|
30
|
-
import android.nfc.tech.NfcF;
|
|
31
|
-
import android.nfc.tech.NfcV;
|
|
32
|
-
import android.nfc.tech.IsoDep;
|
|
33
|
-
import android.nfc.tech.NdefFormatable;
|
|
34
|
-
import android.nfc.tech.MifareClassic;
|
|
35
|
-
import android.nfc.tech.MifareUltralight;
|
|
36
|
-
import android.os.Parcelable;
|
|
37
23
|
import android.os.Bundle;
|
|
38
|
-
|
|
39
|
-
import org.json.JSONObject;
|
|
40
|
-
import org.json.JSONException;
|
|
24
|
+
import android.os.Parcelable;
|
|
41
25
|
|
|
42
26
|
import java.util.*;
|
|
43
27
|
|
|
44
|
-
class NfcManager extends
|
|
28
|
+
class NfcManager extends NfcManagerIOSStubBase implements ActivityEventListener, LifecycleEventListener {
|
|
45
29
|
private static final String LOG_TAG = "ReactNativeNfcManager";
|
|
46
30
|
private final List<IntentFilter> intentFilters = new ArrayList<>();
|
|
47
31
|
private final ArrayList<String[]> techLists = new ArrayList<>();
|
|
48
32
|
private Boolean isForegroundEnabled = false;
|
|
49
33
|
private Boolean isResumed = false;
|
|
50
|
-
private WriteNdefRequest writeNdefRequest = null;
|
|
34
|
+
private NdefHandler.WriteNdefRequest writeNdefRequest = null;
|
|
51
35
|
private TagTechnologyRequest techRequest = null;
|
|
52
36
|
private Tag tag = null;
|
|
53
37
|
private WritableMap bgTag = null;
|
|
38
|
+
private Activity receiverActivity = null;
|
|
54
39
|
// Use NFC reader mode instead of listening to a dispatch
|
|
55
40
|
private Boolean isReaderModeEnabled = false;
|
|
56
41
|
private int readerModeFlags = 0;
|
|
57
42
|
private int readerModeDelay = 0;
|
|
58
|
-
private
|
|
59
|
-
|
|
60
|
-
private static final String ERR_MULTI_REQ = "You can only issue one request at a time";
|
|
61
|
-
private static final String ERR_NO_TECH_REQ = "no tech request available";
|
|
62
|
-
private static final String ERR_NO_REFERENCE = "no reference available";
|
|
63
|
-
private static final String ERR_TRANSCEIVE_FAIL = "transceive fail";
|
|
64
|
-
private static final String ERR_API_NOT_SUPPORT = "unsupported tag api";
|
|
65
|
-
private static final String ERR_GET_ACTIVITY_FAIL = "fail to get current activity";
|
|
66
|
-
private static final String ERR_NO_NFC_SUPPORT = "no nfc support";
|
|
67
|
-
|
|
68
|
-
static class WriteNdefRequest {
|
|
69
|
-
NdefMessage message;
|
|
70
|
-
Callback callback;
|
|
71
|
-
boolean format;
|
|
72
|
-
boolean formatReadOnly;
|
|
73
|
-
|
|
74
|
-
WriteNdefRequest(NdefMessage message, Callback callback, boolean format, boolean formatReadOnly) {
|
|
75
|
-
this.message = message;
|
|
76
|
-
this.callback = callback;
|
|
77
|
-
this.format = format;
|
|
78
|
-
this.formatReadOnly = formatReadOnly;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
43
|
+
private final NfcAdapterStateChangedReceiver mReceiver =
|
|
44
|
+
new NfcAdapterStateChangedReceiver(LOG_TAG, this::emitAdapterStateChanged);
|
|
81
45
|
|
|
82
46
|
public NfcManager(ReactApplicationContext reactContext) {
|
|
83
47
|
super(reactContext);
|
|
@@ -96,31 +60,23 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
96
60
|
public Map<String, Object> getConstants() {
|
|
97
61
|
final Map<String, Object> constants = new HashMap<>();
|
|
98
62
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
constants.put("MIFARE_ULTRALIGHT_TYPE", MifareUltralight.TYPE_ULTRALIGHT);
|
|
102
|
-
constants.put("MIFARE_ULTRALIGHT_TYPE_C", MifareUltralight.TYPE_ULTRALIGHT_C);
|
|
103
|
-
constants.put("MIFARE_ULTRALIGHT_TYPE_UNKNOWN", MifareUltralight.TYPE_UNKNOWN);
|
|
63
|
+
MifareClassicHandler.putConstants(constants);
|
|
64
|
+
MifareUltralightHandler.putConstants(constants);
|
|
104
65
|
|
|
105
66
|
return constants;
|
|
106
67
|
}
|
|
107
68
|
|
|
108
|
-
private boolean hasPendingRequest() {
|
|
109
|
-
return writeNdefRequest != null || techRequest != null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
69
|
@ReactMethod
|
|
113
70
|
public void cancelTechnologyRequest(Callback callback) {
|
|
114
71
|
synchronized(this) {
|
|
115
|
-
|
|
116
|
-
|
|
72
|
+
TagTechnologyRequest request = detachTechnologyRequest();
|
|
73
|
+
if (request != null) {
|
|
74
|
+
request.close();
|
|
117
75
|
try {
|
|
118
|
-
|
|
76
|
+
request.invokePendingCallbackWithError(ERR_CANCEL);
|
|
119
77
|
} catch (RuntimeException ex) {
|
|
120
|
-
|
|
121
|
-
// connected tag, bypass this case explicitly
|
|
78
|
+
Log.w(LOG_TAG, "fail to complete cancelled technology request", ex);
|
|
122
79
|
}
|
|
123
|
-
techRequest = null;
|
|
124
80
|
}
|
|
125
81
|
callback.invoke();
|
|
126
82
|
}
|
|
@@ -145,9 +101,14 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
145
101
|
@ReactMethod
|
|
146
102
|
public void closeTechnology(Callback callback) {
|
|
147
103
|
synchronized(this) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
104
|
+
TagTechnologyRequest request = detachTechnologyRequest();
|
|
105
|
+
if (request != null) {
|
|
106
|
+
request.close();
|
|
107
|
+
try {
|
|
108
|
+
request.invokePendingCallbackWithError(ERR_CANCEL);
|
|
109
|
+
} catch (RuntimeException ex) {
|
|
110
|
+
Log.w(LOG_TAG, "fail to complete closed technology request", ex);
|
|
111
|
+
}
|
|
151
112
|
}
|
|
152
113
|
callback.invoke();
|
|
153
114
|
}
|
|
@@ -159,11 +120,10 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
159
120
|
if (techRequest != null) {
|
|
160
121
|
Tag tag = techRequest.getTagHandle();
|
|
161
122
|
if (tag != null) {
|
|
162
|
-
WritableMap parsed =
|
|
123
|
+
WritableMap parsed = Util.tagToReact(tag);
|
|
163
124
|
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
164
125
|
try {
|
|
165
|
-
|
|
166
|
-
parsed = ndef2React(ndef, new NdefMessage[]{ndef.getCachedNdefMessage()});
|
|
126
|
+
parsed = NdefHandler.ndefToReact(tag);
|
|
167
127
|
} catch (Exception ex) {
|
|
168
128
|
Log.d(LOG_TAG, ex.toString());
|
|
169
129
|
}
|
|
@@ -181,898 +141,322 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
181
141
|
@ReactMethod
|
|
182
142
|
public void getCachedNdefMessage(Callback callback) {
|
|
183
143
|
synchronized(this) {
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
Ndef ndef = Ndef.get(techRequest.getTagHandle());
|
|
187
|
-
WritableMap parsed = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
|
|
188
|
-
callback.invoke(null, parsed);
|
|
189
|
-
} catch (Exception ex) {
|
|
190
|
-
Log.d(LOG_TAG, ex.toString());
|
|
191
|
-
callback.invoke(ex.toString());
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
195
|
-
}
|
|
144
|
+
NdefHandler.getCachedNdefMessage(techRequest, callback);
|
|
196
145
|
}
|
|
197
146
|
}
|
|
198
147
|
|
|
199
148
|
@ReactMethod
|
|
200
149
|
public void getNdefMessage(Callback callback) {
|
|
201
150
|
synchronized(this) {
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
Ndef ndef = Ndef.get(techRequest.getTagHandle());
|
|
205
|
-
WritableMap parsed = ndef2React(null, new NdefMessage[] { ndef.getNdefMessage() });
|
|
206
|
-
callback.invoke(null, parsed);
|
|
207
|
-
} catch (Exception ex) {
|
|
208
|
-
Log.d(LOG_TAG, ex.toString());
|
|
209
|
-
callback.invoke(ex.toString());
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
213
|
-
}
|
|
151
|
+
NdefHandler.getNdefMessage(techRequest, callback);
|
|
214
152
|
}
|
|
215
153
|
}
|
|
216
154
|
|
|
217
155
|
@ReactMethod
|
|
218
156
|
public void queryNdefStatus(Callback callback) {
|
|
219
157
|
synchronized(this) {
|
|
220
|
-
|
|
221
|
-
WritableMap writableMap = Arguments.createMap();
|
|
222
|
-
try {
|
|
223
|
-
Ndef ndef = Ndef.get(techRequest.getTagHandle());
|
|
224
|
-
int maxSize = ndef.getMaxSize();
|
|
225
|
-
boolean isWritable = ndef.isWritable();
|
|
226
|
-
boolean canMakeReadOnly = ndef.canMakeReadOnly();
|
|
227
|
-
writableMap.putInt("maxSize", maxSize);
|
|
228
|
-
writableMap.putBoolean("isWritable", isWritable);
|
|
229
|
-
writableMap.putBoolean("canMakeReadOnly", canMakeReadOnly);
|
|
230
|
-
callback.invoke(null, writableMap);
|
|
231
|
-
} catch (Exception ex) {
|
|
232
|
-
Log.d(LOG_TAG, ex.toString());
|
|
233
|
-
callback.invoke(ex.toString());
|
|
234
|
-
}
|
|
235
|
-
} else {
|
|
236
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
237
|
-
}
|
|
158
|
+
NdefHandler.queryNdefStatus(techRequest, callback);
|
|
238
159
|
}
|
|
239
160
|
}
|
|
240
161
|
|
|
241
162
|
@ReactMethod
|
|
242
163
|
public void writeNdefMessage(ReadableArray rnArray, ReadableMap options, Callback callback) {
|
|
243
164
|
synchronized(this) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
251
|
-
} else {
|
|
252
|
-
byte[] bytes = rnArrayToBytes(rnArray);
|
|
253
|
-
ndef.writeNdefMessage(new NdefMessage(bytes));
|
|
254
|
-
if (reconnectAfterWrite) {
|
|
255
|
-
ndef.close();
|
|
256
|
-
//reconnection is needed in order to be able to read the written ndef
|
|
257
|
-
ndef.connect();
|
|
258
|
-
}
|
|
259
|
-
callback.invoke();
|
|
260
|
-
}
|
|
261
|
-
} catch (Exception ex) {
|
|
262
|
-
Log.d(LOG_TAG, ex.toString());
|
|
263
|
-
callback.invoke(ex.toString());
|
|
264
|
-
}
|
|
265
|
-
} else {
|
|
266
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
267
|
-
}
|
|
165
|
+
NdefHandler.writeNdefMessage(
|
|
166
|
+
techRequest,
|
|
167
|
+
rnArray,
|
|
168
|
+
options,
|
|
169
|
+
callback
|
|
170
|
+
);
|
|
268
171
|
}
|
|
269
172
|
}
|
|
270
173
|
|
|
271
174
|
@ReactMethod
|
|
272
175
|
public void formatNdef(ReadableArray rnArray, ReadableMap options, Callback callback) {
|
|
273
|
-
boolean readOnly = options.getBoolean("readOnly");
|
|
274
|
-
|
|
275
176
|
synchronized(this) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
byte[] bytes = rnArrayToBytes(rnArray);
|
|
283
|
-
NdefMessage msg = new NdefMessage(bytes);
|
|
284
|
-
if (readOnly) {
|
|
285
|
-
ndef.formatReadOnly(msg);
|
|
286
|
-
} else {
|
|
287
|
-
ndef.format(msg);
|
|
288
|
-
}
|
|
289
|
-
callback.invoke();
|
|
290
|
-
}
|
|
291
|
-
} catch (Exception ex) {
|
|
292
|
-
Log.d(LOG_TAG, ex.toString());
|
|
293
|
-
callback.invoke(ex.toString());
|
|
294
|
-
}
|
|
295
|
-
} else {
|
|
296
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
private void mifareClassicAuthenticate(char type, int sector, ReadableArray key, Callback callback) {
|
|
302
|
-
if (techRequest != null) {
|
|
303
|
-
try {
|
|
304
|
-
MifareClassic mifareTag = (MifareClassic) techRequest.getTechHandle();
|
|
305
|
-
if (mifareTag == null || mifareTag.getType() == MifareClassic.TYPE_UNKNOWN) {
|
|
306
|
-
// Not a mifare card, fail
|
|
307
|
-
callback.invoke("mifareClassicAuthenticate fail: TYPE_UNKNOWN");
|
|
308
|
-
return;
|
|
309
|
-
} else if (sector >= mifareTag.getSectorCount()) {
|
|
310
|
-
// Check if in range
|
|
311
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicAuthenticate fail: invalid sector %d (max %d)", sector, mifareTag.getSectorCount());
|
|
312
|
-
callback.invoke(msg);
|
|
313
|
-
return;
|
|
314
|
-
} else if (key.size() != 6) {
|
|
315
|
-
// Invalid key length
|
|
316
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicAuthenticate fail: invalid key (needs length 6 but has %d characters)", key.size());
|
|
317
|
-
callback.invoke(msg);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
boolean result;
|
|
322
|
-
if (type == 'A') {
|
|
323
|
-
result = mifareTag.authenticateSectorWithKeyA(sector, rnArrayToBytes(key));
|
|
324
|
-
} else {
|
|
325
|
-
result = mifareTag.authenticateSectorWithKeyB(sector, rnArrayToBytes(key));
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (!result) {
|
|
329
|
-
callback.invoke("mifareClassicAuthenticate fail: AUTH_FAIL");
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
callback.invoke(null, true);
|
|
334
|
-
} catch (TagLostException ex) {
|
|
335
|
-
callback.invoke("mifareClassicAuthenticate fail: TAG_LOST");
|
|
336
|
-
} catch (Exception ex) {
|
|
337
|
-
callback.invoke("mifareClassicAuthenticate fail: " + ex);
|
|
338
|
-
}
|
|
339
|
-
} else {
|
|
340
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
177
|
+
NdefHandler.formatNdef(
|
|
178
|
+
techRequest,
|
|
179
|
+
rnArray,
|
|
180
|
+
options,
|
|
181
|
+
callback
|
|
182
|
+
);
|
|
341
183
|
}
|
|
342
184
|
}
|
|
343
185
|
|
|
344
186
|
@ReactMethod
|
|
345
187
|
public void mifareClassicAuthenticateA(double sector, ReadableArray key, Callback callback) {
|
|
346
188
|
synchronized(this) {
|
|
347
|
-
|
|
189
|
+
MifareClassicHandler.authenticate(techRequest, 'A', (int)sector, key, callback);
|
|
348
190
|
}
|
|
349
191
|
}
|
|
350
192
|
|
|
351
193
|
@ReactMethod
|
|
352
194
|
public void mifareClassicAuthenticateB(double sector, ReadableArray key, Callback callback) {
|
|
353
195
|
synchronized(this) {
|
|
354
|
-
|
|
196
|
+
MifareClassicHandler.authenticate(techRequest, 'B', (int)sector, key, callback);
|
|
355
197
|
}
|
|
356
198
|
}
|
|
357
199
|
|
|
358
200
|
@ReactMethod
|
|
359
201
|
public void mifareClassicGetBlockCountInSector(double _sectorIndex, Callback callback) {
|
|
360
|
-
int sectorIndex = (int)_sectorIndex;
|
|
361
202
|
synchronized(this) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
callback.invoke("mifareClassicGetBlockCountInSector fail: TYPE_UNKNOWN");
|
|
368
|
-
return;
|
|
369
|
-
} else if (sectorIndex >= mifareTag.getSectorCount()) {
|
|
370
|
-
// Check if in range
|
|
371
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicGetBlockCountInSector fail: invalid sector %d (max %d)", sectorIndex, mifareTag.getSectorCount());
|
|
372
|
-
callback.invoke(msg);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
callback.invoke(null, mifareTag.getBlockCountInSector(sectorIndex));
|
|
377
|
-
} catch (Exception ex) {
|
|
378
|
-
callback.invoke("mifareClassicGetBlockCountInSector fail: " + ex);
|
|
379
|
-
}
|
|
380
|
-
} else {
|
|
381
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
382
|
-
}
|
|
203
|
+
MifareClassicHandler.getBlockCountInSector(
|
|
204
|
+
techRequest,
|
|
205
|
+
(int)_sectorIndex,
|
|
206
|
+
callback
|
|
207
|
+
);
|
|
383
208
|
}
|
|
384
209
|
}
|
|
385
210
|
|
|
386
211
|
@ReactMethod
|
|
387
212
|
public void mifareClassicGetSectorCount(Callback callback) {
|
|
388
213
|
synchronized(this) {
|
|
389
|
-
|
|
390
|
-
try {
|
|
391
|
-
MifareClassic mifareTag = (MifareClassic) techRequest.getTechHandle();
|
|
392
|
-
if (mifareTag == null || mifareTag.getType() == MifareClassic.TYPE_UNKNOWN) {
|
|
393
|
-
// Not a mifare card, fail
|
|
394
|
-
callback.invoke("mifareClassicGetSectorCount fail: TYPE_UNKNOWN");
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
callback.invoke(null, mifareTag.getSectorCount());
|
|
399
|
-
} catch (Exception ex) {
|
|
400
|
-
callback.invoke("mifareClassicGetSectorCount fail: " + ex);
|
|
401
|
-
}
|
|
402
|
-
} else {
|
|
403
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
404
|
-
}
|
|
214
|
+
MifareClassicHandler.getSectorCount(techRequest, callback);
|
|
405
215
|
}
|
|
406
216
|
}
|
|
407
217
|
|
|
408
218
|
@ReactMethod
|
|
409
219
|
public void mifareClassicSectorToBlock(double _sectorIndex, Callback callback) {
|
|
410
|
-
int sectorIndex = (int)_sectorIndex;
|
|
411
220
|
synchronized(this) {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
callback.invoke("mifareClassicSectorToBlock fail: TYPE_UNKNOWN");
|
|
418
|
-
return;
|
|
419
|
-
} else if (sectorIndex >= mifareTag.getSectorCount()) {
|
|
420
|
-
// Check if in range
|
|
421
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicSectorToBlock fail: invalid sector %d (max %d)", sectorIndex, mifareTag.getSectorCount());
|
|
422
|
-
callback.invoke(msg);
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
callback.invoke(null, mifareTag.sectorToBlock(sectorIndex));
|
|
427
|
-
} catch (Exception ex) {
|
|
428
|
-
callback.invoke("mifareClassicSectorToBlock fail: " + ex);
|
|
429
|
-
}
|
|
430
|
-
} else {
|
|
431
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
432
|
-
}
|
|
221
|
+
MifareClassicHandler.sectorToBlock(
|
|
222
|
+
techRequest,
|
|
223
|
+
(int)_sectorIndex,
|
|
224
|
+
callback
|
|
225
|
+
);
|
|
433
226
|
}
|
|
434
227
|
}
|
|
435
228
|
|
|
436
229
|
@ReactMethod
|
|
437
230
|
public void mifareClassicReadBlock(double _blockIndex, Callback callback) {
|
|
438
|
-
int blockIndex = (int)_blockIndex;
|
|
439
231
|
synchronized(this) {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
callback.invoke("mifareClassicReadBlock fail: TYPE_UNKNOWN");
|
|
446
|
-
return;
|
|
447
|
-
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
448
|
-
// Check if in range
|
|
449
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicReadBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
450
|
-
callback.invoke(msg);
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
byte[] buffer = mifareTag.readBlock(blockIndex);
|
|
455
|
-
|
|
456
|
-
WritableArray result = bytesToRnArray(buffer);
|
|
457
|
-
callback.invoke(null, result);
|
|
458
|
-
} catch (TagLostException ex) {
|
|
459
|
-
callback.invoke("mifareClassicReadBlock fail: TAG_LOST");
|
|
460
|
-
} catch (Exception ex) {
|
|
461
|
-
callback.invoke("mifareClassicReadBlock fail: " + ex);
|
|
462
|
-
}
|
|
463
|
-
} else {
|
|
464
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
465
|
-
}
|
|
232
|
+
MifareClassicHandler.readBlock(
|
|
233
|
+
techRequest,
|
|
234
|
+
(int)_blockIndex,
|
|
235
|
+
callback
|
|
236
|
+
);
|
|
466
237
|
}
|
|
467
238
|
}
|
|
468
239
|
|
|
469
240
|
@ReactMethod
|
|
470
241
|
public void mifareClassicReadSector(double _sectorIndex, Callback callback) {
|
|
471
|
-
int sectorIndex = (int)_sectorIndex;
|
|
472
242
|
synchronized(this) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
callback.invoke("mifareClassicReadSector fail: TYPE_UNKNOWN");
|
|
479
|
-
return;
|
|
480
|
-
} else if (sectorIndex >= mifareTag.getSectorCount()) {
|
|
481
|
-
// Check if in range
|
|
482
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicReadSector fail: invalid sector %d (max %d)", sectorIndex, mifareTag.getSectorCount());
|
|
483
|
-
callback.invoke(msg);
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
WritableArray result = Arguments.createArray();
|
|
488
|
-
int blocks = mifareTag.getBlockCountInSector(sectorIndex);
|
|
489
|
-
byte[] buffer;
|
|
490
|
-
for (int i = 0; i < blocks; i++) {
|
|
491
|
-
buffer = mifareTag.readBlock(mifareTag.sectorToBlock(sectorIndex)+i);
|
|
492
|
-
appendBytesToRnArray(result, buffer);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
callback.invoke(null, result);
|
|
496
|
-
} catch (TagLostException ex) {
|
|
497
|
-
callback.invoke("mifareClassicReadSector fail: TAG_LOST");
|
|
498
|
-
} catch (Exception ex) {
|
|
499
|
-
callback.invoke("mifareClassicReadSector fail: " + ex);
|
|
500
|
-
}
|
|
501
|
-
} else {
|
|
502
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
503
|
-
}
|
|
243
|
+
MifareClassicHandler.readSector(
|
|
244
|
+
techRequest,
|
|
245
|
+
(int)_sectorIndex,
|
|
246
|
+
callback
|
|
247
|
+
);
|
|
504
248
|
}
|
|
505
249
|
}
|
|
506
250
|
|
|
507
251
|
@ReactMethod
|
|
508
252
|
public void mifareClassicWriteBlock(double _blockIndex, ReadableArray block, Callback callback) {
|
|
509
|
-
int blockIndex = (int)_blockIndex;
|
|
510
253
|
synchronized(this) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
return;
|
|
518
|
-
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
519
|
-
// Check if in range
|
|
520
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicWriteBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
521
|
-
callback.invoke(msg);
|
|
522
|
-
return;
|
|
523
|
-
} else if (block.size() != MifareClassic.BLOCK_SIZE) {
|
|
524
|
-
// Wrong block count
|
|
525
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicWriteBlock fail: invalid block size %d (should be %d)", block.size(), MifareClassic.BLOCK_SIZE);
|
|
526
|
-
callback.invoke(msg);
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
byte[] buffer = rnArrayToBytes(block);
|
|
531
|
-
mifareTag.writeBlock(blockIndex, buffer);
|
|
532
|
-
|
|
533
|
-
callback.invoke(null, true);
|
|
534
|
-
} catch (TagLostException ex) {
|
|
535
|
-
callback.invoke("mifareClassicWriteBlock fail: TAG_LOST");
|
|
536
|
-
} catch (Exception ex) {
|
|
537
|
-
callback.invoke("mifareClassicWriteBlock fail: " + ex);
|
|
538
|
-
}
|
|
539
|
-
} else {
|
|
540
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
541
|
-
}
|
|
254
|
+
MifareClassicHandler.writeBlock(
|
|
255
|
+
techRequest,
|
|
256
|
+
(int)_blockIndex,
|
|
257
|
+
block,
|
|
258
|
+
callback
|
|
259
|
+
);
|
|
542
260
|
}
|
|
543
261
|
}
|
|
544
262
|
|
|
545
263
|
@ReactMethod
|
|
546
264
|
public void mifareClassicIncrementBlock(double _blockIndex, double _value, Callback callback) {
|
|
547
|
-
int blockIndex = (int)_blockIndex;
|
|
548
|
-
int value = (int)_value;
|
|
549
265
|
synchronized(this) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return;
|
|
557
|
-
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
558
|
-
// Check if in range
|
|
559
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicIncrementBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
560
|
-
callback.invoke(msg);
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
mifareTag.increment(blockIndex, value);
|
|
565
|
-
|
|
566
|
-
callback.invoke(null, true);
|
|
567
|
-
} catch (TagLostException ex) {
|
|
568
|
-
callback.invoke("mifareClassicIncrementBlock fail: TAG_LOST");
|
|
569
|
-
} catch (Exception ex) {
|
|
570
|
-
callback.invoke("mifareClassicIncrementBlock fail: " + ex);
|
|
571
|
-
}
|
|
572
|
-
} else {
|
|
573
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
574
|
-
}
|
|
266
|
+
MifareClassicHandler.incrementBlock(
|
|
267
|
+
techRequest,
|
|
268
|
+
(int)_blockIndex,
|
|
269
|
+
(int)_value,
|
|
270
|
+
callback
|
|
271
|
+
);
|
|
575
272
|
}
|
|
576
273
|
}
|
|
577
274
|
|
|
578
275
|
@ReactMethod
|
|
579
276
|
public void mifareClassicDecrementBlock(double _blockIndex, double _value, Callback callback) {
|
|
580
|
-
int blockIndex = (int)_blockIndex;
|
|
581
|
-
int value = (int)_value;
|
|
582
277
|
synchronized(this) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return;
|
|
590
|
-
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
591
|
-
// Check if in range
|
|
592
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicDecrementBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
593
|
-
callback.invoke(msg);
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
mifareTag.decrement(blockIndex, value);
|
|
598
|
-
|
|
599
|
-
callback.invoke(null, true);
|
|
600
|
-
} catch (TagLostException ex) {
|
|
601
|
-
callback.invoke("mifareClassicDecrementBlock fail: TAG_LOST");
|
|
602
|
-
} catch (Exception ex) {
|
|
603
|
-
callback.invoke("mifareClassicDecrementBlock fail: " + ex);
|
|
604
|
-
}
|
|
605
|
-
} else {
|
|
606
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
607
|
-
}
|
|
278
|
+
MifareClassicHandler.decrementBlock(
|
|
279
|
+
techRequest,
|
|
280
|
+
(int)_blockIndex,
|
|
281
|
+
(int)_value,
|
|
282
|
+
callback
|
|
283
|
+
);
|
|
608
284
|
}
|
|
609
285
|
}
|
|
610
286
|
|
|
611
287
|
@ReactMethod
|
|
612
288
|
public void mifareClassicTransferBlock(double _blockIndex, Callback callback) {
|
|
613
|
-
int blockIndex = (int)_blockIndex;
|
|
614
289
|
synchronized(this) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
callback.invoke("mifareClassicTransferBlock fail: TYPE_UNKNOWN");
|
|
621
|
-
return;
|
|
622
|
-
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
623
|
-
// Check if in range
|
|
624
|
-
@SuppressLint("DefaultLocale") String msg = String.format("mifareClassicTransferBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
625
|
-
callback.invoke(msg);
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
mifareTag.transfer(blockIndex);
|
|
630
|
-
|
|
631
|
-
callback.invoke(null, true);
|
|
632
|
-
} catch (TagLostException ex) {
|
|
633
|
-
callback.invoke("mifareClassicTransferBlock fail: TAG_LOST");
|
|
634
|
-
} catch (Exception ex) {
|
|
635
|
-
callback.invoke("mifareClassicTransferBlock fail: " + ex);
|
|
636
|
-
}
|
|
637
|
-
} else {
|
|
638
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
639
|
-
}
|
|
290
|
+
MifareClassicHandler.transferBlock(
|
|
291
|
+
techRequest,
|
|
292
|
+
(int)_blockIndex,
|
|
293
|
+
callback
|
|
294
|
+
);
|
|
640
295
|
}
|
|
641
296
|
}
|
|
642
297
|
|
|
643
298
|
@ReactMethod
|
|
644
299
|
public void mifareUltralightReadPages(double pageOffset, Callback callback) {
|
|
645
300
|
synchronized(this) {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
callback.invoke(null, resultRnArray);
|
|
652
|
-
} catch (TagLostException ex) {
|
|
653
|
-
callback.invoke("mifareUltralight fail: TAG_LOST");
|
|
654
|
-
} catch (Exception ex) {
|
|
655
|
-
callback.invoke("mifareUltralight fail: " + ex);
|
|
656
|
-
}
|
|
657
|
-
} else {
|
|
658
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
659
|
-
}
|
|
301
|
+
MifareUltralightHandler.readPages(
|
|
302
|
+
techRequest,
|
|
303
|
+
(int)pageOffset,
|
|
304
|
+
callback
|
|
305
|
+
);
|
|
660
306
|
}
|
|
661
307
|
}
|
|
662
308
|
|
|
663
309
|
@ReactMethod
|
|
664
310
|
public void mifareUltralightWritePage(double pageOffset, ReadableArray rnArray, Callback callback) {
|
|
665
311
|
synchronized(this) {
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
} catch (TagLostException ex) {
|
|
673
|
-
callback.invoke("mifareUltralight fail: TAG_LOST");
|
|
674
|
-
} catch (Exception ex) {
|
|
675
|
-
callback.invoke("mifareUltralight fail: " + ex);
|
|
676
|
-
}
|
|
677
|
-
} else {
|
|
678
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
679
|
-
}
|
|
312
|
+
MifareUltralightHandler.writePage(
|
|
313
|
+
techRequest,
|
|
314
|
+
(int)pageOffset,
|
|
315
|
+
rnArray,
|
|
316
|
+
callback
|
|
317
|
+
);
|
|
680
318
|
}
|
|
681
319
|
}
|
|
682
320
|
|
|
683
321
|
@ReactMethod
|
|
684
322
|
public void makeReadOnly(Callback callback) {
|
|
685
323
|
synchronized(this) {
|
|
686
|
-
|
|
687
|
-
try {
|
|
688
|
-
Ndef ndef = (Ndef)techRequest.getTechHandle();
|
|
689
|
-
boolean result = ndef.makeReadOnly();
|
|
690
|
-
callback.invoke(null, result);
|
|
691
|
-
} catch (Exception ex) {
|
|
692
|
-
Log.d(LOG_TAG, ex.toString());
|
|
693
|
-
callback.invoke(ex.toString());
|
|
694
|
-
}
|
|
695
|
-
} else {
|
|
696
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
697
|
-
}
|
|
324
|
+
NdefHandler.makeReadOnly(techRequest, callback);
|
|
698
325
|
}
|
|
699
326
|
}
|
|
700
327
|
|
|
701
|
-
@Override
|
|
702
|
-
public void setAlertMessage(String message, Callback callback) {
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
@Override
|
|
707
|
-
public void isSessionAvailable(Callback callback) {
|
|
708
|
-
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
@Override
|
|
712
|
-
public void isTagSessionAvailable(Callback callback) {
|
|
713
|
-
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
@Override
|
|
717
|
-
public void sendMifareCommand(ReadableArray bytes, Callback callback) {
|
|
718
|
-
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
@Override
|
|
722
|
-
public void sendCommandAPDU(ReadableMap payload, Callback callback) {
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
@Override
|
|
727
|
-
public void sendCommandAPDUBytes(ReadableArray bytes, Callback callback) {
|
|
728
|
-
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
@Override
|
|
732
|
-
public void sendFelicaCommand(ReadableArray bytes, Callback callback) {
|
|
733
|
-
|
|
734
|
-
}
|
|
735
|
-
|
|
736
328
|
@ReactMethod
|
|
737
329
|
public void setTimeout(double timeout, Callback callback) {
|
|
738
330
|
synchronized (this) {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
// but it doesn't provide transceive in its interface, so we need to explicitly cast it
|
|
745
|
-
switch (tech) {
|
|
746
|
-
case "NfcA": {
|
|
747
|
-
NfcA techHandle = (NfcA) baseTechHandle;
|
|
748
|
-
techHandle.setTimeout((int)timeout);
|
|
749
|
-
callback.invoke();
|
|
750
|
-
return;
|
|
751
|
-
}
|
|
752
|
-
case "NfcF": {
|
|
753
|
-
NfcF techHandle = (NfcF) baseTechHandle;
|
|
754
|
-
techHandle.setTimeout((int)timeout);
|
|
755
|
-
callback.invoke();
|
|
756
|
-
return;
|
|
757
|
-
}
|
|
758
|
-
case "IsoDep": {
|
|
759
|
-
IsoDep techHandle = (IsoDep) baseTechHandle;
|
|
760
|
-
techHandle.setTimeout((int)timeout);
|
|
761
|
-
callback.invoke();
|
|
762
|
-
return;
|
|
763
|
-
}
|
|
764
|
-
case "MifareClassic": {
|
|
765
|
-
MifareClassic techHandle = (MifareClassic) baseTechHandle;
|
|
766
|
-
techHandle.setTimeout((int)timeout);
|
|
767
|
-
callback.invoke();
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
case "MifareUltralight": {
|
|
771
|
-
MifareUltralight techHandle = (MifareUltralight) baseTechHandle;
|
|
772
|
-
techHandle.setTimeout((int)timeout);
|
|
773
|
-
callback.invoke();
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
Log.d(LOG_TAG, "setTimeout not supported");
|
|
778
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
779
|
-
} catch (Exception ex) {
|
|
780
|
-
Log.d(LOG_TAG, ex.toString());
|
|
781
|
-
callback.invoke(ex.toString());
|
|
782
|
-
}
|
|
783
|
-
} else {
|
|
784
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
785
|
-
}
|
|
331
|
+
NfcTechIoRouter.setTimeout(
|
|
332
|
+
techRequest,
|
|
333
|
+
(int)timeout,
|
|
334
|
+
callback
|
|
335
|
+
);
|
|
786
336
|
}
|
|
787
337
|
}
|
|
788
338
|
|
|
789
339
|
@ReactMethod
|
|
790
340
|
public void getTimeout(Callback callback) {
|
|
791
341
|
synchronized (this) {
|
|
792
|
-
|
|
793
|
-
try {
|
|
794
|
-
String tech = techRequest.getTechType();
|
|
795
|
-
TagTechnology baseTechHandle = techRequest.getTechHandle();
|
|
796
|
-
// TagTechnology is the base class for each tech (ex, NfcA, NfcB, IsoDep ...)
|
|
797
|
-
// but it doesn't provide transceive in its interface, so we need to explicitly cast it
|
|
798
|
-
switch (tech) {
|
|
799
|
-
case "NfcA": {
|
|
800
|
-
NfcA techHandle = (NfcA) baseTechHandle;
|
|
801
|
-
int timeout = techHandle.getTimeout();
|
|
802
|
-
callback.invoke(null, timeout);
|
|
803
|
-
return;
|
|
804
|
-
}
|
|
805
|
-
case "NfcF": {
|
|
806
|
-
NfcF techHandle = (NfcF) baseTechHandle;
|
|
807
|
-
int timeout = techHandle.getTimeout();
|
|
808
|
-
callback.invoke(null, timeout);
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
case "IsoDep": {
|
|
812
|
-
IsoDep techHandle = (IsoDep) baseTechHandle;
|
|
813
|
-
int timeout = techHandle.getTimeout();
|
|
814
|
-
callback.invoke(null, timeout);
|
|
815
|
-
return;
|
|
816
|
-
}
|
|
817
|
-
case "MifareClassic": {
|
|
818
|
-
MifareClassic techHandle = (MifareClassic) baseTechHandle;
|
|
819
|
-
int timeout = techHandle.getTimeout();
|
|
820
|
-
callback.invoke(null, timeout);
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
case "MifareUltralight": {
|
|
824
|
-
MifareUltralight techHandle = (MifareUltralight) baseTechHandle;
|
|
825
|
-
int timeout = techHandle.getTimeout();
|
|
826
|
-
callback.invoke(null, timeout);
|
|
827
|
-
return;
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
Log.d(LOG_TAG, "getTimeout not supported");
|
|
831
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
832
|
-
} catch (Exception ex) {
|
|
833
|
-
Log.d(LOG_TAG, ex.toString());
|
|
834
|
-
callback.invoke(ex.toString());
|
|
835
|
-
}
|
|
836
|
-
} else {
|
|
837
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
838
|
-
}
|
|
342
|
+
NfcTechIoRouter.getTimeout(techRequest, callback);
|
|
839
343
|
}
|
|
840
344
|
}
|
|
841
345
|
|
|
842
346
|
@ReactMethod
|
|
843
347
|
public void connect(ReadableArray techs, Callback callback){
|
|
844
348
|
synchronized(this) {
|
|
349
|
+
if (hasPendingRequest()) {
|
|
350
|
+
callback.invoke(ERR_MULTI_REQ);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
TagTechnologyRequest request = new TagTechnologyRequest(techs.toArrayList(), null);
|
|
845
355
|
try {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
356
|
+
if (!request.connect(this.tag)) {
|
|
357
|
+
request.close();
|
|
358
|
+
callback.invoke(this.tag == null ? ERR_NO_REFERENCE : ERR_API_NOT_SUPPORT);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
techRequest = request;
|
|
849
362
|
} catch (Exception ex) {
|
|
850
363
|
callback.invoke(ex.toString());
|
|
364
|
+
return;
|
|
851
365
|
}
|
|
366
|
+
callback.invoke(null, null);
|
|
852
367
|
}
|
|
853
368
|
}
|
|
854
369
|
|
|
855
370
|
@ReactMethod
|
|
856
371
|
public void close(Callback callback){
|
|
857
372
|
synchronized(this) {
|
|
373
|
+
TagTechnologyRequest request = detachTechnologyRequest();
|
|
374
|
+
if (request == null) {
|
|
375
|
+
callback.invoke(ERR_NO_TECH_REQ);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
request.close();
|
|
858
380
|
try {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
callback.invoke(ex.toString());
|
|
381
|
+
request.invokePendingCallbackWithError(ERR_CANCEL);
|
|
382
|
+
} catch (RuntimeException ex) {
|
|
383
|
+
Log.w(LOG_TAG, "fail to complete closed technology request", ex);
|
|
863
384
|
}
|
|
385
|
+
callback.invoke(null, null);
|
|
864
386
|
}
|
|
865
387
|
}
|
|
866
388
|
|
|
867
389
|
@ReactMethod
|
|
868
390
|
public void transceive(ReadableArray rnArray, Callback callback) {
|
|
869
391
|
synchronized(this) {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
TagTechnology baseTechHandle = techRequest.getTechHandle();
|
|
876
|
-
// TagTechnology is the base class for each tech (ex, NfcA, NfcB, IsoDep ...)
|
|
877
|
-
// but it doesn't provide transceive in its interface, so we need to explicitly cast it
|
|
878
|
-
switch (tech) {
|
|
879
|
-
case "NfcA": {
|
|
880
|
-
NfcA techHandle = (NfcA) baseTechHandle;
|
|
881
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
882
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
883
|
-
callback.invoke(null, resultRnArray);
|
|
884
|
-
return;
|
|
885
|
-
}
|
|
886
|
-
case "NfcB": {
|
|
887
|
-
NfcB techHandle = (NfcB) baseTechHandle;
|
|
888
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
889
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
890
|
-
callback.invoke(null, resultRnArray);
|
|
891
|
-
return;
|
|
892
|
-
}
|
|
893
|
-
case "NfcF": {
|
|
894
|
-
NfcF techHandle = (NfcF) baseTechHandle;
|
|
895
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
896
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
897
|
-
callback.invoke(null, resultRnArray);
|
|
898
|
-
return;
|
|
899
|
-
}
|
|
900
|
-
case "NfcV": {
|
|
901
|
-
NfcV techHandle = (NfcV) baseTechHandle;
|
|
902
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
903
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
904
|
-
callback.invoke(null, resultRnArray);
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
case "IsoDep": {
|
|
908
|
-
IsoDep techHandle = (IsoDep) baseTechHandle;
|
|
909
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
910
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
911
|
-
callback.invoke(null, resultRnArray);
|
|
912
|
-
return;
|
|
913
|
-
}
|
|
914
|
-
case "MifareClassic": {
|
|
915
|
-
MifareClassic techHandle = (MifareClassic) baseTechHandle;
|
|
916
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
917
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
918
|
-
callback.invoke(null, resultRnArray);
|
|
919
|
-
return;
|
|
920
|
-
}
|
|
921
|
-
case "MifareUltralight": {
|
|
922
|
-
MifareUltralight techHandle = (MifareUltralight) baseTechHandle;
|
|
923
|
-
byte[] resultBytes = techHandle.transceive(bytes);
|
|
924
|
-
WritableArray resultRnArray = bytesToRnArray(resultBytes);
|
|
925
|
-
callback.invoke(null, resultRnArray);
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
Log.d(LOG_TAG, "transceive not supported");
|
|
930
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
931
|
-
} catch (Exception ex) {
|
|
932
|
-
Log.d(LOG_TAG, "transceive fail: " + ex);
|
|
933
|
-
callback.invoke(ERR_TRANSCEIVE_FAIL);
|
|
934
|
-
}
|
|
935
|
-
} else {
|
|
936
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
937
|
-
}
|
|
392
|
+
NfcTechIoRouter.transceive(
|
|
393
|
+
techRequest,
|
|
394
|
+
rnArray,
|
|
395
|
+
callback
|
|
396
|
+
);
|
|
938
397
|
}
|
|
939
398
|
}
|
|
940
399
|
|
|
941
400
|
@ReactMethod
|
|
942
401
|
public void getMaxTransceiveLength(Callback callback) {
|
|
943
402
|
synchronized(this) {
|
|
944
|
-
|
|
945
|
-
try {
|
|
946
|
-
String tech = techRequest.getTechType();
|
|
947
|
-
|
|
948
|
-
TagTechnology baseTechHandle = techRequest.getTechHandle();
|
|
949
|
-
// TagTechnology is the base class for each tech (ex, NfcA, NfcB, IsoDep ...)
|
|
950
|
-
// but it doesn't provide transceive in its interface, so we need to explicitly cast it
|
|
951
|
-
switch (tech) {
|
|
952
|
-
case "NfcA": {
|
|
953
|
-
NfcA techHandle = (NfcA) baseTechHandle;
|
|
954
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
955
|
-
callback.invoke(null, max);
|
|
956
|
-
return;
|
|
957
|
-
}
|
|
958
|
-
case "NfcB": {
|
|
959
|
-
NfcB techHandle = (NfcB) baseTechHandle;
|
|
960
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
961
|
-
callback.invoke(null, max);
|
|
962
|
-
return;
|
|
963
|
-
}
|
|
964
|
-
case "NfcF": {
|
|
965
|
-
NfcF techHandle = (NfcF) baseTechHandle;
|
|
966
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
967
|
-
callback.invoke(null, max);
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
case "NfcV": {
|
|
971
|
-
NfcV techHandle = (NfcV) baseTechHandle;
|
|
972
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
973
|
-
callback.invoke(null, max);
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
976
|
-
case "IsoDep": {
|
|
977
|
-
IsoDep techHandle = (IsoDep) baseTechHandle;
|
|
978
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
979
|
-
callback.invoke(null, max);
|
|
980
|
-
return;
|
|
981
|
-
}
|
|
982
|
-
case "MifareUltralight": {
|
|
983
|
-
MifareUltralight techHandle = (MifareUltralight) baseTechHandle;
|
|
984
|
-
int max = techHandle.getMaxTransceiveLength();
|
|
985
|
-
callback.invoke(null, max);
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
Log.d(LOG_TAG, "getMaxTransceiveLength not supported");
|
|
990
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
991
|
-
} catch (Exception ex) {
|
|
992
|
-
Log.d(LOG_TAG, "getMaxTransceiveLength fail");
|
|
993
|
-
callback.invoke(ex.toString());
|
|
994
|
-
}
|
|
995
|
-
} else {
|
|
996
|
-
callback.invoke(ERR_NO_TECH_REQ);
|
|
997
|
-
}
|
|
403
|
+
NfcTechIoRouter.getMaxTransceiveLength(techRequest, callback);
|
|
998
404
|
}
|
|
999
405
|
}
|
|
1000
406
|
|
|
1001
407
|
@ReactMethod
|
|
1002
408
|
public void cancelNdefWrite(Callback callback) {
|
|
1003
409
|
synchronized(this) {
|
|
1004
|
-
|
|
1005
|
-
writeNdefRequest.callback.invoke(ERR_CANCEL);
|
|
1006
|
-
writeNdefRequest = null;
|
|
1007
|
-
callback.invoke();
|
|
1008
|
-
} else {
|
|
1009
|
-
callback.invoke(ERR_NOT_REGISTERED);
|
|
1010
|
-
}
|
|
410
|
+
writeNdefRequest = NdefHandler.cancelNdefWrite(writeNdefRequest, callback);
|
|
1011
411
|
}
|
|
1012
412
|
}
|
|
1013
413
|
|
|
1014
414
|
@ReactMethod
|
|
1015
415
|
public void requestNdefWrite(ReadableArray rnArray, ReadableMap options, Callback callback) {
|
|
1016
416
|
synchronized(this) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
boolean format = options.getBoolean("format");
|
|
1026
|
-
boolean formatReadOnly = options.getBoolean("formatReadOnly");
|
|
1027
|
-
|
|
1028
|
-
try {
|
|
1029
|
-
NdefMessage msgToWrite;
|
|
1030
|
-
|
|
1031
|
-
/// the only case we allow ndef message to be null is when formatting, see:
|
|
1032
|
-
/// https://developer.android.com/reference/android/nfc/tech/NdefFormatable.html#format(android.nfc.NdefMessage)
|
|
1033
|
-
/// this API allows the `firstMessage` to be null
|
|
1034
|
-
if (format && rnArray == null) {
|
|
1035
|
-
msgToWrite = null;
|
|
1036
|
-
} else {
|
|
1037
|
-
byte[] bytes = rnArrayToBytes(rnArray);
|
|
1038
|
-
msgToWrite = new NdefMessage(bytes);
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
writeNdefRequest = new WriteNdefRequest(
|
|
1042
|
-
msgToWrite,
|
|
1043
|
-
callback, // defer the callback
|
|
1044
|
-
format,
|
|
1045
|
-
formatReadOnly
|
|
1046
|
-
);
|
|
1047
|
-
} catch (FormatException e) {
|
|
1048
|
-
callback.invoke(e.toString());
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
417
|
+
writeNdefRequest = NdefHandler.requestNdefWrite(
|
|
418
|
+
rnArray,
|
|
419
|
+
options,
|
|
420
|
+
isForegroundEnabled,
|
|
421
|
+
hasPendingRequest(),
|
|
422
|
+
writeNdefRequest,
|
|
423
|
+
callback
|
|
424
|
+
);
|
|
1051
425
|
}
|
|
1052
426
|
}
|
|
1053
427
|
|
|
1054
428
|
@ReactMethod
|
|
1055
429
|
public void start(Callback callback) {
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
430
|
+
synchronized(this) {
|
|
431
|
+
var context = getReactApplicationContext();
|
|
432
|
+
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
|
|
433
|
+
if (nfcAdapter == null) {
|
|
434
|
+
Log.d(LOG_TAG, "not support in this device");
|
|
435
|
+
callback.invoke(ERR_NO_NFC_SUPPORT);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
1060
438
|
|
|
1061
|
-
|
|
439
|
+
Log.d(LOG_TAG, "start");
|
|
1062
440
|
Activity currentActivity = context.getCurrentActivity();
|
|
1063
441
|
if (currentActivity == null) {
|
|
1064
442
|
callback.invoke(ERR_GET_ACTIVITY_FAIL);
|
|
1065
443
|
return;
|
|
1066
444
|
}
|
|
1067
445
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
446
|
+
try {
|
|
447
|
+
if (receiverActivity == null) {
|
|
448
|
+
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED);
|
|
449
|
+
currentActivity.registerReceiver(mReceiver, filter);
|
|
450
|
+
receiverActivity = currentActivity;
|
|
451
|
+
}
|
|
452
|
+
Intent launchIntent = currentActivity.getIntent();
|
|
453
|
+
// we consider the launching intent to be background
|
|
454
|
+
bgTag = parseNfcIntent(launchIntent);
|
|
455
|
+
} catch (Exception ex) {
|
|
456
|
+
callback.invoke(ex.toString());
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
1072
459
|
callback.invoke();
|
|
1073
|
-
} else {
|
|
1074
|
-
Log.d(LOG_TAG, "not support in this device");
|
|
1075
|
-
callback.invoke(ERR_NO_NFC_SUPPORT);
|
|
1076
460
|
}
|
|
1077
461
|
}
|
|
1078
462
|
|
|
@@ -1094,7 +478,7 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1094
478
|
// compatible with MifareClassic
|
|
1095
479
|
// TODO: Check if it's the same case with MifareUltralight
|
|
1096
480
|
if (tech.equals("MifareClassic")) {
|
|
1097
|
-
if (!
|
|
481
|
+
if (!Util.isDeviceSupported(currentActivity)) {
|
|
1098
482
|
callback.invoke(null, false);
|
|
1099
483
|
return;
|
|
1100
484
|
}
|
|
@@ -1155,66 +539,47 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1155
539
|
callback.invoke();
|
|
1156
540
|
}
|
|
1157
541
|
|
|
1158
|
-
@Override
|
|
1159
|
-
public void restartTechnologyRequest(Callback callback) {
|
|
1160
|
-
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
@Override
|
|
1164
|
-
public void invalidateSession(Callback callback) {
|
|
1165
|
-
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
@Override
|
|
1169
|
-
public void invalidateSessionWithError(String message, Callback callback) {
|
|
1170
|
-
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
542
|
@ReactMethod
|
|
1174
543
|
public void registerTagEvent(ReadableMap options, Callback callback) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
ndef.addDataType("*/*");
|
|
1186
|
-
} catch (MalformedMimeTypeException e) {
|
|
1187
|
-
throw new RuntimeException("fail", e);
|
|
1188
|
-
}
|
|
1189
|
-
intentFilters.add(ndef);
|
|
544
|
+
synchronized(this) {
|
|
545
|
+
Log.d(LOG_TAG, "registerTagEvent");
|
|
546
|
+
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
|
547
|
+
try {
|
|
548
|
+
// capture all mime-based dispatch NDEF
|
|
549
|
+
ndef.addDataType("*/*");
|
|
550
|
+
} catch (MalformedMimeTypeException ex) {
|
|
551
|
+
callback.invoke(ex.toString());
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
1190
554
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
555
|
+
intentFilters.clear();
|
|
556
|
+
techLists.clear();
|
|
557
|
+
intentFilters.add(ndef);
|
|
558
|
+
// capture all rest NDEF, such as uri-based
|
|
559
|
+
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED));
|
|
560
|
+
techLists.add(new String[]{Ndef.class.getName()});
|
|
561
|
+
// for those without NDEF, get them as tags
|
|
562
|
+
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED));
|
|
1194
563
|
|
|
1195
|
-
|
|
1196
|
-
|
|
564
|
+
isReaderModeEnabled = options.getBoolean("isReaderModeEnabled");
|
|
565
|
+
readerModeFlags = options.getInt("readerModeFlags");
|
|
566
|
+
readerModeDelay = options.getInt("readerModeDelay");
|
|
567
|
+
isForegroundEnabled = true;
|
|
1197
568
|
|
|
1198
|
-
|
|
1199
|
-
|
|
569
|
+
if (isResumed) {
|
|
570
|
+
enableDisableForegroundDispatch(true);
|
|
571
|
+
}
|
|
572
|
+
callback.invoke();
|
|
1200
573
|
}
|
|
1201
|
-
callback.invoke();
|
|
1202
574
|
}
|
|
1203
575
|
|
|
1204
576
|
@ReactMethod
|
|
1205
577
|
public void unregisterTagEvent(Callback callback) {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
578
|
+
synchronized(this) {
|
|
579
|
+
Log.d(LOG_TAG, "unregisterTagEvent");
|
|
580
|
+
resetTagRegistration();
|
|
581
|
+
callback.invoke();
|
|
1209
582
|
}
|
|
1210
|
-
|
|
1211
|
-
intentFilters.clear();
|
|
1212
|
-
isForegroundEnabled = false;
|
|
1213
|
-
isReaderModeEnabled = false;
|
|
1214
|
-
readerModeFlags = 0;
|
|
1215
|
-
readerModeDelay = 0;
|
|
1216
|
-
|
|
1217
|
-
callback.invoke();
|
|
1218
583
|
}
|
|
1219
584
|
|
|
1220
585
|
@ReactMethod
|
|
@@ -1234,124 +599,121 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1234
599
|
}
|
|
1235
600
|
|
|
1236
601
|
@Override
|
|
1237
|
-
public void
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
@Override
|
|
1247
|
-
public void iso15693_readMultipleBlocks(ReadableMap options, Callback callback) {
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
@Override
|
|
1252
|
-
public void iso15693_writeSingleBlock(ReadableMap options, Callback callback) {
|
|
1253
|
-
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
@Override
|
|
1257
|
-
public void iso15693_lockBlock(ReadableMap options, Callback callback) {
|
|
1258
|
-
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
@Override
|
|
1262
|
-
public void iso15693_writeAFI(ReadableMap options, Callback callback) {
|
|
1263
|
-
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
@Override
|
|
1267
|
-
public void iso15693_lockAFI(ReadableMap options, Callback callback) {
|
|
1268
|
-
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
@Override
|
|
1272
|
-
public void iso15693_writeDSFID(ReadableMap options, Callback callback) {
|
|
1273
|
-
|
|
602
|
+
public void onHostResume() {
|
|
603
|
+
Log.d(LOG_TAG, "onResume");
|
|
604
|
+
isResumed = true;
|
|
605
|
+
if (isForegroundEnabled) {
|
|
606
|
+
enableDisableForegroundDispatch(true);
|
|
607
|
+
}
|
|
1274
608
|
}
|
|
1275
609
|
|
|
1276
610
|
@Override
|
|
1277
|
-
public void
|
|
1278
|
-
|
|
611
|
+
public void onHostPause() {
|
|
612
|
+
Log.d(LOG_TAG, "onPause");
|
|
613
|
+
isResumed = false;
|
|
614
|
+
enableDisableForegroundDispatch(false);
|
|
1279
615
|
}
|
|
1280
616
|
|
|
1281
617
|
@Override
|
|
1282
|
-
public void
|
|
1283
|
-
|
|
618
|
+
public void onHostDestroy() {
|
|
619
|
+
Log.d(LOG_TAG, "onDestroy");
|
|
620
|
+
cleanUpNativeState();
|
|
1284
621
|
}
|
|
1285
622
|
|
|
1286
623
|
@Override
|
|
1287
|
-
public void
|
|
1288
|
-
|
|
624
|
+
public void invalidate() {
|
|
625
|
+
cleanUpNativeState();
|
|
626
|
+
ReactApplicationContext context = getReactApplicationContext();
|
|
627
|
+
context.removeActivityEventListener(this);
|
|
628
|
+
context.removeLifecycleEventListener(this);
|
|
629
|
+
super.invalidate();
|
|
1289
630
|
}
|
|
1290
631
|
|
|
1291
632
|
@Override
|
|
1292
|
-
public void
|
|
1293
|
-
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
|
-
@Override
|
|
1297
|
-
public void iso15693_customCommand(ReadableMap options, Callback callback) {
|
|
1298
|
-
|
|
633
|
+
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
|
634
|
+
Log.d(LOG_TAG, "onActivityResult");
|
|
1299
635
|
}
|
|
1300
636
|
|
|
1301
637
|
@Override
|
|
1302
|
-
public void
|
|
1303
|
-
|
|
638
|
+
public void onNewIntent(Intent intent) {
|
|
639
|
+
Log.d(LOG_TAG, "onNewIntent " + intent);
|
|
640
|
+
WritableMap nfcTag = parseNfcIntent(intent);
|
|
641
|
+
if (nfcTag != null) {
|
|
642
|
+
if (isForegroundEnabled) {
|
|
643
|
+
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
644
|
+
} else {
|
|
645
|
+
sendEvent("NfcManagerDiscoverBackgroundTag", nfcTag);
|
|
646
|
+
bgTag = nfcTag;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
1304
649
|
}
|
|
1305
650
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
651
|
+
private boolean hasPendingRequest() {
|
|
652
|
+
return writeNdefRequest != null || techRequest != null;
|
|
1309
653
|
}
|
|
1310
654
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
655
|
+
private TagTechnologyRequest detachTechnologyRequest() {
|
|
656
|
+
TagTechnologyRequest request = techRequest;
|
|
657
|
+
techRequest = null;
|
|
658
|
+
return request;
|
|
1314
659
|
}
|
|
1315
660
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
661
|
+
private void resetTagRegistration() {
|
|
662
|
+
if (isResumed) {
|
|
663
|
+
enableDisableForegroundDispatch(false);
|
|
664
|
+
}
|
|
665
|
+
intentFilters.clear();
|
|
666
|
+
techLists.clear();
|
|
667
|
+
isForegroundEnabled = false;
|
|
668
|
+
isReaderModeEnabled = false;
|
|
669
|
+
readerModeFlags = 0;
|
|
670
|
+
readerModeDelay = 0;
|
|
1319
671
|
}
|
|
1320
672
|
|
|
1321
|
-
|
|
1322
|
-
|
|
673
|
+
private void cleanUpNativeState() {
|
|
674
|
+
synchronized(this) {
|
|
675
|
+
resetTagRegistration();
|
|
676
|
+
isResumed = false;
|
|
1323
677
|
|
|
1324
|
-
|
|
678
|
+
TagTechnologyRequest request = detachTechnologyRequest();
|
|
679
|
+
if (request != null) {
|
|
680
|
+
request.close();
|
|
681
|
+
try {
|
|
682
|
+
request.invokePendingCallbackWithError(ERR_CANCEL);
|
|
683
|
+
} catch (RuntimeException ex) {
|
|
684
|
+
Log.w(LOG_TAG, "fail to complete destroyed technology request", ex);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
1325
687
|
|
|
688
|
+
NdefHandler.WriteNdefRequest ndefRequest = writeNdefRequest;
|
|
689
|
+
writeNdefRequest = null;
|
|
690
|
+
if (ndefRequest != null) {
|
|
691
|
+
try {
|
|
692
|
+
ndefRequest.invokeCallbackWithError(ERR_CANCEL);
|
|
693
|
+
} catch (RuntimeException ex) {
|
|
694
|
+
Log.w(LOG_TAG, "fail to complete destroyed NDEF request", ex);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
1326
697
|
|
|
698
|
+
if (receiverActivity != null) {
|
|
699
|
+
try {
|
|
700
|
+
receiverActivity.unregisterReceiver(mReceiver);
|
|
701
|
+
} catch (IllegalArgumentException ex) {
|
|
702
|
+
Log.w(LOG_TAG, "adapter-state receiver was already unregistered", ex);
|
|
703
|
+
}
|
|
704
|
+
receiverActivity = null;
|
|
705
|
+
}
|
|
1327
706
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
Log.d(LOG_TAG, "onResume");
|
|
1331
|
-
isResumed = true;
|
|
1332
|
-
if (isForegroundEnabled) {
|
|
1333
|
-
enableDisableForegroundDispatch(true);
|
|
707
|
+
tag = null;
|
|
708
|
+
bgTag = null;
|
|
1334
709
|
}
|
|
1335
710
|
}
|
|
1336
711
|
|
|
1337
|
-
@Override
|
|
1338
|
-
public void onHostPause() {
|
|
1339
|
-
Log.d(LOG_TAG, "onPause");
|
|
1340
|
-
isResumed = false;
|
|
1341
|
-
enableDisableForegroundDispatch(false);
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
@Override
|
|
1345
|
-
public void onHostDestroy() {
|
|
1346
|
-
Log.d(LOG_TAG, "onDestroy");
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
712
|
private void enableDisableForegroundDispatch(boolean enable) {
|
|
1350
713
|
Log.i(LOG_TAG, "enableForegroundDispatch, enable = " + enable);
|
|
1351
714
|
var context = getReactApplicationContext();
|
|
1352
715
|
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
|
|
1353
716
|
Activity currentActivity = context.getCurrentActivity();
|
|
1354
|
-
final NfcManager manager = this;
|
|
1355
717
|
if (nfcAdapter != null && currentActivity != null && !currentActivity.isFinishing()) {
|
|
1356
718
|
try {
|
|
1357
719
|
if (isReaderModeEnabled) {
|
|
@@ -1359,36 +721,7 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1359
721
|
Log.i(LOG_TAG, String.format("enableReaderMode, flags: %d, delay: %d ms", readerModeFlags, readerModeDelay));
|
|
1360
722
|
Bundle readerModeExtras = new Bundle();
|
|
1361
723
|
readerModeExtras.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, readerModeDelay);
|
|
1362
|
-
nfcAdapter.enableReaderMode(currentActivity,
|
|
1363
|
-
@Override
|
|
1364
|
-
public void onTagDiscovered(Tag tag) {
|
|
1365
|
-
synchronized (this) {
|
|
1366
|
-
manager.tag = tag;
|
|
1367
|
-
Log.d(LOG_TAG, "readerMode onTagDiscovered");
|
|
1368
|
-
WritableMap nfcTag;
|
|
1369
|
-
// if the tag contains NDEF, we want to report the content
|
|
1370
|
-
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
1371
|
-
Ndef ndef = Ndef.get(tag);
|
|
1372
|
-
nfcTag = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
|
|
1373
|
-
} else {
|
|
1374
|
-
nfcTag = tag2React(tag);
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
if (nfcTag != null) {
|
|
1378
|
-
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
1379
|
-
if (techRequest!= null && !techRequest.isConnected()) {
|
|
1380
|
-
boolean result = techRequest.connect(tag);
|
|
1381
|
-
if (result) {
|
|
1382
|
-
techRequest.invokePendingCallback(techRequest.getTechType());
|
|
1383
|
-
} else {
|
|
1384
|
-
// this indicates that we get a NFC tag, but none of the user required tech is matched
|
|
1385
|
-
techRequest.invokePendingCallback(null);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
}, readerModeFlags, readerModeExtras);
|
|
724
|
+
nfcAdapter.enableReaderMode(currentActivity, this::handleReaderModeTagDiscovered, readerModeFlags, readerModeExtras);
|
|
1392
725
|
} else {
|
|
1393
726
|
Log.i(LOG_TAG, "disableReaderMode");
|
|
1394
727
|
nfcAdapter.disableReaderMode(currentActivity);
|
|
@@ -1406,6 +739,31 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1406
739
|
}
|
|
1407
740
|
}
|
|
1408
741
|
|
|
742
|
+
private void handleReaderModeTagDiscovered(Tag tag) {
|
|
743
|
+
synchronized (this) {
|
|
744
|
+
this.tag = tag;
|
|
745
|
+
Log.d(LOG_TAG, "readerMode onTagDiscovered");
|
|
746
|
+
WritableMap nfcTag;
|
|
747
|
+
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
748
|
+
nfcTag = NdefHandler.ndefToReact(tag);
|
|
749
|
+
} else {
|
|
750
|
+
nfcTag = Util.tagToReact(tag);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (nfcTag != null) {
|
|
754
|
+
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
755
|
+
if (techRequest != null && !techRequest.isConnected()) {
|
|
756
|
+
boolean result = techRequest.connect(tag);
|
|
757
|
+
if (result) {
|
|
758
|
+
techRequest.invokePendingCallback(techRequest.getTechType());
|
|
759
|
+
} else {
|
|
760
|
+
techRequest.invokePendingCallback(null);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
1409
767
|
private PendingIntent getPendingIntent() {
|
|
1410
768
|
Activity activity = getReactApplicationContext().getCurrentActivity();
|
|
1411
769
|
assert activity != null;
|
|
@@ -1429,63 +787,35 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1429
787
|
|
|
1430
788
|
private void sendEvent(String eventName,
|
|
1431
789
|
@Nullable WritableMap params) {
|
|
790
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
791
|
+
WritableMap eventPayload = params != null ? params : Arguments.createMap();
|
|
792
|
+
switch (eventName) {
|
|
793
|
+
case "NfcManagerDiscoverTag":
|
|
794
|
+
emitOnDiscoverTag(eventPayload);
|
|
795
|
+
return;
|
|
796
|
+
case "NfcManagerDiscoverBackgroundTag":
|
|
797
|
+
emitOnDiscoverBackgroundTag(eventPayload);
|
|
798
|
+
return;
|
|
799
|
+
case "NfcManagerStateChanged":
|
|
800
|
+
emitOnStateChanged(eventPayload);
|
|
801
|
+
return;
|
|
802
|
+
default:
|
|
803
|
+
Log.w(LOG_TAG, "unknown NFC event: " + eventName);
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
1432
807
|
getReactApplicationContext()
|
|
1433
808
|
.getJSModule(RCTNativeAppEventEmitter.class)
|
|
1434
809
|
.emit(eventName, params);
|
|
1435
810
|
}
|
|
1436
811
|
|
|
1437
|
-
private
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
|
|
1445
|
-
NfcAdapter.STATE_OFF);
|
|
1446
|
-
String stateStr = "unknown";
|
|
1447
|
-
switch (state) {
|
|
1448
|
-
case NfcAdapter.STATE_OFF:
|
|
1449
|
-
stateStr = "off";
|
|
1450
|
-
break;
|
|
1451
|
-
case NfcAdapter.STATE_TURNING_OFF:
|
|
1452
|
-
stateStr = "turning_off";
|
|
1453
|
-
break;
|
|
1454
|
-
case NfcAdapter.STATE_ON:
|
|
1455
|
-
stateStr = "on";
|
|
1456
|
-
break;
|
|
1457
|
-
case NfcAdapter.STATE_TURNING_ON:
|
|
1458
|
-
stateStr = "turning_on";
|
|
1459
|
-
break;
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
try {
|
|
1463
|
-
WritableMap writableMap = Arguments.createMap();
|
|
1464
|
-
writableMap.putString("state", stateStr);
|
|
1465
|
-
sendEvent("NfcManagerStateChanged", writableMap);
|
|
1466
|
-
} catch (Exception ex) {
|
|
1467
|
-
Log.d(LOG_TAG, "send nfc state change event fail: " + ex);
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
};
|
|
1472
|
-
|
|
1473
|
-
@Override
|
|
1474
|
-
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
|
1475
|
-
Log.d(LOG_TAG, "onActivityResult");
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
@Override
|
|
1479
|
-
public void onNewIntent(Intent intent) {
|
|
1480
|
-
Log.d(LOG_TAG, "onNewIntent " + intent);
|
|
1481
|
-
WritableMap nfcTag = parseNfcIntent(intent);
|
|
1482
|
-
if (nfcTag != null) {
|
|
1483
|
-
if (isForegroundEnabled) {
|
|
1484
|
-
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
1485
|
-
} else {
|
|
1486
|
-
sendEvent("NfcManagerDiscoverBackgroundTag", nfcTag);
|
|
1487
|
-
bgTag = nfcTag;
|
|
1488
|
-
}
|
|
812
|
+
private void emitAdapterStateChanged(String stateStr) {
|
|
813
|
+
try {
|
|
814
|
+
WritableMap writableMap = Arguments.createMap();
|
|
815
|
+
writableMap.putString("state", stateStr);
|
|
816
|
+
sendEvent("NfcManagerStateChanged", writableMap);
|
|
817
|
+
} catch (Exception ex) {
|
|
818
|
+
Log.d(LOG_TAG, "send nfc state change event fail: " + ex);
|
|
1489
819
|
}
|
|
1490
820
|
}
|
|
1491
821
|
|
|
@@ -1507,11 +837,9 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1507
837
|
synchronized(this) {
|
|
1508
838
|
this.tag = tag;
|
|
1509
839
|
if (writeNdefRequest != null) {
|
|
1510
|
-
|
|
1511
|
-
tag,
|
|
1512
|
-
writeNdefRequest
|
|
1513
|
-
);
|
|
840
|
+
NdefHandler.WriteNdefRequest request = writeNdefRequest;
|
|
1514
841
|
writeNdefRequest = null;
|
|
842
|
+
NdefHandler.writeNdef(tag, request);
|
|
1515
843
|
|
|
1516
844
|
// explicitly return null, to avoid extra detection
|
|
1517
845
|
return null;
|
|
@@ -1531,139 +859,25 @@ class NfcManager extends NativeNfcManagerSpec implements ActivityEventListener,
|
|
|
1531
859
|
}
|
|
1532
860
|
}
|
|
1533
861
|
|
|
1534
|
-
Ndef ndef;
|
|
1535
862
|
switch (action) {
|
|
1536
863
|
case NfcAdapter.ACTION_NDEF_DISCOVERED:
|
|
1537
|
-
ndef = Ndef.get(tag);
|
|
1538
864
|
Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
|
|
1539
|
-
parsed =
|
|
865
|
+
parsed = NdefHandler.ndefToReact(tag, messages);
|
|
1540
866
|
break;
|
|
1541
867
|
case NfcAdapter.ACTION_TECH_DISCOVERED:
|
|
1542
868
|
// if the tag contains NDEF, we want to report the content
|
|
1543
869
|
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
1544
|
-
|
|
1545
|
-
parsed = ndef2React(ndef, new NdefMessage[]{ndef.getCachedNdefMessage()});
|
|
870
|
+
parsed = NdefHandler.ndefToReact(tag);
|
|
1546
871
|
} else {
|
|
1547
|
-
parsed =
|
|
872
|
+
parsed = Util.tagToReact(tag);
|
|
1548
873
|
}
|
|
1549
874
|
break;
|
|
1550
875
|
case NfcAdapter.ACTION_TAG_DISCOVERED:
|
|
1551
|
-
parsed =
|
|
876
|
+
parsed = Util.tagToReact(tag);
|
|
1552
877
|
break;
|
|
1553
878
|
}
|
|
1554
879
|
|
|
1555
880
|
return parsed;
|
|
1556
881
|
}
|
|
1557
882
|
|
|
1558
|
-
private WritableMap tag2React(Tag tag) {
|
|
1559
|
-
try {
|
|
1560
|
-
JSONObject json = Util.tagToJSON(tag);
|
|
1561
|
-
return JsonConvert.jsonToReact(json);
|
|
1562
|
-
} catch (JSONException ex) {
|
|
1563
|
-
return null;
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
|
-
private WritableMap ndef2React(Ndef ndef, Parcelable[] messages) {
|
|
1568
|
-
try {
|
|
1569
|
-
JSONObject json = buildNdefJSON(ndef, messages);
|
|
1570
|
-
return JsonConvert.jsonToReact(json);
|
|
1571
|
-
} catch (JSONException ex) {
|
|
1572
|
-
return null;
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
|
|
1577
|
-
JSONObject json = Util.ndefToJSON(ndef);
|
|
1578
|
-
|
|
1579
|
-
// ndef is null for peer-to-peer
|
|
1580
|
-
// ndef and messages are null for ndef format-able
|
|
1581
|
-
if (ndef == null && messages != null) {
|
|
1582
|
-
try {
|
|
1583
|
-
|
|
1584
|
-
if (messages.length > 0) {
|
|
1585
|
-
NdefMessage message = (NdefMessage) messages[0];
|
|
1586
|
-
json.put("ndefMessage", Util.messageToJSON(message));
|
|
1587
|
-
// guessing type, would prefer a more definitive way to determine type
|
|
1588
|
-
json.put("type", "NDEF");
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
if (messages.length > 1) {
|
|
1592
|
-
Log.d(LOG_TAG, "Expected one ndefMessage but found " + messages.length);
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
} catch (JSONException e) {
|
|
1596
|
-
// shouldn't happen
|
|
1597
|
-
Log.e(Util.TAG, "Failed to convert ndefMessage into json", e);
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
|
-
return json;
|
|
1601
|
-
}
|
|
1602
|
-
|
|
1603
|
-
private void writeNdef(Tag tag, WriteNdefRequest request) {
|
|
1604
|
-
NdefMessage message = request.message;
|
|
1605
|
-
Callback callback = request.callback;
|
|
1606
|
-
boolean formatReadOnly = request.formatReadOnly;
|
|
1607
|
-
boolean format = request.format;
|
|
1608
|
-
|
|
1609
|
-
if (format || formatReadOnly) {
|
|
1610
|
-
try {
|
|
1611
|
-
Log.d(LOG_TAG, "ready to writeNdef");
|
|
1612
|
-
NdefFormatable formatable = NdefFormatable.get(tag);
|
|
1613
|
-
if (formatable == null) {
|
|
1614
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
1615
|
-
} else {
|
|
1616
|
-
Log.d(LOG_TAG, "ready to format ndef, seriously");
|
|
1617
|
-
formatable.connect();
|
|
1618
|
-
if (formatReadOnly) {
|
|
1619
|
-
formatable.formatReadOnly(message);
|
|
1620
|
-
} else {
|
|
1621
|
-
formatable.format(message);
|
|
1622
|
-
}
|
|
1623
|
-
callback.invoke();
|
|
1624
|
-
}
|
|
1625
|
-
} catch (Exception ex) {
|
|
1626
|
-
callback.invoke(ex.toString());
|
|
1627
|
-
}
|
|
1628
|
-
} else {
|
|
1629
|
-
try {
|
|
1630
|
-
Log.d(LOG_TAG, "ready to writeNdef");
|
|
1631
|
-
Ndef ndef = Ndef.get(tag);
|
|
1632
|
-
if (ndef == null) {
|
|
1633
|
-
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
1634
|
-
} else if (!ndef.isWritable()) {
|
|
1635
|
-
callback.invoke("tag is not writeable");
|
|
1636
|
-
} else if (ndef.getMaxSize() < message.toByteArray().length) {
|
|
1637
|
-
callback.invoke("tag size is not enough");
|
|
1638
|
-
} else {
|
|
1639
|
-
Log.d(LOG_TAG, "ready to writeNdef, seriously");
|
|
1640
|
-
ndef.connect();
|
|
1641
|
-
ndef.writeNdefMessage(message);
|
|
1642
|
-
callback.invoke();
|
|
1643
|
-
}
|
|
1644
|
-
} catch (Exception ex) {
|
|
1645
|
-
callback.invoke(ex.toString());
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
private static byte[] rnArrayToBytes(ReadableArray rArray) {
|
|
1651
|
-
byte[] bytes = new byte[rArray.size()];
|
|
1652
|
-
for (int i = 0; i < rArray.size(); i++) {
|
|
1653
|
-
bytes[i] = (byte)(rArray.getInt(i) & 0xff);
|
|
1654
|
-
}
|
|
1655
|
-
return bytes;
|
|
1656
|
-
}
|
|
1657
|
-
|
|
1658
|
-
private static WritableArray bytesToRnArray(byte[] bytes) {
|
|
1659
|
-
return appendBytesToRnArray(Arguments.createArray(), bytes);
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
private static WritableArray appendBytesToRnArray(WritableArray value, byte[] bytes) {
|
|
1663
|
-
for (byte aByte : bytes) {
|
|
1664
|
-
value.pushInt((aByte & 0xFF));
|
|
1665
|
-
}
|
|
1666
|
-
return value;
|
|
1667
|
-
}
|
|
1668
883
|
}
|
|
1669
|
-
|