我正在使用 flutter nfc_manager 在 nfc 标签上写入。 它在 iOS 上运行得很好 但在 Android 中,当我尝试在空的 NFC 标签上写入时出现问题。 在具有现有数据的标签上写入工作正常。我该如何解决?
这是我的iOS代码
Future<bool> _ndefWrite(NdefMessage ndefMessage) async {
Completer<bool> completer = Completer<bool>();
await NfcManager.instance.startSession(
pollingOptions: {NfcPollingOption.iso14443, NfcPollingOption.iso15693},
alertMessage: "NFC 태그를 스캔해주세요.",
onDiscovered: (NfcTag tag) async {
var ndef = Ndef.from(tag);
if (ndef == null || !ndef.isWritable) {
_errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Use completer to complete with false
} else {
try {
await ndef.write(ndefMessage);
_alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
NfcManager.instance.stopSession(alertMessage: _alertMessage);
completer.complete(true); // Complete with true upon success
} catch (error) {
_errorMessage = error.toString();
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Complete with false on error
}
}
},
onError: (NfcError error) async {
_errorMessage = error.message;
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Complete with false on error
}
);
return completer.future.timeout(const Duration(seconds: 10), onTimeout: () {
NfcManager.instance.stopSession(errorMessage: "NFC 스캔 시간 초과.");
if (!completer.isCompleted) {
completer.complete(false); // Complete with false only if not already completed
}
return false;
});
}
这是我的 Android 代码。 我认为问题在于,当检测到代码中的空标签时,它会变为 null “Ndef.from(标签)” 但在ios中它工作正常。
Future<bool> _ndefWriteAndroid(NdefMessage ndefMessage) async {
Completer<bool> completer = Completer<bool>();
NFCDialog nfcDialog = NFCDialog(context: context, completer: completer);
nfcDialog.show();
await NfcManager.instance.startSession(
onDiscovered: (NfcTag tag) async {
Navigator.of(context, rootNavigator: true).pop();
var ndef = Ndef.from(tag);
if (ndef == null || !ndef.isWritable) {
_errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Use completer to complete with false
} else {
try {
await ndef.write(ndefMessage);
_alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
NfcManager.instance.stopSession(alertMessage: _alertMessage);
completer.complete(true); // Complete with true upon success
} catch (error) {
_errorMessage = error.toString();
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Complete with false on error
}
}
},
);
return completer.future.timeout(const Duration(seconds: 10), onTimeout: () {
Navigator.of(context, rootNavigator: true).pop();
NfcManager.instance.stopSession(errorMessage: "NFC 스캔 시간 초과.");
if (!completer.isCompleted) {
completer.complete(false); // Complete with false only if not already completed
}
return false;
});
}
这是我在 AndroidManifest.xml 中的意图过滤器
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
问题是空标签不是Ndef标签,Ndef标签必须至少有一个空TLV块。
在 Android 中,要检测能够存储 Ndef 消息的空标签,您需要查找 NdefFormatable 标签
所以你需要将代码中的逻辑重新安排为这样
var ndef = Ndef.from(tag);
if (ndef == null) {
var ndefFormatable = NdefFormatable.from(tag);
if (ndefFormatable != null) {
// Format and write message in one operation.
await ndefFormatable.format(ndefMessage);
_alertMessage = "NFC Success message";
NfcManager.instance.stopSession(alertMessage: _alertMessage);
completer.complete(true); // Complete with true upon success
} else {
errorMessage = "Some error message";
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Use completer to complete with false
}
} else if (!ndef.isWritable) {
_errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Use completer to complete with false
} else {
try {
await ndef.write(ndefMessage);
_alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
NfcManager.instance.stopSession(alertMessage: _alertMessage);
completer.complete(true); // Complete with true upon success
} catch (error) {
_errorMessage = error.toString();
NfcManager.instance.stopSession(errorMessage: _errorMessage);
completer.complete(false); // Complete with false on error
}
}
基本上,如果您没有检测到 Ndef 标签,请尝试检测 Ndeformatable 标签,然后在那里格式化(并写入)您的 Ndef 消息。如果不是任何一种类型,则失败。