Главная » Разработка для Android » КОММУНИКАЦИЯ БЛИЖНЕГО ПОЛЯ (NFC) в Android приложении

0

 

Коммуникация ближнего поля – это технология близкодействующей (до 20 см), высокочастотной беспроводной коммуникации. Это стандарт, дополняющий более крупный стандарт радиочастотной идентификации (РЧИД), комбинирующий интерфейс смарт-карты и считывателя в единое устройство. Данный стандарт изначально разрабатывался для использования с мобильными телефонами, поэтому он весьма заинтересовал производителей, искавших способы бесконтактной передачи данных (например, при использовании кредитных карточек). Стандарт позволяет использовать коммуникацию ближнего поля несколькими способами.

Эмуляция карты. Устройство – карточка бесконтактного считывания, поэтому с него могут получать информацию другие считыватели.

Режим считывания. Устройство может считывать метки РЧИД (радиочастотная идентификация).

Одноранговый режим. Между двумя устройствами устанавливается прямая и обратная коммуникация для обмена данными.

В Android 2.3 (API уровня 9) Google реализовал функциональность режима считывания при коммуникации ближнего поля. Начиная с Android 2.3.3 (API уровня 10), также появилась возможность записи данных в метку NFC и обмена данными в одноранговом реЖиме (Р2Р).

Метки коммуникации ближнего поля состоят из данных, закодированных в формате для обмена данными при коммуникации ближнего поля (NDEF). Этот формат регламентируется в спецификации NFC Forum Туре 2. Каждое NDEF-сообщение состоит из одной или более записей NDEF Официальная техническая спецификация коммуникации ближнего поля расположена по адресу http:// www.nfc-forum.org/. Для разработки и тестирования считывающего приложения, использующего коммуникацию ближнего поля, настоятельно рекомендуется приобрести NFC-совместимое устройство (например, Nexus S, см. http://www.google.com/ phone/detail/nexus-s) и использовать NFC-совместимую метку.

Для применения функций коммуникации ближнего поля в вашем приложении необходимо объявить в файле описания следующее право доступа:

<uses-permission android:name="android.permission.NFC" />

Чтобы допустить установку приложения только на те устройства, которые поддерживают NFC, добавьте в файл описания и следующую строку:

<uses-feature android:name="android.hardware.rife" />

Считывание метки

Режим считывания предназначен для получения уведомлений при сканировании РЧИД/NFC метки. В Android 2.3 (API уровня 9) единственный способ реализации такой функции – создать активность, которая будет слушать намерения android, nf caction. TAGDISCOVERED, которые широковещательным способом сообщают о том, что в данный момент считывается метка. В Android 2.3.3 (API уровня 10) предоставляются более обширные средства для получения таких уведомлений в соответствии с процессом, показанным на рис. 16.2.

Рис. 16.2. Поток меток коммуникации ближнего поля в Android 2.3.3 (API уровня 10)

В Android 2.3.3 (API уровня 10) и выше при обнаружении метки NFC объект метки (Parcel able) помещается в намерение (Intent) как EXTRATAG. Затем система начинает отслеживать логический поток, чтобы найти активность, которой лучше всего будет направить намерение. Такой механизм разработан для того, чтобы обеспечить высокую вероятность направления метки к подходящей активности без вывода пользователю диалогового окна для выбора активности (то есть сделать это прозрачным образом) и, таким образом, воспрепятствовать обрыву соединения между меткой и устройством. Этот обрыв может быть спровоцирован ненужным вмешательством пользователя. Первое, что необходимо проверить, – узнать, есть ли на переднем плане какая-нибудь активность, которая вызвала метод enableForegroundDispatch(). Если это так, то намерение передается активности и на этом процесс завершается. Если же нет, то система проверяет первую запись NdefRecord в первом NdefMessage данных тега. Если NdefRecord – это уникальный идентификатор ресурса (URI), рассылка Smart Poster или информация о типе МІМЕ, то система проверяет наличие активности, зарегистрированной на получение намерения ACTION_NDEF_ DISCOVERED (android. nfс. action. NDEF_DISCOVERED) с нужным типом данных. Если такое намерение существует, то подходящая для его обработки активность (чем точнее совпадение, тем лучше) получает намерение – и на этом все завершается. Если и эти условия не выполняются, то система ищет активность, зарегистрированную на получение ACTION_TECH_DISCOVERED и подходящую для специфического набора технологий, соответствующего метке (опять же чем точнее совпадение, тем лучше). Если совпадение имеется, то намерение передается такой активности – и решение найдено. Тем не менее, если не найдется активность, которая прошла бы предыдущие проверки, намерение в итоге будет передано как действие ACTION_TAG_DISCOVERED, и именно так происходила бы обработка метки в версии Android 2.3 (API уровня 9).

Чтобы гарантировать, что именно активность, которая находится на переднем плане, была первой в очереди на получение метки, нужно получать адаптер устройства коммуникации ближнего поля и вызвать enabl eForegroundDi spatch со ссылкой на контекст активности. Конкретный адаптер устройства коммуникации ближнего поля представлен классом NfcAdapter. Чтобы получить точный адаптер конкретного устройства, необходимо запустить getDef aul tAdapter() в версии Android 2.3 (API уровня 9) или getDef aul tAdapter (context) в Android 2.3.3 (API уровня 10):

Когда адаптер устройства коммуникации ближнего поля получен, нужно создать намерение Pendinglntent и передать его методу enableForegroundDispatchO. Этот метод должен вызываться из основного потока и только в том случае, если интересующая нас активность находится на переднем плане (после вызова метода

onResume ()):

Исключительно важно то, что, когда активность уходит с переднего плана (при вызове метода onPause()), вы должны вызвать метод disableForegroundDispatchO:

Если активность зарегистрирована на ACTION_NDEF_DISCOVERED, эта активность должна иметь фильтр намерений (intent-fіlter) android. nfс. action. NDEF_DISCOVERED и все фильтры для конкретных (специфичных) данных в файле описания:

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

Когда метка считана, система широковещательным образом передает намерение, причем его информационное наполнение (полезная нагрузка) выступает в качестве ассоциированных данных. В Android 2.3.3 (API уровня 10) здесь также содержится объект Tag (в качестве EXTRA_TAG). Этот объект Tag предоставляет средства для получения конкретной TagTechnology и для выполнения сложных операций (например, ввода-вывода). Необходимо учитывать, что массивы (Array), передаваемые этому классу и возвращаемые им, не клонируются, поэтому будьте осторожны и не модифицируйте их:

В Android 2.3 (API уровня 9) и выше идентификатор (ID) метки заключен внутри намерения и зашифрован строкой android. nf с. extra. ID (NfcAdapter. EXTRA_ID) как массив байтов:

Данные упакованы в виде массива Parcel abl е-объектов (NdefMessage), зашифрованных строкой android.nf с. extra. NDEF MESSAGES (NfcAdapter.EXTRA NDEF MESSAGES):

Внутри каждого сообщения NdefMessage находится массив из NdefRecord. В этой записи всегда будет присутствовать 3-битный TNF (type name format, формат имени типа), тип записи, уникальный идентификатор и полезная нагрузка. Подробнее этот состав рассматривается в документе NdefRecord по адресу http://developer.android. com/reference/android/nfc/NdefRecord.html. В настоящее время известно несколько таких типов, четыре наиболее распространенных из них – TEXT, URI, SMART_POSTER и ABSOLUTEJJRI – мы рассмотрим ниже:

Для считывания полезной нагрузки типа NdefRecord. RTD_TEXT первый байт этой информации определяет статус и соответственно тип кодировки текстовой полезной нагрузки:

При считывании полезной нагрузки стандартного уникального идентификатора ресурса (тип NdefRecord.RTDJJRI) первый байт полезной нагрузки определяет префикс URI:

При указании абсолютного URI (тип NdefRecord. TNF_ABSOLUTE_URI) вся полезная нагрузка имеет кодировку UTF-8 и составляет весь URI:

Особый тип Smart Poster (NdefRecord.RTD_SMART_POSTER) состоит из множества подзаписей текста или данных URI (или абсолютных URI):

Запись в метку

Уже в Android 2.3.3 (API уровня 10) появилась возможность записи данных в метку. Для этого используется объект.Тад, который применяется для получения в метке подходящей TagTechnol оду. Метки коммуникации ближнего поля работают на основе независимо разработанных технологий и предлагают широкий спектр возможностей. Реализации TagTechnol оду обеспечивают доступ к этим различным технологиям и возможностям. В нашем случае технология NDEF требуется для получения и изменения в метке информации NdefRecords и NdefMessage:

При осуществлении операций ввода-вывода с применением TagTechnol оду необходимо соблюдать следующие требования.

Перед использованием любой последующей операции ввода-вывода нужно вызывать метод connect ().

Операции ввода-вывода могут блокироваться, и их никогда не следует вызывать в основном потоке приложения.

Единовременно можно устанавливать соединение только с одной TagTechnol оду. Другие вызовы connect() будут выдавать исключение IOException.

Метод close() следует вызывать после завершения операций ввода-вывода с TagTechnol оду. Этот метод будет отменять все прочие заблокированные операции ввода-вывода в других потоках (в том числе connect ()), выдавая исключение IOException.

Итак, чтобы записать данные в метку, метод connect () вызывается из потока, работающего отдельно от главного потока. Когда это сделано, і sConnected() следует проверить, чтобы убедиться, что соединение установлено. Если оно установлено, то можно вызвать метод writeNdefMessage() с созданным сообщением NdefMessage (содержащим не менее одной записи NdefRecord). После того как данные записаны, вызывается close() для завершения процесса.

Полный код для внесения текстовой записи в метку с использованием ссылки на NDEF TagTechnol оду таков:

Одноранговый режим

Одноранговый режим (peer-to-peer mode, Р2Р) активируется в Android 2.3.3 (API уровня 10), когда одно устройство должно передавать данные другому по технологии коммуникации ближнего поля, причем второе устройство способно принимать данные, получаемые при такой коммуникации. Отправляющее устройство также может получать информацию с принимающего устройства, в этом и заключается одноранговая коммуникация. Для ее осуществления используется метод enabl eFore-groundNdefPush() класса NfcAdapter. В результате активность для передачи сообщения NdefMessage (если она находится на переднем плане) может передать его другому устройству, приспособленному для коммуникации ближнего поля и поддерживающему протокол отправки NDEF com.android.npp. Метод enableForegroundNdefPush() следует вызывать из основного потока (как и в случае с onResume()):

Когда метод enabl eForegroundNdef Push О активен, стандартная диспетчеризация меток отключена. Лишь активность, находящаяся на переднем плане, может получать найденную по метке информацию с помощью метода enabl eForegroundDi spatchC).

Важно отметить, что когда активность уходит с переднего плана (onPauseO), вызывается метод di sabl eForegroundNdefPush():

Источник: Android. Программирование на Java для нового поколения мобильных устройств

По теме:

  • Комментарии