![](/img/trans.png)
[英]Android NFC - ndef.writeNdefMessage() throws IOException and erases tag data
[英]Android NFC writeNdefMessage throws IOException Tag is not 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复制了大部分代码,并通过搜索标签技术列表将其修改为接受ISO14443A标签类型4对于支持技术()中的IsoDep,NfcA和Ndef。 由于列出了所有这些,app继续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 Block被转发到微控制器。 只处理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
它现在有效。 我发现检查和设置配置字的启动例程是以过高的波特率传输的,用于AS3953。 这适用于阅读,但必须混淆写入标签的东西。
我无法确定这是否是它无效的唯一原因。 由于水位中断的处理太迟,因此32Byte FIFO的读取速度也很慢 - 我只是期望问题出在android端,因为我在逻辑分析中找不到写命令而异常没有足够描述原因。
非常感谢Michael Roland进行进一步的调试,我仍然没有解释为什么首先读取标签,如果我想写它但是很好 - 应该有一个解决方法,读取空的ndef消息,这样写入过程就完成了很快。
目前我必须处理固件,无法预测任何进一步的问题,但实际问题(ndef.writeNdefMessage())成功返回。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.