Непрерывно обнаруживать тег NFC на Android

Из моего чтения и экспериментов я обнаружил, что устройства Android используют некоторый метод для предотвращения дублирования чтения тега (как обсуждалось здесь). Это отлично подходит для энергосбережения, однако ограничивает возможное применение этой технологии.

Например, проблема, с которой я сталкиваюсь, заключается в том, что у меня есть пассивный тег, содержимое которого постоянно обновляется. После того, как тег прочитан, телефон перестает обнаруживать теги до тех пор, пока он не будет удален, в течение этого времени вы не можете продолжать читать обновленное содержимое в теге, не удаляя его из поля и повторно нажимая. Кроме того, магнитное поле либо отключается, либо становится чрезвычайно слабым для экономии энергии после того, как метка была первоначально прочитана. Таким образом, вы не можете постоянно питать пассивные устройства.

Есть ли способ заставить Android-устройство постоянно включаться и читать обновляемый пассивный тег?

NB: я не возражаю, если это связано с рутированием устройства Android, чтобы получить прямой контроль над оборудованием.


person user3095420    schedule 05.05.2016    source источник
comment
Я никогда не наблюдал такого поведения. Можете дать ссылку, где это обсуждается?   -  person Nils Pipenbrinck    schedule 05.05.2016
comment
electronics.stackexchange.com/questions/154402/ Я обновлю эту ссылку в исходном сообщении   -  person user3095420    schedule 05.05.2016


Ответы (2)


То, что вы заявляете в своем вопросе, просто неверно для устройств Android NFC. Как только метка обнаружена (= допустимая метка, которая ответила на все обязательные команды и потенциально может быть отправлена ​​в приложение), считыватель NFC будет непрерывно включать метку (несущая ВЧ остается включенной) и обмениваться с ней некоторыми командами. Команды, которыми обмениваются на этом этапе проверки активности («проверка присутствия»), зависят от типа тега, версии Android и реализации стека Android NFC. Обычно это либо

  1. повторяющиеся циклы деактивации и повторной активации,
  2. многократное чтение определенной области памяти, или
  3. какая-то другая последовательность команд пинг-понга

это позволяет стеку NFC узнать, отвечает ли тег. Только в случае сбоя проверки присутствия Android отключит ВЧ-несущую считывателя NFC и перезапустится либо с полной последовательностью опроса (проверка всех видов поддерживаемых технологий тегов), либо с фазой обнаружения (короткие ВЧ-импульсы несущей для обнаружить расстройку, указывающую на потенциальное присутствие тега).

Таким образом, если ваш тег ведет себя правильно и вашим пользователям удается сохранять тег, прикрепленный к устройству 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();
person Michael Roland    schedule 05.05.2016
comment
Вы правы в том, что то, что я сказал, было на самом деле неверным, я думаю, это случай неправильного вывода, основанного на моем наблюдении. Прочитав ваш ответ, я реализовал код, очень похожий на тот, который вы предоставили, который постоянно опрашивал блок памяти (без задержки) в течение целой минуты. К моему удивлению, Android-телефон действительно продолжал питать устройство. Я ценю вашу помощь и подробное объяснение! - person user3095420; 05.05.2016
comment
хотел бы поделиться своим случаем, я пропустил инструкцию ndef,close(), отсюда и мой вывод: после каждого чтения мы должны закрыть, а затем снова подключиться, чтобы выполнить следующее чтение. - person NotABot; 17.05.2019

Превосходный ответ от Михаила. Но я вижу проблему. Когда микроконтроллер на метке выполняет I2C-чтение энергонезависимой памяти в устройстве NFC, может показаться, что он рискует помешать пингу, выполняемому телефоном.

Я использую телефон Motorola G6 Play с чем-то очень похожим на тег M24LR-DISCOVERY, который имеет M24LR04E-R. [Я воспроизвел результаты для ST25DV.] Метка питается от настольного источника, а НЕ от сбора энергии для этого эксперимента.

Когда тег находится в поле телефона, я вижу активность в логарифме отладчика Android каждые 130 мс или около того.

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 проверяет наличие тега. В это время я вижу, что выход RF_BUSY M24LR становится низким примерно на 15 мс каждые 130 мс или около того. Я связываю это с активностью Android выше.

Если затем микроконтроллер выполняет чтение блока через i2c памяти M24LR, то вскоре после этого телефон воспроизводит звуковой сигнал уведомления. Случилось так, что телефон потерял связь с меткой и снова подключился. Выходные данные 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, чтобы микроконтроллер на метке не запускал какие-либо операции чтения i2c, когда выполнялся RF-доступ, но проблема все еще возникает. Я предполагаю, что проблема связана с пингом RF, когда происходит доступ к памяти, но я только предполагаю.

Кажется, что шансы на разрыв соединения увеличиваются с увеличением количества прочитанных байтов (поддерживая идею конфликта). Чтение одного байта часто может пройти без разрыва соединения.

Может ли это быть действительно правильным поведением? Неужели ничего нельзя сделать, чтобы предотвратить это? Как OP (или я) использовал бы эти устройства для реализации системы, в которой микроконтроллер на метке мог бы читать / записывать память устройства NFC для обмена информацией с приложением, работающим на телефоне? Как я уже сказал, я наблюдал это как с M24LR, так и с ST25DV.

[Извините, если это скорее вопрос, чем ответ, но я хотел пролить больше света на эту тему.]

person Richard    schedule 14.10.2020
comment
Хотя это не упоминалось в моем первоначальном вопросе, я тоже использовал M24LR в том же контексте, что и вы. Мне удалось заставить его работать, изменив код Android, но это было так давно, что я уже не помню точно, как я это сделал :( - person user3095420; 14.10.2020
comment
@user3095420 user3095420 - Мне не удалось найти что-либо на стороне Android, чтобы изменить способ проверки наличия тега. Мне было бы интересно узнать, как. Я решил проблему, изменив способ доступа микроконтроллера к памяти nfc, но это не тот метод, который мне нравится, и он имеет разветвления. Я поражен, что проблема существует. Я просмотрел листы данных и не вижу рекомендуемого метода, позволяющего избежать конфликтов и сделать доступ безопасным. - person Richard; 15.10.2020