W tym dokumencie opisujemy podstawowe zadania związane z NFC, które możesz wykonywać na Androidzie. Wyjaśnia, jak wysyłać i odbierać dane NFC w postaci wiadomości NDEF, oraz opisuje interfejsy API platformy Android, 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.
Odczytywanie danych NDEF z tagu NFC odbywa się za pomocą systemu wysyłania tagów, który analizuje wykryte tagi NFC, odpowiednio kategoryzuje dane i uruchamia aplikację zainteresowaną skategoryzowanymi danymi. Aplikacja, która chce obsługiwać zeskanowany tag NFC, może zadeklarować filtr intencji i poprosić o obsługę danych.
System wysyłania tagów
Urządzenia z Androidem zwykle wyszukują tagi NFC, gdy ekran jest odblokowany, chyba że komunikacja NFC jest wyłączona w menu Ustawienia urządzenia. Gdy urządzenie z Androidem wykryje tag NFC, oczekiwane zachowanie to przekazanie intencji do najbardziej odpowiedniej aktywności bez pytania użytkownika, której aplikacji ma użyć. Urządzenia skanują tagi NFC z bardzo bliskiej odległości, więc wymuszenie na użytkownikach ręcznego wybierania aktywności spowodowałoby prawdopodobnie odsunięcie urządzenia od tagu i przerwanie połączenia. Aby zapobiec wyświetlaniu selektora aktywności, opracuj aktywność tak, aby obsługiwała tylko te tagi NFC, które są dla niej istotne.
Aby Ci w tym pomóc, Android udostępnia specjalny system wysyłania tagów, który analizuje zeskanowane tagi NFC, przetwarza je i próbuje znaleźć aplikacje zainteresowane zeskanowanymi danymi. W tym celu:
- Analizowanie tagu NFC i określanie typu MIME lub identyfikatora URI, który identyfikuje ładunek danych w tagu.
- Enkapsulacja typu MIME lub identyfikatora URI i ładunku w intencji. Pierwsze 2 kroki opisano w artykule Jak tagi NFC są mapowane na typy MIME i identyfikatory URI.
- Uruchamia aktywność na podstawie intencji. Opisano to w artykule Jak tagi NFC są wysyłane do aplikacji.
Sposób mapowania tagów NFC na typy MIME i identyfikatory URI
Zanim zaczniesz pisać aplikacje NFC, musisz poznać różne typy tagów NFC, sposób, w jaki system wysyłania tagów analizuje tagi NFC, oraz specjalne działania, które system wysyłania tagów wykonuje po wykryciu komunikatu NDEF. Tagi NFC wykorzystują wiele różnych technologii, a dane można na nich zapisywać na wiele sposobów. Android w największym stopniu obsługuje standard NDEF, który został zdefiniowany przez NFC Forum.
Dane NDEF są umieszczane w wiadomości (NdefMessage), która zawiera co najmniej 1 rekord (NdefRecord). Każdy rekord NDEF musi być prawidłowo sformatowany zgodnie ze specyfikacją typu rekordu, który chcesz utworzyć. Android obsługuje też inne typy tagów, które nie zawierają danych NDEF. Możesz z nimi pracować, korzystając z klas w pakiecie android.nfc.tech. Więcej informacji o tych technologiach znajdziesz w artykule Zaawansowane NFC. Praca z tymi typami tagów wymaga napisania własnego stosu protokołów do komunikacji z tagami, dlatego zalecamy używanie formatu NDEF, gdy jest to możliwe, aby ułatwić programowanie i zapewnić maksymalną obsługę urządzeń z Androidem.
Uwaga: aby pobrać pełne specyfikacje NDEF, wejdź na stronę NFC Forum Specifications & Application Documents i zapoznaj się z sekcją Creating common types of NDEF records, w której znajdziesz przykłady tworzenia rekordów NDEF.
W sekcjach poniżej znajdziesz szczegółowe informacje o tym, jak Android obsługuje tagi sformatowane w NDEF. Gdy urządzenie z Androidem skanuje tag NFC zawierający dane w formacie NDEF, analizuje wiadomość i próbuje określić typ MIME danych lub identyfikujący adres URI. W tym celu system odczytuje pierwszy rekord NdefRecord w rekordzie NdefMessage, aby określić, jak interpretować całą wiadomość NDEF (wiadomość NDEF może zawierać wiele rekordów NDEF). W prawidłowo sformatowanej wiadomości NDEF pierwszy rekord NdefRecord zawiera te pola:
- 3-bit TNF (Type Name Format)
- Wskazuje, jak interpretować pole typu o zmiennej długości. Prawidłowe wartości zostały opisane w tabeli 1.
- Typ o zmiennej długości
- Opisuje typ rekordu. Jeśli używasz TNF_WELL_KNOWN, użyj tego pola, aby określić definicję typu rekordu (RTD). Prawidłowe wartości RTD zostały opisane w tabeli 2.
- Identyfikator o zmiennej długości
- Unikalny identyfikator rekordu. To pole nie jest często używane, ale jeśli chcesz jednoznacznie zidentyfikować tag, możesz utworzyć dla niego identyfikator.
- Ładunek o zmiennej długości
- Rzeczywiste dane, które chcesz odczytać lub zapisać. Wiadomość NDEF może zawierać wiele rekordów NDEF, więc nie zakładaj, że cały ładunek znajduje się w pierwszym rekordzie NDEF wiadomości NDEF.
System wysyłania tagów używa pól TNF i type, aby spróbować przypisać typ MIME lub identyfikator URI do wiadomości NDEF. Jeśli się to uda, informacje te zostaną umieszczone w obiekcie ACTION_NDEF_DISCOVERED wraz z rzeczywistym ładunkiem. W niektórych przypadkach system wysyłania tagów nie może jednak określić typu danych na podstawie pierwszego rekordu NDEF. Dzieje się tak, gdy danych NDEF nie można przypisać do typu MIME ani URI lub gdy tag NFC nie zawiera danych NDEF. W takich przypadkach obiekt Tag zawierający informacje o technologiach tagu i ładunku jest umieszczany w obiekcie ACTION_TECH_DISCOVERED.
Tabela 1 zawiera opis sposobu, w jaki system wysyłania tagów mapuje pola TNF i type na typy MIME lub URI. Opisuje też, których TNFs nie można zmapować na typ MIME ani URI.
W takich przypadkach system wysyłania tagów wraca do wartości ACTION_TECH_DISCOVERED.
Jeśli na przykład system wysyłania tagów napotka rekord typu TNF_ABSOLUTE_URI, mapuje pole typu o zmiennej długości tego rekordu na identyfikator URI. System wysyłania tagów umieszcza ten identyfikator URI w polu danych ACTION_NDEF_DISCOVERED wraz z innymi informacjami o tagu, takimi jak ładunek. Jeśli jednak napotka rekord typu TNF_UNKNOWN, utworzy intencję, która obejmuje technologie tagu.
Tabela 1. Obsługiwane TNFs i ich mapowania
| Format nazwy typu (TNF) | Mapowanie | 
|---|---|
| TNF_ABSOLUTE_URI | Identyfikator URI na podstawie pola Type. | 
| TNF_EMPTY | Wracasz do ACTION_TECH_DISCOVERED. | 
| TNF_EXTERNAL_TYPE | Identyfikator URI na podstawie URN w polu typu. URN jest zakodowany w polu typu NDEF w skróconej formie: <domain_name>:<service_name>.
        Android mapuje to na identyfikator URI w formacie:vnd.android.nfc://ext/<domain_name>:<service_name>. | 
| TNF_MIME_MEDIA | Typ MIME na podstawie pola typu. | 
| TNF_UNCHANGED | Nieprawidłowa w pierwszym rekordzie, więc przyjmuje wartość ACTION_TECH_DISCOVERED. | 
| TNF_UNKNOWN | Wracasz do ACTION_TECH_DISCOVERED. | 
| TNF_WELL_KNOWN | Typ MIME lub URI w zależności od definicji typu rekordu (RTD), którą ustawiasz w polu typu. Więcej informacji o dostępnych RTD i ich mapowaniach znajdziesz w tabeli 2. | 
Tabela 2. Obsługiwane identyfikatory RTD dla typu TNF_WELL_KNOWN i ich mapowania
| Definicja typu rekordu (RTD) | Mapowanie | 
|---|---|
| RTD_ALTERNATIVE_CARRIER | Wracasz do ACTION_TECH_DISCOVERED. | 
| RTD_HANDOVER_CARRIER | Wracasz do ACTION_TECH_DISCOVERED. | 
| RTD_HANDOVER_REQUEST | Wracasz do ACTION_TECH_DISCOVERED. | 
| RTD_HANDOVER_SELECT | Wracasz do ACTION_TECH_DISCOVERED. | 
| RTD_SMART_POSTER | Identyfikator URI na podstawie analizy ładunku. | 
| RTD_TEXT | Typ MIME text/plain. | 
| RTD_URI | Identyfikator URI na podstawie ładunku. | 
Sposób wysyłania tagów NFC do aplikacji
Gdy system wysyłania tagów zakończy tworzenie intencji, która zawiera tag NFC i jego informacje identyfikacyjne, wysyła ją do zainteresowanej aplikacji, która filtruje intencje. Jeśli intencję może obsłużyć więcej niż jedna aplikacja, wyświetlany jest selektor aktywności, aby użytkownik mógł wybrać aktywność. System wysyłania tagów definiuje 3 intencje, które są wymienione w kolejności od najwyższego do najniższego priorytetu:
- 
      ACTION_NDEF_DISCOVERED: ten zamiar jest używany do uruchamiania działania, gdy zostanie zeskanowany tag zawierający ładunek NDEF i jest on rozpoznanego typu. Jest to zamiar o najwyższym priorytecie, a system wysyłania tagów w miarę możliwości próbuje uruchomić działanie z tym zamiarem przed każdym innym zamiarem.Uwaga: od Androida 16 skanowanie tagów NFC, które przechowują linki URL (czyli schemat URI to „https://” lub „http://”), będzie wywoływać intencję ACTION_VIEWzamiast intencjiACTION_NDEF_DISCOVERED.
- ACTION_TECH_DISCOVERED: Jeśli żadne działania nie są zarejestrowane do obsługi intencji- ACTION_NDEF_DISCOVERED, system wysyłania tagów próbuje uruchomić aplikację z tą intencją. Ten zamiar jest też uruchamiany bezpośrednio (bez wcześniejszego uruchamiania- ACTION_NDEF_DISCOVERED), jeśli zeskanowany tag zawiera dane NDEF, których nie można przypisać do typu MIME ani URI, lub jeśli tag nie zawiera danych NDEF, ale jest znany.
- ACTION_TAG_DISCOVERED: ten zamiar jest uruchamiany, jeśli żadne działania nie obsługują zamiarów- ACTION_NDEF_DISCOVEREDani- ACTION_TECH_DISCOVERED.
Podstawowy sposób działania systemu wysyłania tagów jest następujący:
- Próba rozpoczęcia aktywności za pomocą intencji utworzonej przez system wysyłania tagów podczas analizowania tagu NFC (ACTION_NDEF_DISCOVEREDlubACTION_TECH_DISCOVERED).
- Jeśli nie ma filtra aktywności dla tego zamiaru, spróbuj uruchomić aktywność z następnym najniższym priorytetem (ACTION_TECH_DISCOVEREDlubACTION_TAG_DISCOVERED), dopóki aplikacja nie odfiltruje zamiaru lub dopóki system wysyłania tagów nie wypróbuje wszystkich możliwych zamiarów.
- Jeśli żadna aplikacja nie filtruje żadnego z tych zamiarów, nie rób nic.
 
  Jeśli to możliwe, używaj wiadomości NDEF i intencji ACTION_NDEF_DISCOVERED, ponieważ jest ona najbardziej szczegółowa z tych 3 rodzajów. Ten zamiar pozwala uruchomić aplikację w odpowiedniejszym momencie niż w przypadku pozostałych 2 zamiarów, co zwiększa wygodę użytkownika.
Poproś o dostęp do NFC w pliku manifestu Androida
Zanim uzyskasz dostęp do sprzętu NFC urządzenia i będziesz prawidłowo obsługiwać intencje NFC, zadeklaruj te elementy w pliku AndroidManifest.xml:
- Element NFC <uses-permission>umożliwiający dostęp do sprzętu NFC:<uses-permission android:name="android.permission.NFC" /> 
- Minimalna wersja pakietu SDK, którą może obsługiwać Twoja aplikacja. Poziom API 9 obsługuje tylko ograniczone wysyłanie tagów za pomocą ACTION_TAG_DISCOVEREDi zapewnia dostęp do wiadomości NDEF tylko za pomocą dodatkuEXTRA_NDEF_MESSAGES. Nie ma dostępu do innych właściwości tagu ani operacji wejścia/wyjścia. Interfejs API na poziomie 10 obejmuje kompleksową obsługę odczytu i zapisu oraz wysyłanie NDEF na pierwszym planie, a interfejs API na poziomie 14 zapewnia dodatkowe wygodne metody tworzenia rekordów NDEF.<uses-sdk android:minSdkVersion="10"/>
- element uses-feature, aby aplikacja była widoczna w Google Play tylko na urządzeniach z modułem NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" /> Jeśli Twoja aplikacja korzysta z funkcji NFC, ale nie jest ona kluczowa dla jej działania, możesz pominąć element uses-featurei sprawdzić dostępność NFC w czasie działania aplikacji, sprawdzając, czygetDefaultAdapter()jestnull.
Filtrowanie intencji NFC
Aby uruchomić aplikację po zeskanowaniu tagu NFC, którym chcesz się zająć, możesz filtrować w manifestie Androida jedną, dwie lub wszystkie trzy intencje NFC. Zwykle jednak chcesz filtrować według intencji ACTION_NDEF_DISCOVERED, aby mieć największą kontrolę nad tym, kiedy aplikacja się uruchamia. Intencja ACTION_TECH_DISCOVERED jest rezerwowa dla intencji ACTION_NDEF_DISCOVERED, gdy nie ma filtrów aplikacji dla ACTION_NDEF_DISCOVERED lub gdy ładunek nie jest w formacie NDEF. Filtrowanie według ACTION_TAG_DISCOVERED jest zwykle zbyt ogólną kategorią, aby na jej podstawie filtrować.  Wiele aplikacji filtruje ACTION_NDEF_DISCOVERED lub ACTION_TECH_DISCOVERED przed ACTION_TAG_DISCOVERED, więc prawdopodobieństwo uruchomienia Twojej aplikacji jest niewielkie. ACTION_TAG_DISCOVERED jest dostępny tylko w ostateczności w przypadku aplikacji, które mają filtrować intencje, gdy nie są zainstalowane żadne inne aplikacje do obsługi intencji ACTION_NDEF_DISCOVERED lub ACTION_TECH_DISCOVERED.
Wdrożenia tagów NFC są różne i często nie zależą od Ciebie, dlatego nie zawsze jest to możliwe. W razie potrzeby możesz użyć pozostałych 2 intencji. Jeśli masz kontrolę nad typami tagów i zapisywanych danych, zalecamy używanie formatu NDEF do formatowania tagów. W sekcjach poniżej znajdziesz informacje o tym, jak filtrować poszczególne typy intencji.
ACTION_NDEF_DISCOVERED
Aby filtrować intencje ACTION_NDEF_DISCOVERED, zadeklaruj filtr intencji wraz z typem danych, które chcesz filtrować. W tym przykładzie filtrowane są intencje ACTION_NDEF_DISCOVERED
o typie 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>
Poniższy przykład filtruje identyfikator URI w formacie 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 filtry aktywności są przeznaczone dla intencji ACTION_TECH_DISCOVERED, musisz utworzyć plik zasobu XML, który określa technologie obsługiwane przez aktywność w ramach zestawu tech-list. Twoja aktywność jest uznawana za pasującą, jeśli tech-list jest podzbiorem technologii obsługiwanych przez tag, które możesz uzyskać, wywołując getTechList().
Jeśli na przykład skanowany tag obsługuje MifareClassic, NdefFormatable i NfcA, Twój tech-listzestaw musi zawierać wszystkie 3, 2 lub 1 z tych technologii (i nic więcej), aby Twoja aktywność została dopasowana.
Poniższy przykład określa wszystkie technologie. Musisz usunąć te, które nie są obsługiwane przez tag NFC. Zapisz ten plik (możesz mu nadać 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ć wiele zestawów tech-list. Każdy z tech-list
  zbiorów jest rozpatrywany niezależnie, a Twoja aktywność jest uznawana za pasującą, jeśli dowolny z tech-list zbiorów jest podzbiorem technologii zwracanych przez getTechList(). Zapewnia to semantykę AND i OR
  w przypadku technologii dopasowywania. Poniższy przykład pasuje do tagów, które mogą obsługiwać technologie NfcA i Ndef lub NfcB 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 zasobu w elemencie <meta-data> w elemencie <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 artykule Praca z obsługiwanymi technologiami tagów w dokumencie Zaawansowane NFC.
ACTION_TAG_DISCOVERED
Aby filtrować pod kątem ACTION_TAG_DISCOVERED, użyj tego filtra intencji:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
ACTION_VIEW
 Od Androida 16 skanowanie tagów NFC, które przechowują linki URL, będzie wywoływać intencję ACTION_VIEW. Aby odfiltrować ACTION_VIEW,this. Użyj aplikacji Android app links, aby otworzyć adres URL.
Uzyskiwanie informacji z intencji
Jeśli aktywność rozpoczyna się z powodu intencji NFC, możesz uzyskać informacje o zeskanowanym tagu NFC z intencji. Intencje mogą zawierać te dodatki w zależności od zeskanowanego tagu:
- EXTRA_TAG(wymagany): obiekt- Tagreprezentujący zeskanowany tag.
- EXTRA_NDEF_MESSAGES(opcjonalnie): tablica wiadomości NDEF przeanalizowanych z tagu. Ten dodatkowy element jest obowiązkowy w przypadku intencji- ACTION_NDEF_DISCOVERED.
- EXTRA_ID(opcjonalny): identyfikator tagu niskiego poziomu.
Aby uzyskać te dodatkowe informacje, sprawdź, czy aktywność została uruchomiona za pomocą jednego z intentów NFC, aby upewnić się, że tag został zeskanowany, a następnie pobierz dodatkowe informacje z intentu. W przykładzie poniżej sprawdzana jest intencja ACTION_NDEF_DISCOVERED i pobierane są wiadomości NDEF z dodatku do 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 będzie zawierać ładunek i umożliwi Ci wyliczenie technologii tagu:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Tworzenie typowych rekordów NDEF
W tej sekcji opisujemy, jak tworzyć typowe rodzaje rekordów NDEF, które pomogą Ci podczas zapisywania tagów NFC. Począwszy od Androida 4.0 (interfejs API na poziomie 14), dostępna jest metoda 
createUri(), która pomaga automatycznie tworzyć rekordy URI. Od Androida 4.1 (API na poziomie 16) dostępne są klasy
createExternal()
i createMime(), które pomagają tworzyć rekordy NDEF typu MIME i typu zewnętrznego. Gdy tylko jest to możliwe, używaj tych metod pomocniczych, aby uniknąć błędów podczas ręcznego tworzenia rekordów NDEF.
W tej sekcji opisujemy 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 bardziej wydajny.
Rekord NDEF możesz utworzyć w ten sposób:TNF_ABSOLUTE_URI
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ł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="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
TNF_MIME_MEDIA
Rekord TNF_MIME_MEDIA NDEF możesz utworzyć na te sposoby:
Użyj 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")));
Ręczne tworzenie NdefRecord:
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 TNF_WELL_KNOWN NDEF 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 RTD_URI
Rekord TNF_WELL_KNOWN NDEF możesz utworzyć na te sposoby:
Użyj metody createUri(String):
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Użyj 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);
Ręczne tworzenie NdefRecord:
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>
TNF_EXTERNAL_TYPE
Rekord NDEF możesz utworzyć na te sposoby:TNF_EXTERNAL_TYPE
Użyj 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 tworzenie 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>
W przypadku bardziej ogólnych wdrożeń tagów NFC używaj formatu TNF_EXTERNAL_TYPE, aby lepiej obsługiwać urządzenia z Androidem i bez niego.
Uwaga: identyfikatory URN dla TNF_EXTERNAL_TYPE mają format kanoniczny: urn:nfc:ext:example.com:externalType, jednak specyfikacja RTD NFC Forum stwierdza, że część urn:nfc:ext: identyfikatora URN musi zostać pominięta w rekordzie NDEF. Wystarczy, że podasz domenę (example.com w przykładzie) i typ (externalType w przykładzie) rozdzielone dwukropkiem.
Podczas wysyłania TNF_EXTERNAL_TYPE Android konwertuje URN urn:nfc:ext:example.com:externalType
 na identyfikator URI vnd.android.nfc://ext/example.com:externalType, który jest zadeklarowany w filtrze intencji w przykładzie.
Rekordy aplikacji na Androida
Wprowadzony w Androidzie 4.0 (poziom 14 interfejsu API) rekord aplikacji na Androida (AAR) zapewnia większą pewność, że aplikacja zostanie uruchomiona po zeskanowaniu tagu NFC. AAR ma nazwę pakietu aplikacji osadzoną w rekordzie NDEF. Rekord AAR możesz dodać do dowolnego rekordu NDEF w wiadomości NDEF, ponieważ Android wyszukuje rekordy AAR w całej wiadomości NDEF. Jeśli znajdzie plik AAR, uruchomi aplikację na podstawie nazwy pakietu w tym pliku. Jeśli aplikacja nie jest zainstalowana na urządzeniu, uruchomi się Google Play, aby ją pobrać.
AAR są przydatne, jeśli chcesz uniemożliwić innym aplikacjom filtrowanie pod kątem tego samego zamiaru i potencjalne obsługiwanie określonych tagów, które zostały przez Ciebie wdrożone. Pliki AAR są obsługiwane tylko na poziomie aplikacji ze względu na ograniczenie dotyczące nazwy pakietu, a nie na poziomie aktywności, jak w przypadku filtrowania intencji. Jeśli chcesz obsługiwać intencję na poziomie aktywności, użyj filtrów intencji.
Jeśli tag zawiera AAR, system wysyłania tagów wysyła go w ten sposób:
- Spróbuj uruchomić aktywność za pomocą filtra intencji w normalny sposób. Jeśli aktywność pasująca do intencji pasuje też do AAR, uruchom aktywność.
- Jeśli aktywność, która filtruje intencję, nie pasuje do pliku AAR, jeśli intencję może obsłużyć wiele aktywności lub jeśli żadna aktywność nie obsługuje intencji, uruchom aplikację określoną przez plik AAR.
- Jeśli żadna aplikacja nie może się uruchomić z użyciem AAR, pobierz aplikację z Google Play na podstawie AAR.
Uwaga: możesz zastąpić AAR i system wysyłania intencji systemem wysyłania na pierwszym planie, który umożliwia aktywności na pierwszym planie uzyskanie priorytetu po wykryciu tagu NFC. W przypadku tej metody aktywność musi być na pierwszym planie, aby zastąpić AAR i system wysyłania intencji.
Jeśli nadal chcesz filtrować zeskanowane tagi, które nie zawierają AAR, możesz zadeklarować filtry intencji w normalny sposób. Jest to przydatne, jeśli Twoja aplikacja jest zainteresowana innymi tagami, które nie zawierają AAR. Możesz na przykład chcieć mieć pewność, że Twoja aplikacja obsługuje tagi własne, które wdrażasz, a także ogólne tagi wdrażane przez firmy zewnętrzne. Pamiętaj, że pliki AAR są przeznaczone dla urządzeń z Androidem 4.0 lub nowszym, więc podczas wdrażania tagów prawdopodobnie będziesz używać kombinacji plików AAR i typów MIME/identyfikatorów URI, aby obsługiwać jak najszerszy zakres urządzeń. Dodatkowo podczas wdrażania tagów NFC zastanów się, jak chcesz je zapisać, aby umożliwić obsługę jak największej liczby urządzeń (z Androidem i innych). Możesz to zrobić, definiując stosunkowo unikalny typ MIME lub identyfikator URI, aby ułatwić aplikacjom rozróżnianie.
Android udostępnia prosty interfejs API do tworzenia pliku AAR,
createApplicationRecord(). Wystarczy, że umieścisz AAR w dowolnym miejscu w NdefMessage. Nie chcesz używać pierwszego rekordu z NdefMessage, chyba że AAR jest jedynym rekordem w NdefMessage. Dzieje się tak, ponieważ system Android sprawdza pierwszy rekord w NdefMessage, aby określić typ MIME lub URI tagu, który jest używany do tworzenia intencji filtrowania aplikacji. Poniższy kod pokazuje, jak utworzyć plik 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")} ); )
Lista dozwolonych aplikacji do skanowania tagów NFC
Od Androida 16 użytkownicy są powiadamiani, gdy aplikacja otrzyma pierwszy zamiar NFC dotyczący skanowania tagów NFC. W powiadomieniu użytkownik ma możliwość zabronienia aplikacji skanowania tagów NFC.
- Aplikacje mogą sprawdzać, czy użytkownik zezwolił im na skanowanie tagów NFC, za pomocą metody NfcAdapter.isTagIntentAllowed().
- Aplikacje mogą ponownie prosić użytkownika o zezwolenie na skanowanie tagów NFC, wysyłając intencję
ACTION_CHANGE_TAG_INTENT_PREFERENCE.
Uwaga: lista dozwolonych aplikacji do skanowania tagów NFC jest dostępna w sekcji Settings > Apps > Special app access > Launch via NFC.
