React Native: Android apps crash, onNewIntent
The next piece of code is the NFC module for react-native. I read NFC tag IDs with this. The problem is, if you put the app in the background, if you click on the app icon again, the app crashes, but if you open it from the task list, it works fine.
NFC Reader:
//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 during failure:
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.
+3
source to share
1 answer
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);
}
}
+1
source to share