Following code-snippet is NFC module for react-native. I read NFC Tag IDs with that. Problem is if you put the app in the background, if you click on app icon again, app will crash, but if you open it from tasks list it works fine.
NFC Read Module:
//package com.toastexample;
package net.opencampus.android.client;
import android.widget.Toast;
import android.util.Log;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.LifecycleEventListener;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import java.nio.ByteBuffer;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import android.support.annotation.Nullable;
import java.util.Map;
import java.util.HashMap;
public class NfcReadModule extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
public static final String TAG = "NFCActivity";
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
private ReactApplicationContext reactContext;
private static final char[] HAX_ARRAY = "0123456789ABCDEF".toCharArray();
String serialNumber;
String intentText = "Empty";
Promise tagPromise;
public NfcReadModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.reactContext.addActivityEventListener(this);
}
@Override
public String getName() {
return "NfcReadModule";
}
@Override
public void onNewIntent(Intent intent) {
intentText = "onNewIntent";
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
serialNumber = bytesToHex(tag.getId());
WritableMap params = Arguments.createMap();
params.putString("serial", serialNumber);
sendEvent(this.reactContext, "tagDetected", params);
}
@ReactMethod
public void getCardId(Promise promise) {
this.tagPromise = promise;
}
@Override
public void onHostResume() {
}
@Override
public void onHostPause() {
}
@Override
public void onHostDestroy() {
}
@Override
public void onActivityResult(
final Activity activity,
final int requestCode,
final int resultCode,
final Intent intent) {
}
@ReactMethod
public void show() {
}
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[bytes.length - j - 1] & 0xFF;
hexChars[j * 2] = HAX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HAX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
}
Logs from logcat while crashing :
05-09 10:34:03.457 22282 22282 E AndroidRuntime: FATAL EXCEPTION: main
05-09 10:34:03.457 22282 22282 E AndroidRuntime: Process: net.xxxx.android.client, PID: 22282
05-09 10:34:03.457 22282 22282 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'byte[] android.nfc.Tag.getId()' on a null object reference
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at net.xxxx.android.client.NfcReadModule.onNewIntent(NfcReadModule.java:61)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.facebook.react.bridge.ReactContext.onNewIntent(ReactContext.java:208)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.facebook.react.ReactInstanceManager.onNewIntent(ReactInstanceManager.java:503)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.facebook.react.ReactActivityDelegate.onNewIntent(ReactActivityDelegate.java:189)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.facebook.react.ReactActivity.onNewIntent(ReactActivity.java:99)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1223)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1235)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:2802)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread.performNewIntents(ActivityThread.java:2817)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread.handleNewIntent(ActivityThread.java:2833)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread.-wrap15(ActivityThread.java)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1556)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6119)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
05-09 10:34:03.457 22282 22282 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
05-09 10:34:03.467 607 2381 W ActivityManager: Force finishing activity net.xxxx.android.client/.MainActivity
What am I doing wrong? Thanks in advance.
Fixed by adding a check if the tag is not null :
@Override
public void onNewIntent(Intent intent) {
intentText = "onNewIntent";
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if (tag != null) {
serialNumber = bytesToHex(tag.getId());
WritableMap params = Arguments.createMap();
params.putString("serial", serialNumber);
sendEvent(this.reactContext, "tagDetected", params);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With