在Android上持续检测NFC标签

时间:2016-05-05 08:02:31

标签: android tags nfc energy

根据我的阅读和实验,我发现Android设备使用某种方法来防止重复读取标记(as discussed here)。这对于节能非常有用,但是限制了该技术的可能应用。

例如,我面临的问题是,我有一个无源标签,内容不断更新。一旦标签被读取,手机就会停止检测标签,直到标签被移除为止,在此期间您无法继续读取标签中的更新内容,而无需将其从现场移除并重新点击。 此外,在最初读取标签之后,磁场被非常弱地断电以节省功率。因此,您不能持续为被动设备供电。

有没有办法强制Android设备持续供电并读取更新的无源标签?

注意:我不介意它是否涉及根植Android设备以实现对硬件的直接控制。

2 个答案:

答案 0 :(得分:3)

您在问题中陈述的内容对Android NFC设备而言根本不适用。一旦检测到标签(=有效标签响应所有强制命令并且可能被分派到应用程序),NFC阅读器将持续为标签供电(HF载波保持打开)并与之交换一些命令。在保持活动阶段("存在检查")期间交换的命令取决于标签类型,Android版本和Android NFC堆栈实现。这通常是

  1. 重复停用和重新激活周期,
  2. 反复阅读某个记忆区域,或
  3. 其他一些乒乓命令序列
  4. 允许NFC堆栈查明标签是否仍然响应。只有当存在检查失败时,Android才会关闭NFC阅读器的HF载波,并重新启动完整的轮询序列(测试所有类型的支持标签技术)或带有感应阶段(短的HF载波脉冲到检测失调,表明标签可能存在。)

    因此,如果您的代码行为正常并且您的用户设法将标记附加到Android设备上较长时间,那么就没有什么可以阻止您从同一标记中读取新数据(连续附加时)多次。只要您想要访问应用的标记和标记读取活动,您就需要确保保留标记句柄(Tag对象或甚至是从该标记句柄实例化的特定标记技术对象)。需要一直保持在前台。

    例如,您可以执行类似这样的操作,从标签中读取持续更新的NDEF消息(请注意,您最好使用AsyncTask(或类似的)而不是简单地生成该线程而您可能想要实现某种机制来中断线程):

    new Thread(new Runnable() {
        public void run() {
            Ndef ndef = Ndef.get(tag);
    
            try {
                while (true) {
                    try {
                        Thread.sleep(30000);
    
                        ndef.connect();
                        NdefMessage msg = ndef.getNdefMessage();
    
                        // TODO: do something
    
                    } catch (IOException e) {
                        // if the tag is gone we might want to end the thread:
                        break;
                    } finally {
                        try {
                            ndef.close();
                        } catch (Exception e) {}
                    }
                }
            } catch (InterruptedException e) {
            }
        }
    }).start();
    

答案 1 :(得分:0)

迈克尔的绝妙答案。 但是我看到一个问题。当标签上的微控制器对NFC设备中的非易失性存储器执行i2c读取时,似乎有可能干扰电话正在执行的“ ping”操作。

我正在使用摩托罗拉G6 Play手机,其功能与带有M24LR04E-R的M24LR-DISCOVERY标签非常相似。 [我复制了ST25DV的结果。]标签由台式电源供电,而不是本实验的能量收集。

当标签在手机字段中时,我每隔130ms左右即可看到Android调试器的logcat中的活动。

2020-10-13 19:38:50.555 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(793)] nfaConnectionCallback: Connection Event = 15
2020-10-13 19:38:50.555 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(1389)] nfaConnectionCallback: NFA_PRESENCE_CHECK_EVT
2020-10-13 19:38:50.680 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1953)] nativeNfcTag_doPresenceCheck
2020-10-13 19:38:50.680 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1997)] nativeNfcTag_doPresenceCheck: handle=0
2020-10-13 19:38:50.694 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(793)] nfaConnectionCallback: Connection Event = 15
2020-10-13 19:38:50.694 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(1389)] nfaConnectionCallback: NFA_PRESENCE_CHECK_EVT
2020-10-13 19:38:50.820 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1953)] nativeNfcTag_doPresenceCheck
2020-10-13 19:38:50.820 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1997)] nativeNfcTag_doPresenceCheck: handle=0

这似乎是Android在检查代码是否存在。在这段时间内,我看到M24LR的RF_BUSY输出每130ms左右变低约15ms。我将此与上面的Android活动相关联。

如果微控制器随后通过M24LR存储器的i2c进行了块读取,则不久之后电话会播放通知音。发生的情况是电话与标签失去连接并重新连接。这次的logcat输出显示了这种情况,而没有警告。

2020-10-13 19:38:51.335 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(793)] nfaConnectionCallback: Connection Event = 15
2020-10-13 19:38:51.335 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(1389)] nfaConnectionCallback: NFA_PRESENCE_CHECK_EVT
2020-10-13 19:38:51.335 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(2173)] nativeNfcTag_doPresenceCheck: tag absent
2020-10-13 19:38:51.335 4209-28960/? D/NativeNfcTag: Tag lost, restarting polling loop
2020-10-13 19:38:51.335 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1392)] nativeNfcTag_doDisconnect: enter
2020-10-13 19:38:51.335 4209-28960/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(1414)] nativeNfcTag_doDisconnect: exit
2020-10-13 19:38:51.336 4209-28960/? D/NfcService: Discovery configuration equal, not updating.
2020-10-13 19:38:51.336 4209-28960/? D/NativeNfcTag: Stopping background presence check
2020-10-13 19:38:51.344 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(793)] nfaConnectionCallback: Connection Event = 6
2020-10-13 19:38:51.344 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(1121)] nfaConnectionCallback: NFA_DEACTIVATED_EVT: Type=0, gIsTagDeactivating=0
2020-10-13 19:38:51.344 4209-4411/? I/libnfc_nci: [INFO:NativeNfcManager.cpp(5280)] notifyPollingEventwhileNfcOff: sDiscCmdwhleNfcOff=0
2020-10-13 19:38:51.344 4209-4411/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(921)] getReconnectState = 0x0
2020-10-13 19:38:51.345 4209-4411/? I/libnfc_nci: [INFO:NfcTag.cpp(189)] NfcTag::setDeactivationState: state=0
2020-10-13 19:38:51.345 4209-4411/? I/libnfc_nci: [INFO:NfcTag.cpp(1358)] NfcTag::resetTechnologies
2020-10-13 19:38:51.345 4209-4411/? I/libnfc_nci: [INFO:NativeNfcTag.cpp(263)] nativeNfcTag_abortWaits

断开连接显然会对试图在手机上与标签交换信息的任何应用程序造成严重破坏。

我尝试使用BUSY信号来防止标签上的微控制器在进行RF访问时仍开始任何i2c读取操作,但问题仍然存在。我猜这是由于在进行内存访问时发生RF ping而引起的,但我只是在猜测。

似乎断开连接的机会随着读取的字节数增加(支持“冲突”的想法。)单字节读取通常可以在不引起断开连接的情况下摆脱。

这真的是正确的行为吗?没有什么可以防止的呢? OP(或我本人)将如何使用这些设备来实现一个系统,标签上的微控制器可以读取/写入NFC设备的内存,以与手机上运行的应用交换信息? 如我所说,我在M24LR和ST25DV上都观察到了这一点。

[很抱歉,这不是一个问题,而是一个答案,但我想对这个问题有更多的了解。]