- Android Kotlin — Как читать тег NFC внутри Activity
- 1 ответ
- Разработка NFC приложений для Android
- Архитектура технологии NFC
- Режим эмуляции NFC карты
- Пиринговый режим
- Режим записи/чтения
- Введение в разработку NFC под Android
- Пример 1. Разработка NFC приложения для чтения/записи меток.
- Пример 2. Разработка NFC-приложения, использующего карты MifareClassic
- NFC Tags, NDEF and Android (with Kotlin)
- NFC & NDEF
- Launch Apps with NFC
- Register for NFC Intents
- Receiving NFC Intents
- Intents & Running Android Apps
- Handle Incoming NFC Intents
- Retrieve NDEF Message from the Intent
- Extract Data from the NDEF Message
- Troubleshooting NFC AutoStart
- Check Supported Links of your App
- Chrome Opens All URLs
- Unique Link to your App
- Final NFC / NDEF Reader App
Android Kotlin — Как читать тег NFC внутри Activity
Я нашел здесь несколько недавних сообщений о чтении тегов NFC с Android. Я пришел к выводу, что выполнение действия чтения NFC запускает отдельное намерение.
Я хочу добиться того, чтобы только моим текущим действием было чтение сообщения NDEF из тега NFC в текстовом / простом формате.
Итак, первый вопрос: необходимо ли указывать фильтр намерений в моем манифесте?
Я думаю, что в этом нет необходимости, поскольку я не хочу запускать свое приложение через событие тега NFC, верно?
Второй вопрос: как сохранить логику / функции чтения NFC, связанные с моим приложением / деятельностью?
Я перехожу к своей текущей деятельности и инициализирую адаптер NFC onCreate:
Что будет следующим шагом, чтобы прочитать сообщение NDEF тега nfc? Нашел что-то, связанное с намерением на переднем плане отправки:
Было бы неплохо, если бы у кого-то есть идея / пример (Kotlin), как просто читать тег NFC из действия без таких вещей, как запуск / передача действий NFC.
Например, в iOS при необходимости в VC существует простой сеанс NFC.
1 ответ
Правильно, если вы хотите получать теги только тогда, когда ваш Activity находится на переднем плане, вы можете зарегистрироваться для этого во время выполнения. Вам нужен метод enableForegroundDispatch на NfcAdapter . Вы можете зарегистрировать PendingIntent для определенных типов тегов, по которым вы хотите выполнить фильтрацию, и ваш Activity будет получать Intent в onNewIntent() при обнаружении тега.
Быстрый пример на Kotlin того, как это будет выглядеть, если вы ищете только IsoDep совместимые теги NFC:
Источник
Разработка NFC приложений для Android
Архитектура технологии NFC
NFC основана на RFID технологии с частотой 13.56 МГц и рабочей дистанцией до 10 см. Скорость обмена данными составляет до 424 кб/сек. По сравнению с другими коммуникационными технологиями, основным преимуществом NFC является быстрота и простота использования. На рисунке ниже видно расположение NFC среди других коммуникационных технологий.
Технология NFC имеет три режима: эмуляция NFC-карты, пиринговый режим и режим чтения/записи.
В режиме эмуляции карты NFC представляет собой аналог чипованной RFID карты со своим модулем безопасности, позволяющим защищать процесс покупки. В пиринговом режиме вы можете делиться информацией, например визитной карточкой, с другими NFC устройствами. В также можете устанавливать WiFi или Bluetooth соединения посредством NFC для передачи больших объемов данных. Режим чтения/записи предназначен для чтения или изменения NFC меток с помощью NFC устройств.
Каждый режим более подробно описан ниже.
Режим эмуляции NFC карты
NFC модуль обычно состоит из двух частей: NFC контроллера и элемента безопасности (ЭБ). NFC контроллер отвечает за коммуникации, ЭБ – за шифрацию и дешифрацию чувствительной к взлому информации.
ЭБ подключается к NFC контроллеру посредством шины SWP (Single Wire Protocol) или DCLB (Digital Contactless Bridge). Стандарты NFC определяют логический интерфейс между хостом и контроллером, позволяя им взаимодействовать через RF-поле. ЭБ реализуется с помощью встроенного приложения или компонента ОС.
Существует три варианта реализации ЭБ: можно встроить его в SIM-карту, SD-карту или в NFC чип.
Операторы связи, такие как CMCC (China Mobile Communication Corporation), Vodafone или AT&T обычно используют решение на SIM-карте, поощряя своих абонентов бесплатной заменой старых SIM-карт на новые, оснащенные NFC.
Пиринговый режим
Два NFC устройства могут легко взаимодействовать друг с другом напрямую, обмениваясь небольшими файлами. Для установления Bluetooth/WiFi соединения необходимо обменяться XML файлом специального формата. В этом режиме ЭБ не используется.
Режим записи/чтения
В данном режиме NFC устройство может читать и записывать NFC метки. Хорошим примером применения является чтение информации с оснащенных NFC «умных» постеров.
Введение в разработку NFC под Android
Android поддерживает NFC с помощью двух пакетов: android.nfc и android.nfc.tech.
Основными классами в android.nfc являются:
NfcManager: Устройства под Android могут быть использованы для управления любыми обнаруженными NFC адаптерами, но поскольку большинство Android устройств поддерживают только один NFC адаптер, NfcManager обычно вызывается с getDefaultAdapter для доступа к конкретному адаптеру.
NfcAdapter работает как NFC агент, подобно сетевому адаптеру на ПК. С его помощью телефон получает доступ к аппаратной части NFC для инициализации NFC соединения.
NDEF: Стандарты NFC определяют общий формат данных, называемый NFC Data Exchange Format (NDEF), способный хранить и передавать различные типы объектов, начиная с MIME и заканчивая ультра-короткими RTD-документами, такими как URL. NdefMessage и NdefRecord – два типа NDEF для определенных NFC форумом форматов данных, которые будут использоваться в коде-примере.
Tag: Когда устройство Android обнаруживает пассивный объект типа ярлыка, карты и т.д., он создает объект типа «метка», помещая его далее в целевой объект и в заключении пересылая в соответствующий процесс.
Пакет android.nfc.tech также содержит множество важных подклассов. Эти подклассы обеспечивают доступ к функциям работы с метками, включающими в себя операции чтения и записи. В зависимости от используемого типа технологий, эти классы разбиты на различные категории, такие как NfcA, NfcB, NfcF, MifareClassic и так далее.
Когда телефон со включенным NFC обнаруживает метку, система доставки автоматически создает пакет целевой информации. Если в телефоне имеется несколько приложений, способных работать с этой целевой информаций, пользователю будет показано окно с предложением выбрать одно из списка. Система доставки меток определяет три типа целевой информации, в порядке убывания приоритета: NDEF_DISCOVERED, TECH_DISCOVERED, TAG_DISCOVERED.
Здесь мы используем целевой фильтр для работы со всеми типами информации начиная с TECH_DISCOVERED до ACTION_TECH_DISCOVERED. Файл nfc_tech_filter.xml используется для всех типов, определенных в метке. Подробности можно найти в документации Android. Рисунок ниже показывает схему действий при обнаружении метки.
Пример 1. Разработка NFC приложения для чтения/записи меток.
Следующий пример показывает функции чтения/записи NFC метки. Для того, чтобы получить доступ к аппаратной части NFC и корректно обрабатывать NFC информацию, объявите эти позиции в файле AndroidManifest.xml.
Минимальную версию SDK, которую должно поддерживать ваше приложение — 10, объявите об этом в файле AndroidManifest.xml
Следующий целевой вызов демонстрирует функцию чтения. Если широковещательное сообщение системы равняется NfcAdapter.ACTION_TAG_DISCOVERED, тогда вы можете считать информацию и показать ее.
Следующий код демонстрирует функцию записи. Перед тем, как определить значение mytag, вы должны убедиться, что метка определена и только потом вписать в нее свои данные.
В зависимости от прочитанной информации вы можете выполнить дополнительные действия, такие как запуск какого-либо задания, переход по ссылке и т.д.
Пример 2. Разработка NFC-приложения, использующего карты MifareClassic
В этом примере для чтения мы будем использовать карты MifareClassic и соответствующий им тип метки. Карты MifareClassic широко используются для различных нужд, таких как идентификация человека, автобусный билет и т.д. В традиционной карте MifareClassic область хранения разбита на 16 зон, в каждой зоне 4 блока, и каждый блок может хранить 16 байт данных.
Последний блок в зоне называется трейлером и используется обычно для хранения локального ключа чтения/записи. Он содержит два ключа, А и В, 6 байт длиной каждый, по умолчанию забитые 00 или FF, в зависимости от значения MifareClassic.KEY_DEFAULT.
Для записи на карту Mifare вы, прежде всего, должны иметь корректное значение ключа (что играет защитную роль), а также успешно пройти аутентификацию.
Пример того, как читать карту MifareClassic:
Источник
NFC Tags, NDEF and Android (with Kotlin)
By andijakl
Post date
In this article, you will learn how to add NFC tag reading to an Android app. It registers for auto-starting when the user taps a specific NDEF NFC tag with the phone. In addition, the app reads the NDEF records from the tag.
NFC & NDEF
Apple added support for reading NFC tags with iOS 11 in September 2017. All iPhones starting with the iPhone 7 offer an API to read NFC tags. While Android included NFC support for many years, this was the final missing piece to bring NFC tag scenarios to the masses.
A quick recap of NFC:
- Short-range wireless communication technology: NFC instantly transmits data over nfcAdapter is null, the phone doesn’t have NFC support. Only if nfcAdapter.isEnabled returns true, we’re ready to go!
Launch Apps with NFC
Ultimately, we want to achieve the following: when the user taps our NFC tag, our app should launch and show the contents of the tag.
For launching our app, we use a deep link. In the Manifest, we register the URL of our website (or a specific sub-page of it). This has an important advantage: if the app is not yet installed, you show generic information on a website. That way, you’re always in control of the user experience. Place a link to the app store on that web page to “upgrade” the user.
Additionally, this method is fully compatible with the iPhone, which doesn’t support launching apps through NFC tags.
By default, Android shows a user consent dialog before launching your app. To bypass this, place a special JSON file on your web server. Read more in the Android Documentation about App Links.
Register for NFC Intents
Next, we register our app with Android. We want the app to be launched whenever a specific NDEF record is found on a tag. Add this intent filter to the Activity in your manifest:
Let’s take a closer look at the intent filter:
- When using NDEF formatted tags, it’s easiest to use the android.nfc.action.NDEF_DISCOVERED intent.
- Every intent filter requires a category. Supply at least the android.intent.category.DEFAULT category.
Android doesn’t allow generic subscriptions to all NDEF messages. Instead, we supply more information on the specific NDEF message we’re interested in. This is done through data elements.
Supply at least the scheme and host of your website. To make your filter more generic, it’s a good idea to filter for both https and http. The Android documentation has more information about linking to multiple hosts or subdomains.
Receiving NFC Intents
Now, we have the permission to use NFC. Additionally, we told Android when to launch our application. How do we find out more about the NFC tag contents?
For example: in a museum use case where each exhibit has its own tag, you’d extract the unique part of the URL. Using the item name or ID found in the URL, you show the relevant information in the app.
We’re interested in two properties of the intent:
- Action: the relevant intent has the action NfcAdapter.ACTION_NDEF_DISCOVERED
- Data: the raw contents of the NDEF message are contained in the parcelable array extra called NfcAdapter.EXTRA_NDEF_MESSAGES
Intents & Running Android Apps
How does Android deliver the intent to our app?
- onCreate(): If our app is launched through the NFC tag, Android creates a new instance of our activity. We retrieve the NDEF data through the Activity’s intent property.
- onNewIntent(): What happens if our activity is already open? By default, Android starts a new activity instance. To prevent this behavior, set the launchMode to singleTop in the manifest. Then, or existing activity gets the intent through onNewIntent() – it’s no longer re-started.
Handle Incoming NFC Intents
No matter which way the intent takes to reach our app, it’s a good idea to centralize handling it. Create a new function called processIntent() and call it from both entry points:
In onCreate(), we take the intent property of the activity (getIntent() in Java). In onNewIntent(), we use the intent parameter.
Retrieve NDEF Message from the Intent
In our custom processIntent() function, we finally investigate the NFC tag contents. The following snippet checks the intent type and extracts the raw NDEF message array:
Test the app on your phone and place a breakpoint after extracting the NDEF message. Tap your NFC tag.
You can see that the message contains a single record. Most important is its payload: a byte array.
In the image above, the first byte is 0x02. Writable space is scarce on NFC tags. The most common URI schemes are abbreviated into a single byte, based on a standardized list. 0x02 means “https://www.”. Instead of 12 bytes, you only need 1 byte. If your whole tag only has 48 bytes of storage memory, that’s a big difference. Check the complete list or URI schemes in the NDEF library.
The remaining bytes are direct ASCII codes of the URL written to the NFC tag. The URL inside the record is UTF-8 encoded.
Extract Data from the NDEF Message
All the data we need is visible in the screenshot of the inspector window above. Let’s write the code to extract the URL.
Note: the following code emits error handling for clarity. The complete solution on GitHub includes checks for ranges and null.
- Extract the 1st NDEF message: as mentioned before, most NDEF tags only have one message. We simply take the first:
- Get the 1st record of the message: Android already parsed the message contents into an array of records. Again, we’re interested in the first record:
- Extract information: Android has a built-in function to parse URIs. So, you don’t need to worry about the efficient byte-encoding described before. For all other record types, we log the raw payload.
Congratulations, that’s it! Your app is fully functional. It starts through NFC tags and parses & logs the NDEF contents.
Troubleshooting NFC AutoStart
If your app doesn’t start when tapping the NFC tag, the following hints might help:
Check Supported Links of your App
Through the Android settings, open the properties of your app. Check if the link you registered for is listed in “Supported Links”. The screenshot shows the app registered for “www.andreasjakl.com”:
In case the URL is missing, double-check your manifest. Re-build and re-install the complete app to make sure Android recognizes the intent filter.
Chrome Opens All URLs
In case you allowed a browser like Chrome – or any other app – to open all incoming URLs from NFC tags, Android might no longer prompt to open our own app.
To clear the defaults, go to the properties of the current default app. In Android 8, this action isn’t easy to find; here the steps for Chrome:
- Settings > Apps & notifications > Advanced > Default apps > Opening links > Chrome > Other defaults: clear defaults
Unique Link to your App
To ensure no other app hijacks your URLs, Android offers another option: the Android Application Record (AAR). In addition to the URL record, you add a second record to the NDEF message. It contains the package name of your app.
Android will then always launch your app when it discovers a tag that includes the AAR. In case your app isn’t installed yet, it will open the Google Play Store.
You can easily include an AAR with the NXP TagWriter. Activate the “Add launch application” option when writing your tag:
Even with an additional AAR, your app still launches the same way. You get the NDEF message through the intent as described before. Therefore, it’s always a good idea to add an Android Application Record to your NFC tag if you want a unique association with your app.
Final NFC / NDEF Reader App
I’ve further polished the final app. Download the extended solution from this article from GitHub.
In addition to subscribing for NDEF messages through the manifest, the project also implements foreground dispatch. The app gets & analyzes all NDEF messages when it’s running in the foreground.
The following process is visualized in the NFC app solution screenshot:
- App is launched through NFC (NDEF_DISCOVERED in onCreate()).
- NDEF message contains 2 records: URL + Android Application Record
- While running: tapped 2nd NFC tag with different (non-subscribed) URL
- Delivered & parsed through onNewIntent() thanks to active Foreground Dispatch which subscribed to all NDEF tags.
Источник