В этом документе описаны основные задачи NFC, которые вы выполняете в Android. В нем объясняется, как отправлять и получать данные NFC в форме сообщений NDEF, и описываются API-интерфейсы платформы Android, которые поддерживают эти функции. Более сложные темы, включая обсуждение работы с данными, не относящимися к NDEF, см. в разделе Advanced NFC .
Чтение данных NDEF из тега NFC обрабатывается системой диспетчеризации тегов , которая анализирует обнаруженные теги NFC, соответствующим образом классифицирует данные и запускает приложение, заинтересованное в классифицированных данных. Приложение, которое хочет обрабатывать отсканированную метку NFC, может объявить фильтр намерений и запросить обработку данных.
Система отправки тегов
Устройства на базе Android обычно ищут метки NFC, когда экран разблокирован, если только NFC не отключен в меню настроек устройства. Когда устройство под управлением Android обнаруживает метку NFC, желательно, чтобы наиболее подходящее действие обрабатывало намерение, не спрашивая пользователя, какое приложение использовать. Поскольку устройства сканируют метки NFC на очень небольшом расстоянии, вполне вероятно, что если пользователям придется выбирать действие вручную, им придется отодвинуть устройство от метки и разорвать соединение. Вам следует разработать свою деятельность так, чтобы она обрабатывала только те NFC-теги, которые важны для вашей деятельности, чтобы предотвратить появление средства выбора активности.
Чтобы помочь вам в достижении этой цели, Android предоставляет специальную систему отправки тегов, которая анализирует отсканированные теги NFC, анализирует их и пытается найти приложения, которым интересны отсканированные данные. Это делается путем:
- Анализ тега NFC и определение типа MIME или URI, который идентифицирует полезные данные в теге.
- Инкапсуляция типа MIME или URI и полезных данных в намерение. Эти первые два шага описаны в разделе «Как теги NFC сопоставляются с типами MIME и URI» .
- Запускает действие на основе намерения. Это описано в разделе «Как теги NFC отправляются в приложения» .
Как теги NFC сопоставляются с типами MIME и URI
Прежде чем приступить к написанию приложений NFC, важно понять различные типы тегов NFC, как система отправки тегов анализирует теги NFC и какую специальную работу выполняет система отправки тегов при обнаружении сообщения NDEF. Теги NFC используют широкий спектр технологий, и в них также могут быть записаны данные разными способами. Android имеет наибольшую поддержку стандарта NDEF, определенного NFC Forum .
Данные NDEF инкапсулируются внутри сообщения ( NdefMessage
), которое содержит одну или несколько записей ( NdefRecord
). Каждая запись NDEF должна иметь правильный формат в соответствии со спецификацией типа записи, которую вы хотите создать. Android также поддерживает другие типы тегов, не содержащие данных NDEF, с которыми вы можете работать, используя классы в пакете android.nfc.tech
. Дополнительные сведения об этих технологиях см. в разделе «Расширенный NFC» . Работа с другими типами тегов предполагает написание собственного стека протоколов для взаимодействия с тегами, поэтому мы рекомендуем по возможности использовать NDEF для упрощения разработки и максимальной поддержки устройств на базе Android.
Примечание. Чтобы загрузить полные спецификации NDEF, перейдите на сайт «Спецификации и документы приложений NFC Forum» и ознакомьтесь с примерами создания записей NDEF в разделе «Создание общих типов записей NDEF».
Теперь, когда вы имеете некоторый опыт работы с тегами NFC, в следующих разделах более подробно описывается, как Android обрабатывает теги в формате NDEF. Когда устройство под управлением Android сканирует тег NFC, содержащий данные в формате NDEF, оно анализирует сообщение и пытается определить тип MIME данных или идентифицирующий URI. Для этого система считывает первую NdefRecord
внутри NdefMessage
, чтобы определить, как интерпретировать все сообщение NDEF (сообщение NDEF может иметь несколько записей NDEF). В правильно сформированном сообщении NDEF первая NdefRecord
содержит следующие поля:
- 3-битный TNF (формат имени типа)
- Указывает, как интерпретировать поле типа переменной длины. Допустимые значения описаны в Таблице 1 .
- Тип переменной длины
- Описывает тип записи. При использовании
TNF_WELL_KNOWN
используйте это поле для указания определения типа записи (RTD). Допустимые значения RTD описаны в Таблице 2 . - Идентификатор переменной длины
- Уникальный идентификатор записи. Это поле используется нечасто, но если вам нужно однозначно идентифицировать тег, вы можете создать для него идентификатор.
- Полезная нагрузка переменной длины
- Фактические полезные данные, которые вы хотите прочитать или записать. Сообщение NDEF может содержать несколько записей NDEF, поэтому не предполагайте, что вся полезная нагрузка находится в первой записи NDEF сообщения NDEF.
Система отправки тегов использует поля TNF и type, чтобы попытаться сопоставить тип MIME или URI с сообщением NDEF. В случае успеха он инкапсулирует эту информацию внутри намерения ACTION_NDEF_DISCOVERED
вместе с фактической полезной нагрузкой. Однако бывают случаи, когда система диспетчеризации тегов не может определить тип данных на основе первой записи NDEF. Это происходит, когда данные NDEF не могут быть сопоставлены с типом MIME или URI или когда тег NFC изначально не содержит данных NDEF. В таких случаях объект Tag
, содержащий информацию о технологиях тега и полезной нагрузке, вместо этого инкапсулируется внутри намерения ACTION_TECH_DISCOVERED
.
В таблице 1 описано, как система диспетчеризации тегов сопоставляет поля TNF и типа с типами MIME или URI. Он также описывает, какие TNF нельзя сопоставить с типом MIME или URI. В этих случаях система отправки тегов возвращается к ACTION_TECH_DISCOVERED
.
Например, если система диспетчеризации тегов обнаруживает запись типа TNF_ABSOLUTE_URI
, она сопоставляет поле типа переменной длины этой записи с URI. Система отправки тегов инкапсулирует этот URI в поле данных намерения ACTION_NDEF_DISCOVERED
вместе с другой информацией о теге, например полезной нагрузкой. С другой стороны, если он встречает запись типа TNF_UNKNOWN
, он вместо этого создает намерение, которое инкапсулирует технологии тега.
Тип Формат имени (TNF) | Картирование |
---|---|
TNF_ABSOLUTE_URI | URI на основе поля типа. | TNF_EMPTY | Возвращается к ACTION_TECH_DISCOVERED . | TNF_EXTERNAL_TYPE | URI на основе URN в поле типа. URN кодируется в поле типа NDEF в сокращенной форме: <domain_name>:<service_name> . Android сопоставляет это с URI в форме: vnd.android.nfc://ext/ <domain_name>:<service_name> . | TNF_MIME_MEDIA | Тип MIME на основе поля типа. | TNF_UNCHANGED | Недопустимо в первой записи, поэтому возвращается к ACTION_TECH_DISCOVERED . | TNF_UNKNOWN | Возвращается к ACTION_TECH_DISCOVERED . | TNF_WELL_KNOWN | Тип MIME или URI в зависимости от определения типа записи (RTD), которое вы установили в поле типа. См. Таблицу 2 для получения дополнительной информации о доступных RTD и их сопоставлениях. |
Определение типа записи (RTD) | Картирование |
---|---|
RTD_ALTERNATIVE_CARRIER | Возвращается к ACTION_TECH_DISCOVERED . | RTD_HANDOVER_CARRIER | Возвращается к ACTION_TECH_DISCOVERED . | RTD_HANDOVER_REQUEST | Возвращается к ACTION_TECH_DISCOVERED . | RTD_HANDOVER_SELECT | Возвращается к ACTION_TECH_DISCOVERED . | RTD_SMART_POSTER | URI на основе анализа полезной нагрузки. | RTD_TEXT | MIME-тип text/plain . | RTD_URI | URI на основе полезной нагрузки. |
Как теги NFC передаются приложениям
Когда система диспетчеризации тегов завершает создание намерения, которое инкапсулирует тег NFC и его идентификационную информацию, она отправляет намерение заинтересованному приложению, которое фильтрует это намерение. Если с намерением могут справиться несколько приложений, отображается окно выбора действия, позволяющее пользователю выбрать действие. Система отправки тегов определяет три намерения, которые перечислены в порядке от высшего к низшему приоритету:
-
ACTION_NDEF_DISCOVERED
: это намерение используется для запуска действия, когда тег, содержащий полезную нагрузку NDEF, сканируется и имеет распознанный тип. Это намерение с наивысшим приоритетом, и система отправки тегов пытается запустить действие с этим намерением раньше, чем с любым другим намерением, когда это возможно. -
ACTION_TECH_DISCOVERED
: если не зарегистрировано никаких действий для обработки намеренияACTION_NDEF_DISCOVERED
, система диспетчеризации тегов пытается запустить приложение с этим намерением. Это намерение также запускается напрямую (без предварительного запускаACTION_NDEF_DISCOVERED
), если сканируемый тег содержит данные NDEF, которые невозможно сопоставить с типом MIME или URI, или если тег не содержит данных NDEF, но относится к известной технологии тегов. -
ACTION_TAG_DISCOVERED
: это намерение запускается, если никакие действия не обрабатывают намеренияACTION_NDEF_DISCOVERED
илиACTION_TECH_DISCOVERED
.
Основной принцип работы системы отправки тегов заключается в следующем:
- Попробуйте запустить Activity с намерением, которое было создано системой диспетчеризации тегов при разборе тега NFC (либо
ACTION_NDEF_DISCOVERED
, либоACTION_TECH_DISCOVERED
). - Если никакие действия не фильтруются для этого намерения, попробуйте запустить действие со следующим намерением с наименьшим приоритетом (
ACTION_TECH_DISCOVERED
илиACTION_TAG_DISCOVERED
), пока приложение не отфильтрует намерение или пока система отправки тегов не перепробует все возможные намерения. - Если ни одно из приложений не фильтрует ни одно из намерений, ничего не делайте.
По возможности работайте с сообщениями NDEF и намерением ACTION_NDEF_DISCOVERED
, поскольку оно является наиболее конкретным из трех. Это намерение позволяет вам запустить приложение в более подходящее время, чем два других намерения, предоставляя пользователю лучший опыт.
Запросить доступ NFC в манифесте Android
Прежде чем вы сможете получить доступ к оборудованию NFC устройства и правильно обработать намерения NFC, объявите эти элементы в файле AndroidManifest.xml
:
- Элемент NFC
<uses-permission>
для доступа к оборудованию NFC:<uses-permission android:name="android.permission.NFC" />
- Минимальная версия SDK, которую может поддерживать ваше приложение. Уровень API 9 поддерживает только ограниченную отправку тегов через
ACTION_TAG_DISCOVERED
и предоставляет доступ к сообщениям NDEF только через дополнительную опциюEXTRA_NDEF_MESSAGES
. Никакие другие свойства тега или операции ввода-вывода недоступны. Уровень API 10 включает в себя комплексную поддержку чтения и записи, а также активную отправку NDEF, а уровень API 14 предоставляет дополнительные удобные методы для создания записей NDEF.<uses-sdk android:minSdkVersion="10"/>
- Элемент
uses-feature
, чтобы ваше приложение отображалось в Google Play только для устройств, оснащенных оборудованием NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Если ваше приложение использует функциональность NFC, но эта функциональность не имеет решающего значения для вашего приложения, вы можете опустить элемент
uses-feature
и проверить доступность NFC во время выполнения, проверив, имеет лиgetDefaultAdapter()
значениеnull
.
Фильтр по намерениям NFC
Чтобы запустить приложение при сканировании тега NFC, который вы хотите обработать, ваше приложение может фильтровать одно, два или все три намерения NFC в манифесте Android. Однако обычно вам нужно фильтровать намерение ACTION_NDEF_DISCOVERED
, чтобы максимально контролировать время запуска вашего приложения. Намерение ACTION_TECH_DISCOVERED
является запасным вариантом для ACTION_NDEF_DISCOVERED
когда никакие приложения не фильтруют ACTION_NDEF_DISCOVERED
или когда полезные данные не являются NDEF. Фильтрация для ACTION_TAG_DISCOVERED
обычно является слишком общей категорией, чтобы ее можно было фильтровать. Многие приложения будут фильтровать ACTION_NDEF_DISCOVERED
или ACTION_TECH_DISCOVERED
перед ACTION_TAG_DISCOVERED
, поэтому вероятность запуска вашего приложения мала. ACTION_TAG_DISCOVERED
доступен только в крайнем случае для приложений, подлежащих фильтрации, в тех случаях, когда не установлены другие приложения для обработки намерения ACTION_NDEF_DISCOVERED
или ACTION_TECH_DISCOVERED
.
Поскольку развертывание тегов NFC различается и во многих случаях находится вне вашего контроля, это не всегда возможно, поэтому при необходимости вы можете вернуться к двум другим намерениям. Если у вас есть контроль над типами записываемых тегов и данных, рекомендуется использовать NDEF для форматирования тегов. В следующих разделах описывается, как фильтровать каждый тип намерения.
ACTION_NDEF_DISCOVERED
Чтобы фильтровать намерения ACTION_NDEF_DISCOVERED
, объявите фильтр намерений вместе с типом данных, которые вы хотите фильтровать. В следующем примере фильтруются намерения ACTION_NDEF_DISCOVERED
с помощью MIME-типа text/plain
:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain" /> </intent-filter>
В следующем примере фильтруется URI в форме https://developer.android.com/index.html
.
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
ACTION_TECH_DISCOVERED
Если ваша деятельность фильтрует намерение ACTION_TECH_DISCOVERED
, вы должны создать файл ресурсов XML, в котором указаны технологии, которые поддерживает ваша деятельность, в наборе tech-list
. Ваша деятельность считается совпадением, если набор tech-list
является подмножеством технологий, поддерживаемых тегом, который вы можете получить, вызвав getTechList()
.
Например, если сканируемый тег поддерживает MifareClassic, NdefFormatable и NfcA, в вашем наборе tech-list
должны быть указаны все три, две или одна технология (и ничего больше), чтобы ваша деятельность была сопоставлена.
В следующем примере определяются все технологии. Вы должны удалить те, которые не поддерживаются вашим тегом NFC. Сохраните этот файл (вы можете назвать его как угодно) в папке <project-root>/res/xml
.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech> <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
Вы также можете указать несколько наборов tech-list
. Каждый из наборов tech-list
рассматривается независимо, и ваша деятельность считается совпадением, если какой-либо отдельный набор tech-list
является подмножеством технологий, возвращаемых getTechList()
. Это обеспечивает семантику AND
и OR
для сопоставления технологий. Следующий пример соответствует тегам, которые могут поддерживать технологии NfcA и Ndef или технологии NfcB и Ndef:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.NfcA</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.Ndef</tech> </tech-list> </resources>
В файле AndroidManifest.xml
укажите только что созданный файл ресурсов в элементе <meta-data>
внутри элемента <activity>
, как показано в следующем примере:
<activity> ... <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> ... </activity>
Дополнительные сведения о работе с технологиями тегов и намерении ACTION_TECH_DISCOVERED
см. в разделе «Работа с поддерживаемыми технологиями тегов» в документе Advanced NFC.
ACTION_TAG_DISCOVERED
Чтобы отфильтровать ACTION_TAG_DISCOVERED
используйте следующий фильтр намерений:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Получить информацию из намерений
Если действие начинается из-за намерения NFC, вы можете получить информацию о отсканированной метке NFC из намерения. В зависимости от сканируемого тега намерения могут содержать следующие дополнительные элементы:
-
EXTRA_TAG
(обязательно): объектTag
представляющий сканируемый тег. -
EXTRA_NDEF_MESSAGES
(необязательно): массив сообщений NDEF, проанализированных из тега. Это дополнение является обязательным для целейACTION_NDEF_DISCOVERED
. -
EXTRA_ID
(необязательно): низкоуровневый идентификатор тега.
Чтобы получить эти дополнительные возможности, проверьте, было ли ваше действие запущено с одним из намерений NFC, чтобы убедиться, что тег был отсканирован, а затем получите дополнительные возможности из намерения. В следующем примере проверяется намерение ACTION_NDEF_DISCOVERED
и получаются сообщения NDEF из дополнительного намерения.
Котлин
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) ... if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages -> val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage } // Process the messages array. ... } } }
Ява
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); ... if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages != null) { NdefMessage[] messages = new NdefMessage[rawMessages.length]; for (int i = 0; i < rawMessages.length; i++) { messages[i] = (NdefMessage) rawMessages[i]; } // Process the messages array. ... } } }
Альтернативно вы можете получить объект Tag
из намерения, который будет содержать полезную нагрузку и позволит вам перечислить технологии тега:
Котлин
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Ява
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Создание общих типов записей NDEF.
В этом разделе описывается, как создавать общие типы записей NDEF, которые помогут вам при записи в теги NFC. Начиная с Android 4.0 (уровень API 14), доступен метод createUri()
, который помогает автоматически создавать записи URI. Начиная с Android 4.1 (уровень API 16), доступны createExternal()
и createMime()
, которые помогут вам создавать записи MIME и NDEF внешнего типа. По возможности используйте эти вспомогательные методы, чтобы избежать ошибок при создании записей NDEF вручную.
В этом разделе также описывается, как создать соответствующий фильтр намерений для записи. Все эти примеры записей NDEF должны находиться в первой записи NDEF сообщения NDEF, которое вы записываете в тег.
TNF_ABSOLUTE_URI
Примечание. Мы рекомендуем использовать тип RTD_URI
вместо TNF_ABSOLUTE_URI
, поскольку он более эффективен.
Вы можете создать запись TNF_ABSOLUTE_URI
NDEF следующим образом:
Котлин
val uriRecord = ByteArray(0).let { emptyByteArray -> NdefRecord( TNF_ABSOLUTE_URI, "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")), emptyByteArray, emptyByteArray ) }
Ява
NdefRecord uriRecord = new NdefRecord( NdefRecord.TNF_ABSOLUTE_URI , "https://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")), new byte[0], new byte[0]);
Фильтр намерений для предыдущей записи NDEF будет выглядеть следующим образом:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
TNF_MIME_MEDIA
Запись TNF_MIME_MEDIA
NDEF можно создать следующими способами:
Используя метод createMime()
:
Котлин
val mimeRecord = NdefRecord.createMime( "application/vnd.com.example.android.beam", "Beam me up, Android".toByteArray(Charset.forName("US-ASCII")) )
Ява
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
Создание NdefRecord
вручную:
Котлин
val mimeRecord = Charset.forName("US-ASCII").let { usAscii -> NdefRecord( NdefRecord.TNF_MIME_MEDIA, "application/vnd.com.example.android.beam".toByteArray(usAscii), ByteArray(0), "Beam me up, Android!".toByteArray(usAscii) ) }
Ява
NdefRecord mimeRecord = new NdefRecord( NdefRecord.TNF_MIME_MEDIA , "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
Фильтр намерений для предыдущей записи NDEF будет выглядеть следующим образом:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.com.example.android.beam" /> </intent-filter>
TNF_WELL_KNOWN с RTD_TEXT
Вы можете создать запись TNF_WELL_KNOWN
NDEF следующим образом:
Котлин
fun createTextRecord(payload: String, locale: Locale, encodeInUtf8: Boolean): NdefRecord { val langBytes = locale.language.toByteArray(Charset.forName("US-ASCII")) val utfEncoding = if (encodeInUtf8) Charset.forName("UTF-8") else Charset.forName("UTF-16") val textBytes = payload.toByteArray(utfEncoding) val utfBit: Int = if (encodeInUtf8) 0 else 1 shl 7 val status = (utfBit + langBytes.size).toChar() val data = ByteArray(1 + langBytes.size + textBytes.size) data[0] = status.toByte() System.arraycopy(langBytes, 0, data, 1, langBytes.size) System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size) return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), data) }
Ява
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) { byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII")); Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16"); byte[] textBytes = payload.getBytes(utfEncoding); int utfBit = encodeInUtf8 ? 0 : (1 << 7); char status = (char) (utfBit + langBytes.length); byte[] data = new byte[1 + langBytes.length + textBytes.length]; data[0] = (byte) status; System.arraycopy(langBytes, 0, data, 1, langBytes.length); System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length); NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data); return record; }
Фильтр намерений для предыдущей записи NDEF будет выглядеть следующим образом:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
TNF_WELL_KNOWN с RTD_URI
Запись TNF_WELL_KNOWN
NDEF можно создать следующими способами:
Используя метод createUri(String)
:
Котлин
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Ява
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Используя метод createUri(Uri)
:
Котлин
val rtdUriRecord2 = Uri.parse("https://example.com").let { uri -> NdefRecord.createUri(uri) }
Ява
Uri uri = Uri.parse("https://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
Создание NdefRecord
вручную:
Котлин
val uriField = "example.com".toByteArray(Charset.forName("US-ASCII")) val payload = ByteArray(uriField.size + 1) //add 1 for the URI Prefix payload [0] = 0x01 //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.size) //appends URI to payload val rtdUriRecord = NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, ByteArray(0), payload)
Ява
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII")); byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix payload[0] = 0x01; //prefixes https://www. to the URI System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload NdefRecord rtdUriRecord = new NdefRecord( NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
Фильтр намерений для предыдущей записи NDEF будет выглядеть следующим образом:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="https" android:host="example.com" android:pathPrefix="" /> </intent-filter>
TNF_EXTERNAL_TYPE
Запись TNF_EXTERNAL_TYPE
NDEF можно создать следующими способами:
Используя метод createExternal()
:
Котлин
var payload: ByteArray //assign to your data val domain = "com.example" //usually your app's package name val type = "externalType" val extRecord = NdefRecord.createExternal(domain, type, payload)
Ява
byte[] payload; //assign to your data String domain = "com.example"; //usually your app's package name String type = "externalType"; NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
Создание NdefRecord
вручную:
Котлин
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Ява
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
Фильтр намерений для предыдущей записи NDEF будет выглядеть следующим образом:
<intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="vnd.android.nfc" android:host="ext" android:pathPrefix="/com.example:externalType"/> </intent-filter>
Используйте TNF_EXTERNAL_TYPE
для более общего развертывания тегов NFC, чтобы лучше поддерживать устройства как под управлением Android, так и без него.
Примечание . URN для TNF_EXTERNAL_TYPE
имеют канонический формат: urn:nfc:ext:example.com:externalType
, однако спецификация NFC Forum RTD заявляет, что urn:nfc:ext:
URN должна быть исключена из записи NDEF. Поэтому все, что вам нужно указать, — это домен ( example.com
в примере) и тип ( externalType
в примере), разделенные двоеточием. При отправке TNF_EXTERNAL_TYPE
Android преобразует URN urn:nfc:ext:example.com:externalType
в URI vnd.android.nfc://ext/example.com:externalType
, который и объявляет фильтр намерений в примере.
Записи приложений Android
Запись приложения Android (AAR), представленная в Android 4.0 (уровень API 14), обеспечивает большую уверенность в том, что ваше приложение запускается при сканировании метки NFC. AAR содержит имя пакета приложения, встроенное в запись NDEF. Вы можете добавить AAR к любой записи NDEF вашего сообщения NDEF, поскольку Android ищет AAR во всем сообщении NDEF. Если он находит AAR, он запускает приложение на основе имени пакета внутри AAR. Если приложение отсутствует на устройстве, запускается Google Play для его загрузки.
AAR полезны, если вы хотите запретить другим приложениям фильтровать те же цели и потенциально обрабатывать определенные развернутые вами теги. AAR поддерживаются только на уровне приложения из-за ограничения имени пакета, а не на уровне активности, как при фильтрации намерений. Если вы хотите обработать намерение на уровне активности, используйте фильтры намерений .
Если тег содержит AAR, система отправки тегов осуществляет отправку следующим образом:
- Попробуйте запустить действие, используя фильтр намерений, как обычно. Если действие, соответствующее намерению, также соответствует AAR, запустите действие.
- Если действие, которое фильтрует намерение, не соответствует AAR, если несколько действий могут обработать намерение или если ни одно действие не обрабатывает намерение, запустите приложение, указанное в AAR.
- Если ни одно приложение не может запуститься с AAR, перейдите в Google Play, чтобы загрузить приложение на основе AAR.
Примечание. Вы можете переопределить AAR и систему отправки намерений с помощью системы отправки на переднем плане , которая позволяет активности на переднем плане иметь приоритет при обнаружении тега NFC. При использовании этого метода действие должно находиться на переднем плане, чтобы переопределить AAR и систему диспетчеризации намерений.
Если вы по-прежнему хотите фильтровать сканированные теги, не содержащие AAR, вы можете объявить фильтры намерений обычными. Это полезно, если ваше приложение заинтересовано в других тегах, не содержащих AAR. Например, возможно, вы хотите гарантировать, что ваше приложение обрабатывает собственные теги, которые вы развертываете, а также общие теги, развернутые третьими сторонами. Имейте в виду, что AAR специфичны для устройств Android 4.0 или более поздних версий, поэтому при развертывании тегов вы, скорее всего, захотите использовать комбинацию AAR и типов/URI MIME для поддержки самого широкого спектра устройств. Кроме того, при развертывании тегов NFC подумайте, как вы хотите записать теги NFC, чтобы обеспечить поддержку большинства устройств (под управлением Android и других устройств). Это можно сделать, определив относительно уникальный тип MIME или URI, чтобы приложениям было легче их различать.
Android предоставляет простой API для создания AAR — createApplicationRecord()
. Все, что вам нужно сделать, это встроить AAR в любое место вашего NdefMessage
. Вы не хотите использовать первую запись вашего NdefMessage
, если только AAR не является единственной записью в NdefMessage
. Это связано с тем, что система Android проверяет первую запись NdefMessage
чтобы определить тип MIME или URI тега, который используется для создания намерения приложений фильтровать. Следующий код показывает, как создать AAR:
Котлин
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Ява
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )