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