Ten dokument zawiera opis podstawowych zadań dotyczących NFC, które możesz wykonywać na urządzeniu z Androidem. Przewodnik ten wyjaśnia, jak wysyłać i odbierać dane NFC w postaci komunikatów NDEF, oraz opisuje interfejsy API frameworka Androida, które obsługują te funkcje. Bardziej zaawansowane tematy, w tym omówienie pracy z danymi innymi niż NDEF, znajdziesz w artykule Zaawansowane funkcje NFC.
Odczyt danych NDEF z tagu NFC jest obsługiwany przez system wysyłki tagów, który analizuje wykryte tagi NFC, odpowiednio kategoryzuje dane i uruchamia aplikację zainteresowaną danymi skategoryzowanymi. Aplikacja, która chce obsłużyć zeskanowany tag NFC, może zadeklarować filtr intencji i poprosić o obsługę danych.
System wysyłania tagów
Urządzenia z Androidem zwykle szukają tagów NFC, gdy ekran jest odblokowany, chyba że komunikacja NFC jest wyłączona w menu ustawień urządzenia. Gdy urządzenie z Androidem wykryje tag NFC, pożądane działanie polega na tym, aby najbardziej odpowiednia aktywność obsłużyła intencję bez pytania użytkownika, której aplikacji użyć. Urządzenia skanują tagi NFC w bardzo krótkim zasięgu, więc prawdopodobnie wymuszenie ręcznego wybierania przez użytkowników aktywności spowoduje, że odsuną one urządzenie od tagu i przerwą połączenie. Aby zapobiec wyświetlaniu okna wyboru aktywności, należy tak zaprogramować swoją aktywność, aby obsługiwała tylko te tagi NFC, które są dla niej istotne.
Aby Ci to ułatwić, Android udostępnia specjalny system obsługi tagów, który analizuje zeskanowane tagi NFC, interpretuje je i próbuje zlokalizować aplikacje zainteresowane zeskanowanymi danymi. Dokonuje tego,
- Przetwarzanie znacznika NFC i ustalanie typu MIME lub identyfikatora URI, który identyfikuje dane w znaczniku.
- Opakowanie typu MIME lub identyfikatora URI oraz danych w intencji. Pierwsze 2 kroki opisaliśmy w sekcji Jak tagi NFC są mapowane na typy MIME i identyfikatory URI.
- Rozpoczyna aktywność na podstawie intencji. Opisaliśmy to w sekcji Jak tagi NFC są wysyłane do aplikacji.
Jak tagi NFC są mapowane na typy MIME i identyfikatory URI
Zanim zaczniesz pisać aplikacje NFC, warto poznać różne typy tagów NFC, sposób analizowania tych tagów przez system wysyłania tagów oraz zadania wykonywane przez system wysyłania tagów w przypadku wykrycia komunikatu NDEF. Tagi NFC są dostępne w wielu różnych technologiach i można na nich zapisywać dane na wiele różnych sposobów. Android obsługuje standard NDEF, który jest definiowany przez Forum NFC.
Dane NDEF są zaszyfrowane w ramach komunikatu (NdefMessage
), który zawiera co najmniej jeden rekord (NdefRecord
). Każdy rekord NDEF musi być poprawny zgodnie ze specyfikacją typu rekordu, który chcesz utworzyć. Android obsługuje też inne typy tagów, które nie zawierają danych NDEF. Z takich tagów możesz korzystać, używając klas w pakiecie android.nfc.tech
. Więcej informacji o tych technologiach znajdziesz w artykule NFC zaawansowane. Praca z tymi innymi typami tagów wymaga napisania własnego zestawu protokołów do komunikacji z tagami, dlatego zalecamy używanie NDEF, gdy tylko to możliwe, aby ułatwić proces tworzenia i maksymalnie zwiększyć obsługę urządzeń z Androidem.
Uwaga: aby pobrać pełne specyfikacje NDEF, wejdź na stronę Specyfikacje i dokumenty aplikacyjne Forum NFC i otwórz stronę Tworzenie typowych rekordów NDEF, aby zobaczyć przykłady tworzenia rekordów NDEF.
Teraz, gdy już wiesz coś więcej o tagach NFC, w następnych sekcjach znajdziesz bardziej szczegółowe informacje o tym, jak Android obsługuje tagi w formacie NDEF. Gdy urządzenie z Androidem zeskanuje tag NFC zawierający dane w formacie NDEF, przeanalizuje wiadomość i spróbuje określić typ MIME danych lub identyfikujący URI. W tym celu system odczytuje pierwszy NdefRecord
w ramach NdefMessage
, aby określić, jak interpretować całą wiadomość NDEF (wiadomość NDEF może mieć wiele rekordów NDEF). W prawidłowo sformułowanej wiadomości NDEF pierwsze NdefRecord
zawiera te pola:
- 3-bitowy format TNF (Type Name Format)
- Wskazuje, jak interpretować pole typu o zmiennej długości. Prawidłowe wartości są opisane w tabeli 1.
- Typ o zmiennej długości
- Określa typ rekordu. Jeśli używasz
TNF_WELL_KNOWN
, użyj tego pola do określenia definicji typu rekordu (RTD). Prawidłowe wartości RTD zostały opisane w tabeli 2. - Identyfikator zmiennej długości
- Unikalny identyfikator rekordu. To pole nie jest używane często, ale jeśli musisz jednoznacznie zidentyfikować tag, możesz utworzyć dla niego identyfikator.
- Ładunek o zmiennej długości
- Prawdziwy ładunek danych, który chcesz odczytać lub zapisać. Wiadomość NDEF może zawierać wiele rekordów NDEF, nie zakładaj więc, że pełny ładunek znajduje się w pierwszym rekordzie NDEF wiadomości NDEF.
System obsługi tagów używa pól TNF i type, aby spróbować dopasować typ MIME lub identyfikator URI do wiadomości NDEF. W przypadku powodzenia informacje te są umieszczane w intencji ACTION_NDEF_DISCOVERED
wraz z rzeczywistym ładunkiem. Zdarzają się jednak sytuacje, w których system wysyłania tagów nie może określić typu danych na podstawie pierwszego rekordu NDEF. Dzieje się tak, gdy danych NDEF nie można odwzorować na typ MIME lub identyfikator URI albo gdy tag NFC nie zawiera danych NDEF. W takich przypadkach obiekt Tag
zawierający informacje o technologiach tagu i o ładunku jest umieszczany w intencji ACTION_TECH_DISCOVERED
.
Tabela 1 opisuje, jak system obsługi tagów mapuje pola TNF i type na typy MIME lub URI. Zawiera on też opis, które TNF nie mogą być mapowane na typ MIME ani identyfikator URI.
W takich przypadkach system wysyłania tagów korzysta z ACTION_TECH_DISCOVERED
.
Jeśli na przykład system obsługi tagów napotka rekord typu TNF_ABSOLUTE_URI
, mapuje pole typu zmiennej długości tego rekordu na identyfikator URI. System obsługi tagów umieszcza ten identyfikator URI w polu danych w intencji ACTION_NDEF_DISCOVERED
wraz z innymi informacjami o tagu, takimi jak ładunek. Z drugiej strony, jeśli napotka rekord typu TNF_UNKNOWN
, tworzy intencję, która zawiera technologie tagu.
Format nazwy typu (TNF) | Mapowanie |
---|---|
TNF_ABSOLUTE_URI |
Identyfikator URI na podstawie pola typu. |
TNF_EMPTY |
Przełącza się na ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
Identyfikator URI oparty na URN w polu „Type” (Typ). Identyfikator URN jest kodowany w polu typu NDEF w skróconej postaci: <domain_name>:<service_name> .
Android mapuje to na identyfikator URI w formie:vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA |
Typ MIME na podstawie pola type. |
TNF_UNCHANGED |
Nieprawidłowy w pierwszym rekordzie, więc przyjmuje wartość ACTION_TECH_DISCOVERED . |
TNF_UNKNOWN |
Przełącza się na ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
Typ MIME lub identyfikator URI w zależności od definicji typu rekordu (RTD) ustawionej w polu typu. Więcej informacji o dostępnych typach danych RTD i ich mapowaniu znajdziesz w tabeli 2. |
Definicja typu rekordu (RTD) | Mapowanie |
---|---|
RTD_ALTERNATIVE_CARRIER |
Przełącza się na ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Przełącza się na ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Przełącza się na ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Przełącza się na ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
Identyfikator URI na podstawie parsowania ładunku. |
RTD_TEXT |
Typ MIME elementu text/plain . |
RTD_URI |
Identyfikator URI na podstawie ładunku. |
Jak tagi NFC są wysyłane do aplikacji
Gdy system obsługi tagów zakończy tworzenie zamiaru, który zawiera tag NFC i informacje identyfikacyjne, wysyła go do zainteresowanej aplikacji, która filtruje go pod kątem zamiaru. Jeśli do obsługi intencji kwalifikuje się więcej niż 1 aplikacja, użytkownikowi wyświetla się selektor aktywności, aby mógł wybrać odpowiednią aktywność. System obsługi tagów definiuje 3 zamiary, które są wymienione w kolejności od najwyższego do najniższego priorytetu:
-
ACTION_NDEF_DISCOVERED
: ta intencja służy do uruchamiania aktywności, gdy zeskanowany tag zawiera ładunek NDEF i jest rozpoznawany jako należący do rozpoznawanego typu. Jest to intencja o najwyższym priorytecie, a system wysyłania tagów w miarę możliwości próbuje rozpocząć działanie z tą intencją przed jakąkolwiek inną intencją. ACTION_TECH_DISCOVERED
: jeśli nie zarejestrowano żadnych działań do obsługi inencjiACTION_NDEF_DISCOVERED
, system obsługi tagów próbuje uruchomić aplikację z tą intencją. Ta intencja jest również uruchamiana bezpośrednio (bez uruchamianiaACTION_NDEF_DISCOVERED
), jeśli skanowany tag zawiera dane NDEF, których nie można odwzorować na typ MIME lub URI, albo jeśli tag nie zawiera danych NDEF, ale jest tagiem o znanej technologii.ACTION_TAG_DISCOVERED
: ta intencja jest uruchamiana, jeśli żadne aktywności nie obsługują intencjiACTION_NDEF_DISCOVERED
aniACTION_TECH_DISCOVERED
.
Podstawowy sposób działania systemu rozsyłania tagów:
- Spróbuj uruchomić aktywność z zamiarem utworzonym przez system obsługi tagów podczas analizowania tagu NFC (
ACTION_NDEF_DISCOVERED
lubACTION_TECH_DISCOVERED
). - Jeśli nie ma żadnych aktywności filtrujących ten zamiar, spróbuj uruchomić aktywność z zamiarem o najniższym priorytecie (
ACTION_TECH_DISCOVERED
lubACTION_TAG_DISCOVERED
), aż aplikacja zacznie filtrować zamiar lub dopóki system obsługi tagów nie spróbuje wszystkich możliwych zamiarów. - Jeśli żadne aplikacje nie filtrują żadnego z zamierowań, nie rób nic.
W miarę możliwości korzystaj z wiadomości NDEF i zamiaru ACTION_NDEF_DISCOVERED
, ponieważ jest on najbardziej precyzyjny spośród tych trzech. Ta intencja pozwala uruchomić aplikację w bardziej odpowiednim momencie niż w przypadku pozostałych 2 intencji, co zapewnia użytkownikowi lepsze wrażenia.
Prośba o dostęp do NFC w pliku manifestu Androida
Aby uzyskać dostęp do sprzętu NFC urządzenia i odpowiednio obsługiwać intencje NFC, musisz zadeklarować te elementy w pliku AndroidManifest.xml
:
- Element
<uses-permission>
NFC dający dostęp do sprzętu NFC:<uses-permission android:name="android.permission.NFC" />
- Minimalna wersja pakietu SDK, którą obsługuje Twoja aplikacja. Poziom API 9 obsługuje tylko ograniczone wysyłanie tagów za pomocą funkcji
ACTION_TAG_DISCOVERED
i daje dostęp do wiadomości NDEF tylko za pomocą funkcji dodatkowejEXTRA_NDEF_MESSAGES
. Niedostępne są żadne inne właściwości tagu ani operacje wejścia/wyjścia. Interfejs API w poziomie 10 zapewnia kompleksowe wsparcie dla czytnika/pisaka oraz przesyłanie NDEF na pierwszym planie. Interfejs API w poziomie 14 udostępnia dodatkowe wygodne metody tworzenia rekordów NDEF.<uses-sdk android:minSdkVersion="10"/>
- Element
uses-feature
, dzięki któremu aplikacja będzie widoczna w Google Play tylko na urządzeniach z urządzeniem NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Jeśli Twoja aplikacja korzysta z NFC, ale nie jest to niezbędne, możesz pominąć element
uses-feature
i sprawdzić dostępność NFC w środowisku wykonawczym. W tym celu sprawdź, czygetDefaultAdapter()
ma wartośćnull
.
Filtrowanie według intencji NFC
Aby uruchomić aplikację po zeskanowaniu tagu NFC, którego chcesz użyć, aplikacja może filtrować według 1, 2 lub wszystkich 3 intencji NFC w pliku manifestu Androida. Zwykle jednak warto filtrować według zamiaru ACTION_NDEF_DISCOVERED
, aby mieć jak największą kontrolę nad momentem uruchamiania aplikacji. Intencją ACTION_TECH_DISCOVERED
jest intencja zastępcza dla ACTION_NDEF_DISCOVERED
, gdy żadne aplikacje nie filtrują dla ACTION_NDEF_DISCOVERED
lub gdy ładunek nie jest NDEF. Filtrowanie kategorii ACTION_TAG_DISCOVERED
jest zwykle zbyt ogólne, by uwzględnić ją w filtrze. Wiele aplikacji filtruje ACTION_NDEF_DISCOVERED
lub ACTION_TECH_DISCOVERED
przed ACTION_TAG_DISCOVERED
, więc Twoja aplikacja ma małe prawdopodobieństwo uruchomienia. Funkcja ACTION_TAG_DISCOVERED
jest dostępna w ostateczności, gdy aplikacje są odfiltrowywane w przypadkach, gdy nie są zainstalowane żadne inne aplikacje obsługujące intencję ACTION_NDEF_DISCOVERED
lub ACTION_TECH_DISCOVERED
.
Ze względu na to, że wdrożenia tagów NFC są różne i często nie masz nad nimi kontroli, nie zawsze jest to możliwe. Dlatego w razie potrzeby możesz użyć jednego z 2 innych intencji. Jeśli masz kontrolę nad typami tagów i zapisywanymi danymi, zalecamy sformatowanie tagów za pomocą NDEF. W sekcjach poniżej znajdziesz informacje o tym, jak filtrować według każdego typu zamiaru.
ACTION_NDEF_DISCOVERED
Aby filtrować według intencji ACTION_NDEF_DISCOVERED
, zadeklaruj filtr intencji razem z typem danych, według których chcesz filtrować. ACTION_NDEF_DISCOVERED
intents z typem 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>
W tym przykładzie filtrujemy według identyfikatora URI w postaci 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
Jeśli aktywność filtruje pod kątem intencji ACTION_TECH_DISCOVERED
, musisz utworzyć plik zasobów XML określający technologie, które ta aktywność obsługuje w zbiorze tech-list
. Twoja aktywność jest uznawana za dopasowanie, jeśli zbiór tech-list
jest podzbiorem technologii obsługiwanych przez tag, który możesz uzyskać, wywołując funkcję getTechList()
.
Jeśli na przykład zeskanowany tag obsługuje MifareClassic, NdefFormatable i NfcA, zestaw tech-list
musi zawierać wszystkie 3 technologie, 2 technologie lub 1 technologię (i nic więcej), aby Twoja aktywność została dopasowana.
Poniższy przykład definiuje wszystkie technologie. Musisz usunąć te, których nie obsługuje Twój tag NFC. Zapisz ten plik (możesz nadać mu dowolną nazwę) w folderze <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>
Możesz też określić kilka zbiorów tech-list
. Każdy z zestawów tech-list
jest rozpatrywany niezależnie, a Twoja aktywność jest uznawana za dopasowanie, jeśli dowolny zbiór tech-list
jest podzbiorem technologii zwracanych przez funkcję getTechList()
. Zapewnia to semantykę AND
i OR
dla dopasowywania technologii. W tym przykładzie pasują tagi, które mogą obsługiwać technologie NFC-A i NDEF lub NFC-B i 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>
W pliku AndroidManifest.xml
określ utworzony właśnie plik zasobów w elemencie <meta-data>
wewnątrz elementu <activity>
, jak w tym przykładzie:
<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>
Więcej informacji o pracy z technologiami tagów i intencją ACTION_TECH_DISCOVERED
znajdziesz w dokumentacji dotyczącej zaawansowanych funkcji NFC w sekcji Praca z obsługiwanymi technologiami tagów.
ACTION_TAG_DISCOVERED
Aby filtrować według ACTION_TAG_DISCOVERED
, użyj tego filtra intencji:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Uzyskiwanie informacji z intencji
Jeśli aktywność rozpoczyna się z powodu intencji NFC, możesz uzyskać informacje o skanowanym tagu NFC z intencji. Zależnie od skanowanego tagu intencje mogą zawierać te dodatkowe informacje:
EXTRA_TAG
(wymagany): obiektTag
reprezentujący zeskanowany tag.EXTRA_NDEF_MESSAGES
(opcjonalnie): tablica wiadomości NDEF przeanalizowanych z tagu. Ten dodatek jest wymagany w przypadku intencjiACTION_NDEF_DISCOVERED
.EXTRA_ID
(opcjonalnie): identyfikator niskiego poziomu tagu.
Aby uzyskać te dodatkowe informacje, sprawdź, czy Twoja aktywność została uruchomiona za pomocą jednego z intencji NFC, aby upewnić się, że tag został zeskanowany, a następnie uzyskać dodatkowe informacje z intencji. W tym przykładzie sprawdzamy intencję ACTION_NDEF_DISCOVERED
i pobieramy wiadomości NDEF z dodatkowych danych intencji.
Kotlin
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. ... } } }
Java
@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. ... } } }
Możesz też uzyskać obiekt Tag
z intencji, który zawiera ładunek i umożliwia zliczanie technologii tagu:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Tworzenie typowych rekordów NDEF
Z tej sekcji dowiesz się, jak tworzyć typowe typy rekordów NDEF, które ułatwią Ci zapisywanie na tagach NFC. Od Androida 4.0 (poziom interfejsu API 14) dostępna jest metoda createUri()
, która ułatwia automatyczne tworzenie rekordów URI. Począwszy od Androida 4.1 (poziom interfejsu API 16) dostępne są polecenia createExternal()
i createMime()
, które ułatwiają tworzenie rekordów NDEF typu MIME i zewnętrznego. Aby uniknąć błędów podczas ręcznego tworzenia rekordów NDEF, używaj tych metod pomocniczych.
W tej sekcji opisaliśmy też, jak utworzyć odpowiedni filtr intencji dla rekordu. Wszystkie te przykłady rekordów NDEF powinny znajdować się w pierwszym rekordzie NDEF wiadomości NDEF zapisywanej na tagu.
TNF_ABSOLUTE_URI
Uwaga: zalecamy używanie typu RTD_URI
zamiast TNF_ABSOLUTE_URI
, ponieważ jest on wydajniejszy.
Rekord NDEF TNF_ABSOLUTE_URI
możesz utworzyć w ten sposób:
Kotlin
val uriRecord = ByteArray(0).let { emptyByteArray -> NdefRecord( TNF_ABSOLUTE_URI, "https://developer.android.com/index.html".toByteArray(Charset.forName("US-ASCII")), emptyByteArray, emptyByteArray ) }
Java
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]);
Filtr intencji dla poprzedniego rekordu NDEF wygląda tak:
<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
Rekord NDEF TNF_MIME_MEDIA
możesz utworzyć na te sposoby:
Za pomocą metody createMime()
:
Kotlin
val mimeRecord = NdefRecord.createMime( "application/vnd.com.example.android.beam", "Beam me up, Android".toByteArray(Charset.forName("US-ASCII")) )
Java
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam", "Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
Tworzenie NdefRecord
ręcznie:
Kotlin
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) ) }
Java
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")));
Filtr intencji dla poprzedniego rekordu NDEF wyglądałby tak:
<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 z RTD_TEXT
Rekord NDEF TNF_WELL_KNOWN
możesz utworzyć w ten sposób:
Kotlin
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) }
Java
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; }
Filtr intencji dla poprzedniego rekordu NDEF wyglądałby tak:
<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 z RDT_URI
Rekord NDEF TNF_WELL_KNOWN
można utworzyć na następujące sposoby:
za pomocą metody createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
za pomocą metody createUri(Uri)
:
Kotlin
val rtdUriRecord2 = Uri.parse("https://example.com").let { uri -> NdefRecord.createUri(uri) }
Java
Uri uri = Uri.parse("https://example.com"); NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
Tworzenie NdefRecord
ręcznie:
Kotlin
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)
Java
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);
Filtr intencji dla poprzedniego rekordu NDEF wyglądałby tak:
<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>
TYP_ZEWNĘTRZNEGO_TNF
Rekord NDEF TNF_EXTERNAL_TYPE
można utworzyć na 2 sposoby:
Za pomocą metody createExternal()
:
Kotlin
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)
Java
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);
Ręczne utworzenie NdefRecord
:
Kotlin
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Java
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
Filtr intencji dla poprzedniego rekordu NDEF wyglądałby tak:
<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>
Użyj TNF_EXTERNAL_TYPE
do wdrażania bardziej ogólnych tagów NFC, aby lepiej obsługiwać urządzenia z Androidem i inne.
Uwaga: identyfikatory URN dla TNF_EXTERNAL_TYPE
mają kanoniczny format urn:nfc:ext:example.com:externalType
. Jednak specyfikacja RTD NFC Forum deklaruje, że w rekordzie NDEF należy pominąć część urn:nfc:ext:
identyfikatora URN. Wystarczy, że podasz domenę (w tym przykładzie example.com
) i typ (w tym przykładzie externalType
), rozdzielone dwukropkiem.
Podczas wysyłania TNF_EXTERNAL_TYPE
Android konwertuje identyfikator URN urn:nfc:ext:example.com:externalType
na identyfikator URI vnd.android.nfc://ext/example.com:externalType
, który deklaruje filtr intencji w tym przykładzie.
Rekordy aplikacji na Androida
Wprowadzony w Androidzie 4.0 (poziom interfejsu API 14) rekord aplikacji na Androida (AAR) zapewnia większą pewność, że aplikacja zostanie uruchomiona po zeskanowaniu tagu NFC. Plik AAR zawiera nazwę pakietu aplikacji umieszczoną w rekordzie NDEF. Możesz dodać AAR do dowolnego rekordu NDEF w wiadomości NDEF, ponieważ Android przeszukuje całą wiadomość NDEF w celu znalezienia AAR. Jeśli znajdzie plik AAR, uruchomi aplikację na podstawie nazwy pakietu w tym pliku. Jeśli aplikacja nie jest obecna na urządzeniu, uruchamia się Google Play, aby ją pobrać.
AAR-y są przydatne, jeśli chcesz uniemożliwić innym aplikacjom filtrowanie według tego samego zamiaru i potencjalnie obsługi określonych tagów, które zostały przez Ciebie wdrożone. Ze względu na ograniczenie nazwy pakietu obsługiwane są one tylko na poziomie aplikacji, a nie na poziomie aktywności, jak w przypadku filtrowania intencji. Jeśli chcesz obsłużyć intencję na poziomie aktywności, użyj filtrów intencji.
Jeśli tag zawiera AAR, system obsługi tagów działa w ten sposób:
- Spróbuj rozpocząć aktywność, używając filtra intencji tak jak zwykle. Jeśli aktywność pasująca do intencji pasuje również do AAR, uruchom tę aktywność.
- Jeśli aktywność, która filtruje intencję, nie pasuje do AAR, jeśli kilka aktywności może obsłużyć intencję lub jeśli żadna aktywność nie obsługuje intencji, uruchom aplikację określoną przez AAR.
- Jeśli żadna aplikacja nie może uruchomić pliku AAR, otwórz Google Play i pobierz aplikację na podstawie pliku AAR.
Uwaga: możesz zastąpić AAR i system obsługi intencji systemem obsługi intencji na pierwszym planie, który umożliwia priorytetowe traktowanie aktywności na pierwszym planie po wykryciu tagu NFC. W przypadku tej metody aktywność musi być na pierwszym planie, aby można było zastąpić polecenia AAR i system wysyłania intencji.
Jeśli nadal chcesz filtrować tagi skanowania, które nie zawierają AAR, możesz zadeklarować filtry intencji w zwykły sposób. Jest to przydatne, jeśli aplikacja jest zainteresowana innymi tagami, które nie zawierają AAR. Możesz na przykład chcieć zagwarantować, aby Twoja aplikacja obsługiwała tagi własne, które wdrażasz, a także tagi ogólne wdrażane przez osoby trzecie. Pamiętaj, że tagi AAR są przeznaczone do urządzeń z Androidem 4.0 lub nowszym, więc podczas wdrażania tagów prawdopodobnie zechcesz użyć kombinacji tagów AAR i typów/identyfikatorów URI MIME, aby zapewnić obsługę jak największej liczby urządzeń. Poza tym podczas wdrażania tagów NFC zastanów się, jak chcesz je zapisać, aby umożliwić obsługę na większości urządzeń (z Androidem i innych). Aby to zrobić, zdefiniuj stosunkowo unikalny typ MIME lub identyfikator URI, aby ułatwić aplikacjom ich rozróżnianie.
Android udostępnia prosty interfejs API do tworzenia pakietów AAR.createApplicationRecord()
Wystarczy, że umieścisz plik AAR w dowolnym miejscu w swojej NdefMessage
. Nie chcesz używać pierwszego rekordu NdefMessage
, chyba że AAR jest jedynym rekordem w NdefMessage
. Dzieje się tak, ponieważ system Android sprawdza pierwszy rekord ciągu NdefMessage
, aby określić typ MIME lub identyfikator URI tagu, który służy do tworzenia intencji filtrowania aplikacji. Poniższy kod pokazuje, jak utworzyć AAR:
Kotlin
val msg = NdefMessage( arrayOf( ..., NdefRecord.createApplicationRecord("com.example.android.beam") ) )
Java
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")} ); )