Ошибка подключения при чтении тегов Android NfcV

У меня есть приложение для Android, которое считывает теги NFC. На LG Nexus 4 все работает нормально, но на Samsung Galaxy S5 я получаю только исключения ввода-вывода (проверено на нескольких телефонах).

Итак, теги имеют тип NfcV, и я получаю исключение ввода-вывода при вызове connect() на NfcV (далее это код ошибки -5 ERROR_CONNECT).

NFC TagInfo от NXP может считывать содержимое памяти тег на SG5S - есть ли другие способы чтения тегов NfcV, кроме connect() и transceive()?

Какие различия между чипами NFC могут привести к сбою подключения моего приложения на одном телефоне, но не на другом (в то время как другие приложения считывают его нормально)? Может быть, есть тайм-ауты, которые мне нужно настроить?

Фрагмент кода:

NfcV nfcvTag = NfcV.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
if(nfcvTag!=null){
    try {
        nfcvTag.connect();
        //{flags:0x00, read multiple blocks command: 0x23, start at block 0: 0x00, read 9 blocks (0 to 8): 0x08}
        response = nfcvTag.transceive(new byte[] {(byte)0x00,(byte)0x23,(byte)0x00,byte)0x08});
    } catch (IOException e) {
        Log.d("NFCService", nfcvTag.toString());
    } finally {
        try {
            nfcvTag.close();
        } catch (IOException e) {
        }
    }
}

person pfi    schedule 23.05.2014    source источник
comment
Две вещи: (1) Способен ли NFC TagInfo (мой, а не NXP) считывать тег? (2) Как вы получаете намерение NFC в своем приложении (через диспетчеризацию переднего плана или фильтры намерений в манифесте)?   -  person Michael Roland    schedule 23.05.2014
comment
Да, NFC TagInfo также отлично считывает содержимое памяти на SG5S. Я получаю намерения через диспетчеризацию переднего плана.   -  person pfi    schedule 23.05.2014
comment
Делаете ли вы сразу NfcV.get() и nfcv.connect()после получения намерения? Или между ними есть обработка/создание новых потоков и т.д.? Также просто для подтверждения: это метод connect() вызывает исключение, а не метод transceive(), верно?   -  person Michael Roland    schedule 23.05.2014
comment
Я передаю намерение IntentService, который затем выполняет «get ()» и «connect ()», так что да, между ними создается новый поток. И да, «connect ()» выдает исключение, а не «transceive ()».   -  person pfi    schedule 23.05.2014
comment
Хм, странно. Вплоть до подключения это в значительной степени то, что делает NFC TagInfo (за исключением того, что NFC TagInfo вручную создает рабочий поток для обработки тега вместо использования IntentServce).   -  person Michael Roland    schedule 23.05.2014
comment
Наконец-то вернулся к этому. Комментарии заставили меня заподозрить, что IntentService и SGS5, похоже, прекрасно подключаются к тегу при ручном создании потока и выполнении «connect ()» и «transceive ()» в этом потоке. Однако ответ от 'transceive()' теперь всегда представляет собой один и тот же массив байтов ('[2]'), который не соответствует содержимому памяти и не выглядит как код ошибки. Повторюсь, Nexus4 читает теги без проблем. У кого-нибудь есть мысли по этому поводу?   -  person pfi    schedule 06.06.2014
comment
Что именно вы получаете от тега? Не могли бы вы опубликовать это в шестнадцатеричной системе счисления?   -  person Michael Roland    schedule 06.06.2014
comment
Я получаю массив байтов с размером 1 и значением 0x02. Я постоянно получаю один и тот же ответ (от разных тегов) также, когда пытаюсь прочитать один блок, а не чтение нескольких блоков в приведенном выше коде.   -  person pfi    schedule 06.06.2014
comment
Ну, единственная разница между вашим кодом и NFC TagInfo, по-видимому, заключается в том, что NFC TagInfo использует адресованные команды (т.е. адресный набор флагов и включенный UID).   -  person Michael Roland    schedule 06.06.2014
comment
Спасибо @michaelroland. Ваши комментарии точно определили мои проблемы, поэтому при ручной обработке потоков и адресном чтении SGS5 отлично читает теги. Я очень ценю, что вы поделились своим опытом по этому поводу (не стесняйтесь публиковать ответ, кроме). --- Переключение на адресное чтение имеет смысл (другой чип NFC - другой интерфейс), но почему connect() не работает, когда это делается в IntentService, меня озадачивает.   -  person pfi    schedule 11.06.2014


Ответы (1)


Итак, подытожим то, что мы выяснили в ходе обсуждения в комментариях выше:

Кажется, что вы не можете использовать IntentService для обработки доступа к тегу NFC (через полученное намерение обнаружения NFC) в отдельном потоке. В этом случае метод connect() технологического объекта тега не сработает.

Это не означает, что вы не можете обрабатывать доступ к тегу в отдельном (рабочем) потоке. На самом деле вам не следует не обращаться к тегу в основном (UI) потоке, поскольку это заблокирует приложение (и его пользовательский интерфейс) на время доступа к тегу и может привести к тому, что ваше приложение будет уничтожено система за то, что она не отвечает. Ручное создание рабочего потока, который обрабатывает доступ к тегу, работает отлично.

Мои личные и непроверенные идеи/дикие догадки, почему IntentService не смог обработать тег:

  1. Возможно, передача намерения обнаружения NFC в IntentService привела к значительной задержке между обнаружением тега и фактическим доступом к тегу. Во время этой задержки связь с меткой могла прерваться (например, из-за того, что пользователь сместил антенны считывателя и метки, что сделало связь невозможной, и т. д.)
  2. (У меня недостаточно знаний о внутренностях системной службы Android NFC, чтобы знать, возможно ли это вообще :) Возможно, объект Tag каким-то образом связан с объектом Activity. Поскольку IntentService — это другой компонент (хотя он и выполняется в том же контексте приложения), ему может быть запрещен доступ к объекту Tag.

Похоже, что контроллер NFC, используемый в Galaxy S5, поддерживает только адресованные команды чтения ISO/IEC 15693. Использование безадресных команд (т. е. команд, для которых не установлен адресный флаг и которые не содержат UID тега) приводит к тому, что { 0x02 } возвращается из метода transceive().

Трудно сказать, обычно ли это относится к контроллеру NFC (PN547? от NXP) в S5 или это связано с тем, как тег обрабатывает адресованные и неадресованные команды и ответы.

person Michael Roland    schedule 11.06.2014
comment
IntentService — единственная проблема? - person IgorGanapolsky; 24.04.2020