gpt4 book ai didi

java - 尝试在 NfcManager.start() 上获取空数组的长度

转载 作者:行者123 更新时间:2023-11-30 10:23:33 26 4
gpt4 key购买 nike

我正在使用 react native v0.49 并安装了 react-native-nfc-manager 。当我尝试使用 nfc 时出现错误

Attempt to get length of null array

所以我检查了 nfc 文件夹,发现插件安装存在问题

@ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}

如你所见,当 nfcAdapter 不为 null 时

callback.invoke(null)

所以问题来了,所以我试着改成

callback.invoke(LOG_TAG)

它没有显示错误但我没有得到任何 nfc 标签,显示未定义但没有错误。我能做些什么?这是所有的 NfcManager.java 文件

package community.revteltech.nfc;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Base64;
import android.util.Log;
import android.provider.Settings;
import com.facebook.react.bridge.*;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;

import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Parcelable;

import org.json.JSONObject;
import org.json.JSONException;

import java.util.*;

import static android.app.Activity.RESULT_OK;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;

class NfcManager extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
private static final String LOG_TAG = "NfcManager";
private final List<IntentFilter> intentFilters = new ArrayList<IntentFilter>();
private final ArrayList<String[]> techLists = new ArrayList<String[]>();
private Context context;
private ReactApplicationContext reactContext;
private Boolean isForegroundEnabled = false;
private Boolean isResumed = false;

public NfcManager(ReactApplicationContext reactContext) {
super(reactContext);
context = reactContext;
this.reactContext = reactContext;
reactContext.addActivityEventListener(this);
reactContext.addLifecycleEventListener(this);
Log.d(LOG_TAG, "NfcManager created");
}

@Override
public String getName() {
return "NfcManager";
}

@ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}

@ReactMethod
public void isEnabled(Callback callback) {
Log.d(LOG_TAG, "isEnabled");
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
callback.invoke(null, nfcAdapter.isEnabled());
} else {
callback.invoke(null, false);
}
}

@ReactMethod
public void goToNfcSetting(Callback callback) {
Log.d(LOG_TAG, "goToNfcSetting");
Activity currentActivity = getCurrentActivity();
currentActivity.startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
callback.invoke();
}

@ReactMethod
public void getLaunchTagEvent(Callback callback) {
Activity currentActivity = getCurrentActivity();
Intent launchIntent = currentActivity.getIntent();
WritableMap nfcTag = parseNfcIntent(launchIntent);
callback.invoke(null, nfcTag);
}

@ReactMethod
private void registerTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = true;

// capture all mime-based dispatch NDEF
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
intentFilters.add(ndef);

// capture all rest NDEF, such as uri-based
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED));
techLists.add(new String[]{Ndef.class.getName()});

// for those without NDEF, get them as tags
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED));

if (isResumed) {
enableDisableForegroundDispatch(true);
}
callback.invoke();
}

@ReactMethod
private void unregisterTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = false;
intentFilters.clear();
if (isResumed) {
enableDisableForegroundDispatch(false);
}
callback.invoke();
}

@Override
public void onHostResume() {
Log.d(LOG_TAG, "onResume");
isResumed = true;
if (isForegroundEnabled) {
enableDisableForegroundDispatch(true);
}
}

@Override
public void onHostPause() {
Log.d(LOG_TAG, "onPause");
isResumed = false;
enableDisableForegroundDispatch(false);
}

@Override
public void onHostDestroy() {
Log.d(LOG_TAG, "onDestroy");
}

private void enableDisableForegroundDispatch(boolean enable) {
Log.i(LOG_TAG, "enableForegroundDispatch, enable = " + enable);
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
Activity currentActivity = getCurrentActivity();

if (nfcAdapter != null && !currentActivity.isFinishing()) {
try {
if (enable) {
nfcAdapter.enableForegroundDispatch(currentActivity, getPendingIntent(), getIntentFilters(), getTechLists());
} else {
nfcAdapter.disableForegroundDispatch(currentActivity);
}
} catch (IllegalStateException e) {
Log.w(LOG_TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
}
}
}

private PendingIntent getPendingIntent() {
Activity activity = getCurrentActivity();
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(activity, 0, intent, 0);
}

private IntentFilter[] getIntentFilters() {
return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
}

private String[][] getTechLists() {
return techLists.toArray(new String[0][0]);
}

private void sendEvent(String eventName,
@Nullable WritableMap params) {
getReactApplicationContext()
.getJSModule(RCTNativeAppEventEmitter.class)
.emit(eventName, params);
}

private void sendEventWithJson(String eventName,
JSONObject json) {
try {
WritableMap map = JsonConvert.jsonToReact(json);
sendEvent(eventName, map);
} catch (JSONException ex) {
Log.d(LOG_TAG, "fireNdefEvent fail: " + ex);
}
}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive " + intent);
}
};

@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult");
}

@Override
public void onNewIntent(Intent intent) {
Log.d(LOG_TAG, "onNewIntent " + intent);
WritableMap nfcTag = parseNfcIntent(intent);
if (nfcTag != null) {
sendEvent("NfcManagerDiscoverTag", nfcTag);
}
}

private WritableMap parseNfcIntent(Intent intent) {
Log.d(LOG_TAG, "parseIntent " + intent);
String action = intent.getAction();
Log.d(LOG_TAG, "action " + action);
if (action == null) {
return null;
}

WritableMap parsed = null;
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));

if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
Ndef ndef = Ndef.get(tag);
Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
parsed = ndef2React(ndef, messages);
} else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
for (String tagTech : tag.getTechList()) {
Log.d(LOG_TAG, tagTech);
if (tagTech.equals(NdefFormatable.class.getName())) {
// fireNdefFormatableEvent(tag);
} else if (tagTech.equals(Ndef.class.getName())) { //
Ndef ndef = Ndef.get(tag);
parsed = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
}
}
} else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
parsed = tag2React(tag);
}

return parsed;
}

private WritableMap tag2React(Tag tag) {
try {
JSONObject json = Util.tagToJSON(tag);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}

}

private WritableMap ndef2React(Ndef ndef, Parcelable[] messages) {
try {
JSONObject json = buildNdefJSON(ndef, messages);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}
}

JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
JSONObject json = Util.ndefToJSON(ndef);

// ndef is null for peer-to-peer
// ndef and messages are null for ndef format-able
if (ndef == null && messages != null) {

try {

if (messages.length > 0) {
NdefMessage message = (NdefMessage) messages[0];
json.put("ndefMessage", Util.messageToJSON(message));
// guessing type, would prefer a more definitive way to determine type
json.put("type", "NDEF Push Protocol");
}

if (messages.length > 1) {
Log.d(LOG_TAG, "Expected one ndefMessage but found " + messages.length);
}

} catch (JSONException e) {
// shouldn't happen
Log.e(Util.TAG, "Failed to convert ndefMessage into json", e);
}
}
return json;
}

}

我的 nfc 组件

import React, { Component } from 'react';
import {
View,
Text,
Button,
Platform,
TouchableOpacity,
Linking
} from 'react-native';
import NfcManager, {NdefParser} from 'react-native-nfc-manager';

class NFC extends Component {
constructor(props) {
super(props);
this.state = {
supported: true,
enabled: false,
tag: {},
}
}

componentDidMount() {
NfcManager.start({
onSessionClosedIOS: () => {
console.log('ios session closed');
}
})
.then(result => {
console.log('start OK', result);
})
.catch(error => {
console.warn('start fail', error);
this.setState({supported: false});
})

if (Platform.OS === 'android') {
NfcManager.getLaunchTagEvent()
.then(tag => {
console.log('launch tag', tag);
if (tag) {
this.setState({ tag });
}
})
.catch(err => {
console.log(err);
})
NfcManager.isEnabled()
.then(enabled => {
this.setState({ enabled });
})
.catch(err => {
console.log(err);
})
}
}

render() {
let { supported, enabled, tag } = this.state;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>{`Is NFC supported ? ${supported}`}</Text>
<Text>{`Is NFC enabled (Android only)? ${enabled}`}</Text>

<TouchableOpacity style={{ marginTop: 20 }} onPress={this._startDetection}>
<Text style={{ color: 'blue' }}>Start Tag Detection</Text>
</TouchableOpacity>

<TouchableOpacity style={{ marginTop: 20 }} onPress={this._stopDetection}>
<Text style={{ color: 'red' }}>Stop Tag Detection</Text>
</TouchableOpacity>

<TouchableOpacity style={{ marginTop: 20 }} onPress={this._clearMessages}>
<Text>Clear</Text>
</TouchableOpacity>

<TouchableOpacity style={{ marginTop: 20 }} onPress={this._goToNfcSetting}>
<Text >Go to NFC setting</Text>
</TouchableOpacity>

<Text style={{ marginTop: 20 }}>{`Current tag JSON: ${JSON.stringify(tag)}`}</Text>
</View>
)
}

_onTagDiscovered = tag => {
console.log('Tag Discovered', tag);
this.setState({ tag });
let url = this._parseUri(tag);
if (url) {
Linking.openURL(url)
.catch(err => {
console.warn(err);
})
}
}

_startDetection = () => {
NfcManager.registerTagEvent(this._onTagDiscovered)
.then(result => {
console.log('registerTagEvent OK', result)
})
.catch(error => {
console.warn('registerTagEvent fail', error)
})
}

_stopDetection = () => {
NfcManager.unregisterTagEvent()
.then(result => {
console.log('unregisterTagEvent OK', result)
})
.catch(error => {
console.warn('unregisterTagEvent fail', error)
})
}

_clearMessages = () => {
this.setState({tag: null});
}

_goToNfcSetting = () => {
if (Platform.OS === 'android') {
NfcManager.goToNfcSetting()
.then(result => {
console.log('goToNfcSetting OK', result)
})
.catch(error => {
console.warn('goToNfcSetting fail', error)
})
}
}

_parseUri = (tag) => {
let result = NdefParser.parseUri(tag.ndefMessage[0]),
uri = result && result.uri;
if (uri) {
console.log('parseUri: ' + uri);
return uri;
}
return null;
}
}
export default NFC;

最佳答案

请注意,NFC 并非在所有设备上都可用,因此您必须先检查:

  protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null){
Toast.makeText(this, "NFC not available", Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(this, "NFC is avalable", Toast.LENGTH_SHORT).show();
}
....
....
}

如果 NFC 不存在,这将是收到错误消息的原因:

Attempt to get length of null array on NfcManager.start()

关于java - 尝试在 NfcManager.start() 上获取空数组的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46951110/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com