Android NFC writeNdefMessage 抛出 IOException Tag is not ndef

标签 android nfc ndef

我正在开发一个由标签(AS3953 芯片 + 微 Controller )和智能手机(运行 Android 4.1.2 的三星 Galaxy Fame)组成的 NFC 环境。

虽然读取 NDEF 消息有效,但我一直坚持将消息写入标签。 我从 http://tapintonfc.blogspot.de/2012/07/the-above-footage-from-our-nfc-workshop.html 复制了大部分代码 并通过在 supportedTechs() 中搜索 IsoDep、NfcA 和 Ndef 的标签技术列表来修改它以接受 ISO14443A 标签类型 4。 由于所有这些都已列出,因此应用程序继续写入 Tag():

public WriteResponse writeTag(NdefMessage message, Tag tag) {
try {
    Ndef ndef = Ndef.get(tag);
    if (ndef != null) {
        Log.d(TAG, "writeTag: tag type: "+ndef.getType());
        ndef.connect();
        Log.d(TAG, "writeTag: connected!");
        if (!ndef.isWritable()) {
            return new WriteResponse(0, "Tag is read-only");
        }
        if (ndef.getMaxSize() < message.toByteArray().length) {
            return new WriteResponse(0, "size error");
        }
        Log.d(TAG, "writeTag: write ndef...");
        ndef.writeNdefMessage(message);
        Log.d(TAG, "writeTag: wrote ndef!");
        if (writeProtect)
            ndef.makeReadOnly();
        return new WriteResponse(1, "Wrote message to pre-formatted tag.");
    } else {
        Log.d(TAG, "writeTag: ndef==null!");
        return new WriteResponse(0, "writeTag: ndef==null!");
    }
} catch (Exception e) {
    Log.d(TAG, "writeTag: exception: " + e.toString());
    return new WriteResponse(0, "Failed to write tag");
}
}

LogCat 显示:

11:08:46.400: onNewIntent
11:08:46.400: supportedTechs: techlist: android.nfc.tech.IsoDep,android.nfc.tech.NfcA,android.nfc.tech.Ndef,
11:08:46.400: supportedTechs: tech is supported!
11:08:46.400: writeTag: tag type: org.nfcforum.ndef.type4
11:08:46.410: writeTag: connected!
11:08:46.410: writeTag: write ndef...
11:08:46.490: writeTag: exception: java.io.IOException: Tag is not ndef

As you can see an IOException is thrown saying the Tag is not ndef which contradicts the techlist. Looking further into the android code writeNdefMessage() tries to get a TagService and a ServiceHandle from the tag to match them against. This fails so the exception is thrown (no message written up to now):

public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
...
INfcTag tagService = mTag.getTagService();
...
int serviceHandle = mTag.getServiceHandle();
if (tagService.isNdef(serviceHandle)) {
    ...
}
else {
    throw new IOException("Tag is not ndef");
}
...
}

是否有解决方法,或者我的标签根本不可能? 由于我也在对标签进行编程,错误可能在另一侧,但它 似乎是 Java 的问题。


编辑 1:

我之前没有连接到任何技术,所以不应该有任何打开的连接。如果 我在ndef.connect()之前打开一个连接有IllegalStateException: Close other technology first!

我将 AS3953 配置为 ISO14443A Level-4,因此仅转发标签类型 4 block 到微 Controller 。仅处理 I-Blocks,但即使有其他命令,µC 也必须将其读出 通过 SPI 端口,逻辑分析并非如此。正如我所说,读取 ndef 文件有效并且我测试了它 对于一个 4KB 的文件。查看逻辑分析,执行以下步骤(全部返回正 9000 代码):

(c=command, r=response) (corrected due to renaming mistake)
select by name:
c: 02 00 a4 04 00 07 d2 76 00 00 85 01 01 00
r: 02 90 00
select by id - select cc file
c: 03 00 a4 00 0c 02 e1 03
r: 03 90 00
read 0x0f bytes of cc file
c: 02 00 b0 00 00 0f
r: 02 00 0f 20 00 3b 00 34 04 06 e1 04 0f ff 00 00 90 00
select by id - select ndef file
c: 03 00 a4 00 0c 02 e1 04
r: 03 90 00
read 0x02 bytes (first 2 bytes are apdu-size)
c: 02 00 b0 00 00 02
r: 02 0f d3 90 00
read 0x3b bytes (frame size) of first part of ndef file (external type, jpeg image as payload)
c: 03 00 b0 00 02 3b
r: 03 c4 0c 00 00 0f c1 64 65 2e 74 65 73 74 61 70 70 3a 61 01 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 00 60 00 00 ff db 00 43 00 49 32 36 40 36 2d 49 40 3b 40 52 4d 49 56 6d 90 00
[ndef file]
read 0x26 bytes of last part of ndef file
c: 03 00 b0 0f ae 27
r: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF D9 00 00 90 00

使用相同的应用程序进行写作,我开始过滤 NfcAdapter.ACTION_TAG_DISCOVERED Intent 的 Activity 。 就像在链接示例中一样,手机触摸了调用 onResume() 的标签 mNfcAdapter.enableForegroundDispatch(...);

当我记录 SPI 通信时,完成了与上述相同的读取过程。由于 LogCat 显示一个工作 Intent 调度程序我猜应用程序在 IOException 停止,关闭连接 当 android 再次找到标签时,立即过去读出。


编辑 2:

当第一个中断发出取消选择命令时,可能会有提示 由 AS3953 本身处理:

(count * interrupt)
3 * power up 
1 * Wake-up IRQ at entry in ACTIVE(*) state 
1 * Deselect command
1 * Wake-up IRQ at entry in ACTIVE(*) state 
1 * IRQ due to start of receive

最佳答案

现在可以了。我想出了一个检查和设置配置字的启动例程 以对 AS3953 而言过高的波特率传输。这对阅读有用,但有些东西 一定是混淆了写入标签。

我不能确定这是否是它不起作用的唯一原因。还有一个问题 32 字节 FIFO 的读取速度很慢,因为水位中断处理得太晚了——我只是期望 问题出在android端,因为我在逻辑分析中找不到write命令 并且异常没有充分描述原因。

非常感谢 Michael Roland 的进一步调试,我仍然不明白为什么标签是 如果我想写信,请先阅读,但好吧 - 应该有一个解决方法 空的 ndef 消息,因此写入过程将快速完成。

现在我必须在固件上工作,不能预测任何进一步的问题,但实际 issue (ndef.writeNdefMessage()) 成功返回。

关于Android NFC writeNdefMessage 抛出 IOException Tag is not ndef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23057060/

相关文章:

android - 在 fragment 中播放 YouTube 视频

android - Android NFC 手机可以充当 NFC 标签吗?

javascript - 如何在 Electron 项目中实现 nfc 阅读器 (ACR122)?

android - 将服务与 Activity (广播、回调等)通信的最佳方式

java - 从数组加载 map (游戏)时出现问题

java - 当互联网关闭和恢复时,如何使 android 中的发射器监听器工作?

android - 低功耗蓝牙与 NFC

android - writeNdefMessage 中断 I/O 后 NFC Tag 变为 "corrupted"

c# - 如何使用兼容Android的C#读写NDEF格式的NFC标签?

swift - 替换 readerSession 中的 CoreNFC UI?