Android NFC writeNdefMessage抛出IOException标签不是ndef

时间:2014-04-14 09:53:56

标签: android nfc ndef

我正在开发一个NFC环境,包括一个标签(AS3953芯片+微控制器)和一个智能手机(三星Galaxy Fame runnung Android 4.1.2)。

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

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

正如你所看到的,抛出了一个IOException,说Tag不是ndef,这是矛盾的 技术列表。进一步研究android代码,writeNdefMessage()试图获取 标记中的TagService和ServiceHandle以匹配它们。这样就失败了 抛出异常(到目前为止没有写入消息):

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:先关闭其他技术!

我将AS3953配置为ISO14443A Level-4,因此只转发Tag Type 4 Blocks 到微控制器。只处理I-Block,但即使有其他命令,μ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意图的活动。 就像在链接的示例中一样,手机触摸调用onResume()的标签 mNfcAdapter.enableForegroundDispatch(...);

当我记录SPI通信时,完成与上述相同的读取过程。自LogCat 显示一个工作意图调度程序我猜应用程序在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

1 个答案:

答案 0 :(得分:4)

现在有效。我想出了一个检查和设置配置字的启动例程 对于AS3953,波特率过高。这适用于阅读但有些东西 必须混淆写入标签。

我无法确定这是否是它无法运作的唯一原因。还有一个问题 由于水位中断的处理太晚,因此读取32Byte FIFO的速度很慢 - 我只是期望 由于我无法在逻辑分析中找到写命令,因此问题出在android端 而且例外并没有足够的描述原因。

非常感谢Michael Roland的进一步调试,我仍然不知道为什么标签是 首先阅读,如果我想写它,但很好 - 应该有一个解决方法阅读 空ndef消息,这样写入过程将很快完成。

现在我必须处理固件并且无法预测任何进一步的问题,但实际情况 issue(ndef.writeNdefMessage())成功返回。