我正在尝试使用Android应用程序将数据写入NFC卡,但是当我尝试编写数据时,我得到了一个java.io.IOExcetion。日志告诉我它是null。我添加了printstacktrace,它指向android.nfc.tech.NdefFormatble.format(NdefFormarmatable.java:131)和android.nfc.tech.NdefFormatble.format(NdefFormarmatable.java:94)的错误。我已经看过这个类,看看错误是什么,Android Studio说它无法解析该类中某些导入的符号。我无法弄清楚出了什么问题,我很感激有任何帮助来解决这个问题。我以前确实有这个工作,然后突然间我开始得到这个错误。我确实将Android Studio更新为3.1.1,但我尝试使用AS 3.0和2.3但是我得到了同样的错误。我已经包含了所有被调用的方法以及堆栈跟踪。
这是卡的格式化并写入:
private void formatTag(Tag tag, NdefMessage ndefMessage) {
try {
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
if (ndefFormatable == null) {
Toast.makeText(this, "Tag is not ndef formatable!", Toast.LENGTH_SHORT).show();
return;
}
ndefFormatable.connect();
ndefFormatable.format(ndefMessage); ***<----MainActivity.java:469***
ndefFormatable.close();
Toast.makeText(this, "Tag writen!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Log.e("formatTag", "" + e.getMessage());
e.printStackTrace();
}
}
这是编写NDEF消息的方法
private void writeNdefMessage(Tag tag, NdefMessage ndefMessage) {
try {
if (tag == null) {
Toast.makeText(this, "Tag object cannot be null", Toast.LENGTH_SHORT).show();
return;
}
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// format tag with the ndef format and writes the message.
formatTag(tag, ndefMessage); **<----- MainActivity.java 494**
} else {
ndef.connect();
if (!ndef.isWritable()) {
Toast.makeText(this, "Tag is not writable!", Toast.LENGTH_SHORT).show();
ndef.close();
return;
}
ndef.writeNdefMessage(ndefMessage);
ndef.close();
Toast.makeText(this, "Tag writen!", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.e("writeNdefMessage", "" + e.getMessage());
e.printStackTrace();
}
这是从
调用writeNdefMessage的地方 @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) {
Toast.makeText(this, "NfcIntent!", Toast.LENGTH_SHORT).show();
if(tglReadWrite.isChecked())
{
Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if(parcelables != null && parcelables.length > 0)
{
readDataFromMessage((NdefMessage) parcelables[0]);
}else{
Toast.makeText(this, "No NDEF messages found!", Toast.LENGTH_SHORT).show();
}
}else{
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
NdefMessage ndefMessage = createNdefMessage(mToken.getText()+";");
writeNdefMessage(tag, ndefMessage); ***<---- MainActivity.java:406***
}
}
}
这是StackTrace
04-13 02:50:51.112 6311-6311/com.appsolutedevelopment.labourstaff E/formatTag: null
04-13 02:50:51.112 6311-6311 / com.appsolutedevelopment.labourstaff W / System.err:java.io.IOException 04-13 02:50:51.113 6311-6311 / com.appsolutedevelopment.labourstaff W / System.err:at android.nfc.tech.NdefFormatable.format(NdefFormatable.java:131) 在android.nfc.tech.NdefFormatable.format(NdefFormatable.java:94) at com.appsolutedevelopment.labourstaff.MainActivity.formatTag(MainActivity.java:469) at com.appsolutedevelopment.labourstaff.MainActivity.writeNdefMessage(MainActivity.java:494) at com.appsolutedevelopment.labourstaff.MainActivity.onNewIntent(MainActivity.java:406) 在android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1228) 在android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1240) 在android.app.ActivityThread.deliverNewIntents(ActivityThread.java:2946) 在android.app.ActivityThread.performNewIntents(ActivityThread.java:2958) 在android.app.ActivityThread.handleNewIntent(ActivityThread.java:2967) 在android.app.ActivityThread.-wrap15(ActivityThread.java) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1648) 在android.os.Handler.dispatchMessage(Handler.java:105) 在android.os.Looper.loop(Looper.java:156) 在android.app.ActivityThread.main(ActivityThread.java:6523) at java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:942) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
最后是NdefFormatable类
package android.nfc.tech;
import android.nfc.ErrorCodes; ***<---- Cannot resolve symbol 'ErrorCodes'***
import android.nfc.FormatException;
import android.nfc.INfcTag; ***<---- Cannot resolve symbol 'INfcTag'***
import android.nfc.NdefMessage;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.os.RemoteException;
import android.util.Log;
import java.io.IOException;
/**
* Provide access to NDEF format operations on a {@link Tag}.
*
* <p>Acquire a {@link NdefFormatable} object using {@link #get}.
*
* <p>Android devices with NFC must only enumerate and implement this
* class for tags for which it can format to NDEF.
*
* <p>Unfortunately the procedures to convert unformated tags to NDEF formatted
* tags are not specified by NFC Forum, and are not generally well-known. So
* there is no mandatory set of tags for which all Android devices with NFC
* must support {@link NdefFormatable}.
*
* <p class="note"><strong>Note:</strong> Methods that perform I/O operations
* require the {@link android.Manifest.permission#NFC} permission.
*/
public final class NdefFormatable extends BasicTagTechnology {
private static final String TAG = "NFC";
/**
* Get an instance of {@link NdefFormatable} for the given tag.
* <p>Does not cause any RF activity and does not block.
* <p>Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}.
* This indicates the tag is not NDEF formatable by this Android device.
*
* @param tag an NDEF formatable tag
* @return NDEF formatable object
*/
public static NdefFormatable get(Tag tag) {
if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null;
try {
return new NdefFormatable(tag);
} catch (RemoteException e) {
return null;
}
}
/**
* Internal constructor, to be used by NfcAdapter
* @hide
*/
public NdefFormatable(Tag tag) throws RemoteException {
super(tag, TagTechnology.NDEF_FORMATABLE);
}
/**
* Format a tag as NDEF, and write a {@link NdefMessage}.
*
* <p>This is a multi-step process, an IOException is thrown
* if any one step fails.
* <p>The card is left in a read-write state after this operation.
*
* <p>This is an I/O operation and will block until complete. It must
* not be called from the main application thread. A blocked call will be canceled with
* {@link IOException} if {@link #close} is called from another thread.
*
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param firstMessage the NDEF message to write after formatting, can be null
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message to write is malformed
*/
public void format(NdefMessage firstMessage) throws IOException, FormatException {
format(firstMessage, false); ***<----NdefFormatable.java:94***
}
/**
* Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only.
*
* <p>This is a multi-step process, an IOException is thrown
* if any one step fails.
* <p>The card is left in a read-only state if this method returns successfully.
*
* <p>This is an I/O operation and will block until complete. It must
* not be called from the main application thread. A blocked call will be canceled with
* {@link IOException} if {@link #close} is called from another thread.
*
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param firstMessage the NDEF message to write after formatting
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message to write is malformed
*/
public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
format(firstMessage, true);
}
/*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException,
FormatException {
checkConnected();
try {
int serviceHandle = mTag.getServiceHandle();
INfcTag tagService = mTag.getTagService();
int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
case ErrorCodes.ERROR_IO:
throw new IOException(); ***<---- NdefFormatable.java:131***
case ErrorCodes.ERROR_INVALID_PARAM:
throw new FormatException();
default:
// Should not happen
throw new IOException();
}
// Now check and see if the format worked
if (!tagService.isNdef(serviceHandle)) {
throw new IOException();
}
// Write a message, if one was provided
if (firstMessage != null) {
errorCode = tagService.ndefWrite(serviceHandle, firstMessage);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
case ErrorCodes.ERROR_IO:
throw new IOException();
case ErrorCodes.ERROR_INVALID_PARAM:
throw new FormatException();
default:
// Should not happen
throw new IOException();
}
}
// optionally make read-only
if (makeReadOnly) {
errorCode = tagService.ndefMakeReadOnly(serviceHandle);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
case ErrorCodes.ERROR_IO:
throw new IOException();
case ErrorCodes.ERROR_INVALID_PARAM:
throw new IOException();
default:
// Should not happen
throw new IOException();
}
}
} catch (RemoteException e) {
Log.e(TAG, "NFC service dead", e);
}
}
}
如果我遗漏了任何内容,或者任何人需要更多信息,请询问,我会得到所需的一切。如果有人可以对此有所了解,我会非常感激,因为它已经让我扭转了这么长时间。
感谢。
答案 0 :(得分:0)
我在Android NFC - ndef.writeNdefMessage() throws IOException and erases tag data找到了这个问题的答案。这解释了当我尝试在写入操作失败后写入NFC卡时,我的应用程序中发生了什么。如果有人正在寻找这个问题的解决方案,那么这个Android nfcA.connect(), nfcA.transceive(), nfcA.setTimeout() and nfcA.getMaxTransceiveLength()可能会有所帮助。如果您正在尝试将读取和写入关键数据写入NFC令牌/卡片,那么我建议使用nfcA作为NDEF的反对者。