W tym dokumencie opisano podstawowe czynności związane z komunikacją NFC, które możesz wykonywać na Androidzie. Wyjaśniono w nim, jak odbiera dane NFC w postaci wiadomości NDEF i opisuje interfejsy API platformy Android, które obsługują tych funkcji. W przypadku bardziej zaawansowanych tematów, w tym dyskusji na temat pracy z danymi innymi niż NDEF, Więcej informacji znajdziesz w sekcji Zaawansowane NFC.
Istnieją 2 główne przypadki użycia danych NDEF i Androida:
- Odczyt danych NDEF z tagu NFC
- Przesyłanie wiadomości NDEF z jednego urządzenia na drugie przy użyciu Androida BeamTM
Odczyt danych NDEF z tagu NFC jest obsługiwany przez wysyłkę tagu , który analizuje wykryte tagi NFC, odpowiednio kategoryzuje dane i uruchamia dla aplikacji, która jest zainteresowana danymi kategoryzowanymi. Aplikacja, która chce obsługiwać zeskanowany tag NFC może zadeklarować filtr intencji oraz żądania obsługi danych.
Funkcja Android BeamTM pozwala urządzeniu przesłać wiadomość NDEF na innego urządzenia, fizycznie stykając urządzenia. Taka interakcja ułatwia do wysyłania danych niż w przypadku innych technologii bezprzewodowych, takich jak Bluetooth. Dzięki komunikacji NFC nie trzeba instalować ręcznie urządzeń Wykrywanie lub parowanie jest wymagane. Połączenie nawiązywane jest automatycznie, gdy dwóch urządzeniach do celu. Android Beam jest dostępny przez zestaw interfejsów API NFC, dzięki czemu każda aplikacja może przesyłać i przekazywać informacje między urządzeniami. Na przykład aplikacje Kontakty, Przeglądarka i YouTube używają Android Beam pozwala udostępniać kontakty, strony internetowe i filmy innym urządzeniom.
System wysyłania tagów
Urządzenia z Androidem zwykle szukają tagów NFC, gdy ekran jest odblokowane, chyba że komunikacja NFC jest wyłączona w menu ustawień urządzenia. Po wykryciu tagu NFC przez urządzenie z Androidem wymagane jest jest najodpowiedniejsze działanie intencji bez pytania użytkownika o to, która aplikacja których użyć. Urządzenia skanują tagi NFC w bardzo krótkim zasięgu, więc prawdopodobnie spowoduje to odłączenie urządzenia od tagu i zerwanie połączenia. Opracowuj aktywność tak, aby obsługiwała tylko te tagi NFC, na których Ci zależy uniemożliwia wyświetlenie wyboru aktywności.
Aby Ci w tym pomóc, Android udostępnia specjalny system wysyłania tagów, który analizuje zeskanowane tagów NFC, analizuje je i próbuje znaleźć aplikacje zainteresowane zeskanowanymi danymi. it Robi to przez:
- Analiza tagu NFC i ustalenie typu MIME lub identyfikatora URI identyfikującego ładunek danych .
- Uwzględnienie typu MIME lub identyfikatora URI i ładunku w intencji. To dwa pierwsze instrukcje znajdziesz w artykule Jak tagi NFC są mapowane na typy MIME i identyfikatory URI.
- Rozpoczyna aktywność na podstawie intencji. Opisa to tutaj: Jak tagi NFC są wysyłane do aplikacji.
Jak tagi NFC są mapowane na typy MIME i identyfikatory URI
Zanim zaczniesz pisać aplikacje NFC, zapoznaj się z różnymi typy tagów NFC, sposób analizowania tagów NFC przez system wysyłania tagów oraz specjalne funkcje tagów system wysyłania, gdy wykryje wiadomość NDEF. Tagi NFC mają z szeroką gamą technologii, a także zapisywać dane na wiele różnych sposobów. Android w największym stopniu obsługuje standard NDEF, który został zdefiniowany na Forum NFC.
Dane NDEF są zawarte w wiadomości (NdefMessage
), która zawiera jeden
lub więcej rekordów (NdefRecord
). Każdy rekord NDEF musi być poprawnie sformatowany zgodnie z
specyfikację typu rekordu, który ma zostać utworzony. Android,
obsługuje też inne typy tagów, które nie zawierają danych NDEF. Aby z nich korzystać, użyj funkcji
na zajęcia w pakiecie android.nfc.tech
. Aby dowiedzieć się więcej,
więcej informacji o tych technologiach znajdziesz w temacie Zaawansowane funkcje NFC. Praca z tymi innymi typami tagów obejmuje
własnego stosu protokołów do komunikowania się z tagami. Dlatego zalecamy użycie NDEF
jest to możliwe ze względu na łatwość programowania i maksymalną obsługę urządzeń z systemem Android.
Uwaga: Aby pobrać pełną specyfikację NDEF, odwiedź specyfikacje Forum NFC dokumenty aplikacyjne oraz Tworzenie typowych typów rekordów NDEF, na których można znaleźć przykłady tworzyć rekordy NDEF.
Skoro już masz wiedzę na temat tagów NFC, w kolejnych sekcjach dowiesz się, jak
Android obsługuje tagi w formacie NDEF. Gdy urządzenie z Androidem skanuje tag NFC zawierający NDEF
sformatowanych danych, analizuje wiadomość i próbuje określić typ MIME lub zidentyfikować
Identyfikator URI. W tym celu system odczytuje pierwszy element NdefRecord
wewnątrz ciągu NdefMessage
, aby określić, jak zinterpretować cały komunikat NDEF (komunikat NDEF może
mają kilka rekordów NDEF). W dobrze sformułowanej wiadomości NDEF pierwszy element NdefRecord
zawiera następujące pola:
- 3-bitowy TNF (format nazwy typu)
- Wskazuje, jak interpretować pole typu zmiennej długości. Prawidłowe wartości to opisane w tabeli 1.
- Typ zmiennej długości
- Określa typ rekordu. Jeśli używasz
TNF_WELL_KNOWN
, wpisz w tym polu, aby określić definicję 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 często używane, ale (jeśli tag wymaga jednoznacznej identyfikacji, można utworzyć dla niego identyfikator.
- Ładunek o zmiennej długości
- Rzeczywiste ładunki danych, które chcesz odczytywać lub zapisywać. NDEF komunikat może zawierać wiele rekordów NDEF, więc nie zakładaj, że pełny ładunek znajduje się w pierwszym NDEF w rekordzie wiadomości NDEF.
System wysyłania tagów używa pól TNF i type, aby spróbować zmapować typ MIME lub identyfikator URI
Komunikat NDEF. Jeśli operacja się uda, umieszcza tę informację w intencji ACTION_NDEF_DISCOVERED
razem z rzeczywistym ładunkiem. Istnieje jednak
występują przypadki, gdy system wysyłania tagów nie może określić typu danych na podstawie pierwszego NDEF
nagrywać. Dzieje się tak, gdy danych NDEF nie można zmapować na typ MIME lub identyfikator URI albo gdy
Tag NFC nie zawiera danych NDEF, od których można zacząć. W takich przypadkach obiekt Tag
, który zawiera informacje o technologii tagu i ładunku, jest
zawarte w intencji ACTION_TECH_DISCOVERED
.
Tabela 1 opisuje, jak system wysyłania tagów mapuje TNF i typ
do typów MIME lub identyfikatorów URI. Dowiesz się też, których plików TNF nie można zmapować na typ MIME lub identyfikator URI.
W takich przypadkach system wysyłki tagów przełącza się na
ACTION_TECH_DISCOVERED
Jeśli na przykład system wysyłania tagów napotka rekord typu TNF_ABSOLUTE_URI
, mapuje pole typu zmiennej długości tego rekordu
do identyfikatora URI. System wysyłania tagów umieszcza ten identyfikator URI w polu danych intencji ACTION_NDEF_DISCOVERED
wraz z innymi informacjami o tagu.
takich jak ładunek. Z drugiej strony, jeśli natrafi na rekord typu TNF_UNKNOWN
, tworzy intencję, która obejmuje technologie tagu.
.
Format nazwy typu (TNF) | Mapowanie |
---|---|
TNF_ABSOLUTE_URI |
Identyfikator URI na podstawie pola typu. |
TNF_EMPTY |
Powraca do ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
Identyfikator URI oparty na URN w polu typu. URN jest kodowany w polu typu NDEF w
skrócona forma: <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 typu. |
TNF_UNCHANGED |
Nieprawidłowa w pierwszym rekordzie, dlatego wartość używana jest
ACTION_TECH_DISCOVERED |
TNF_UNKNOWN |
Powraca do ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
Typ MIME lub identyfikator URI w zależności od definicji typu rekordu (RTD) ustawionej w type (Typ konwersji). Więcej informacji znajdziesz w tabeli 2. dostępnych RTD i ich mapowań. |
Definicja typu rekordu (RTD) | Mapowanie |
---|---|
RTD_ALTERNATIVE_CARRIER |
Powraca do ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Powraca do ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Powraca do ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Powraca do ACTION_TECH_DISCOVERED . |
RTD_SMART_POSTER |
Identyfikator URI oparty na analizie ładunku. |
RTD_TEXT |
Typ MIME: text/plain . |
RTD_URI |
Identyfikator URI oparty na ładunku. |
Jak tagi NFC są wysyłane do aplikacji
Gdy system wysyłania tagów utworzy intencję, która obejmie tag NFC i jego tag wysyła intencje do zainteresowanych aplikacji, filtry intencji. Jeśli więcej niż jedna aplikacja może obsłużyć intencję, narzędzie wyboru aktywności jest wyświetlana, 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
: ta intencja służy do uruchamiania Działanie, gdy tag zawierający ładunek NDEF jest skanowany i ma rozpoznany typ. To jest o intencji o najwyższym priorytecie, a system wysyłania tagów próbuje uruchomić działanie z tym elementem przed intencjami z innymi intencjami, gdy tylko jest to możliwe. ACTION_TECH_DISCOVERED
: jeśli żadne aktywności nie są rejestrowane na obsługuje:ACTION_NDEF_DISCOVERED
system wysyłania tagów próbuje uruchomić aplikację z tą intencją. Ten intencja jest również inicjowana bezpośrednio (bez rozpoczynania dyrektywyACTION_NDEF_DISCOVERED
), jeśli skanowany tag zawiera dane NDEF, których nie można zmapować na typ MIME lub identyfikator URI albo jeśli tag nie zawiera NDEF ale pochodzą ze znanej technologii tagów.ACTION_TAG_DISCOVERED
: ta intencja została uruchomiona jeśli żadne działania nie obsługują funkcjiACTION_NDEF_DISCOVERED
lubACTION_TECH_DISCOVERED
intencji.
Podstawowy sposób działania systemu wysyłania tagów jest następujący:
- Spróbuj uruchomić aktywność z intencją utworzoną przez system wysyłania tagów
podczas analizowania tagu NFC (albo
ACTION_NDEF_DISCOVERED
lubACTION_TECH_DISCOVERED
). - Jeśli żadne działania nie są filtrowane dla tej intencji, spróbuj rozpocząć aktywność od następnej
intencja o najniższym priorytecie (
ACTION_TECH_DISCOVERED
lubACTION_TAG_DISCOVERED
), dopóki aplikacja nie przefiltruje danych pod kątem argumentu lub do czasu, gdy system wysyłania tagów spróbuje użyć wszystkich możliwych intencji. - Jeśli żadna z aplikacji nie filtruje według którejkolwiek z intencji, nie rób nic.
W miarę możliwości korzystaj z wiadomości NDEF i intencji ACTION_NDEF_DISCOVERED
, ponieważ jest to najbardziej szczegółowy
trzy. Ta intencja umożliwia uruchomienie aplikacji w bardziej odpowiednim momencie niż
dla wygody użytkownika.
Poproś o dostęp do NFC w pliku manifestu Androida
Aby uzyskać dostęp do sprzętu NFC urządzenia i prawidłowo obsługiwać intencje NFC, zadeklaruj 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. Interfejs API poziomu 9 obsługuje tylko
ograniczona dostawa tagów przez
ACTION_TAG_DISCOVERED
i daje tylko dostęp do wiadomości NDEF przy użyciu dodatkuEXTRA_NDEF_MESSAGES
. Nie inne właściwości tagów lub operacje wejścia-wyjścia. Poziom API 10 obejmuje kompleksową obsługę odczytu/zapisu, a także przekazywanie NDEF na pierwszym planie i poziom interfejsu API. 14 to łatwiejszy sposób na przesyłanie wiadomości NDEF na inne urządzenia za pomocą Android Beam i dodatkowych wygodnych metod tworzenia rekordów NDEF.<uses-sdk android:minSdkVersion="10"/>
- Element
uses-feature
, który umożliwia wyświetlenie aplikacji w Google Play tylko w przypadku urządzeń wyposażonych w moduł NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Jeśli aplikacja obsługuje komunikację NFC, aplikacji, możesz pominąć element
uses-feature
i sprawdzić dostępność NFC na stronie w środowisku wykonawczym, sprawdzając, czygetDefaultAdapter()
jestnull
.
Filtruj pod kątem intencji NFC
Aby uruchomić aplikację po zeskanowaniu tagu NFC, który chcesz obsługiwać,
może filtrować jedną, dwie lub wszystkie 3 intencje NFC w pliku manifestu Androida. Musisz jednak
zwykle filtrują pod kątem intencji ACTION_NDEF_DISCOVERED
dla
mają największą kontrolę nad czasem uruchamiania aplikacji. Intencja ACTION_TECH_DISCOVERED
jest regułą zastępczą dla reguły ACTION_NDEF_DISCOVERED
, gdy żadne aplikacje nie filtrują dla tego parametru
ACTION_NDEF_DISCOVERED
lub gdy ładunek nie jest
NDEF. Filtrowanie danych „ACTION_TAG_DISCOVERED
” jest zwykle zbyt ogólne dla
według kategorii, według której chcesz filtrować. Wiele aplikacji będzie odfiltrowywać ACTION_NDEF_DISCOVERED
lub ACTION_TECH_DISCOVERED
przed ACTION_TAG_DISCOVERED
, więc w ich przypadku prawdopodobieństwo
od uruchomienia. Z usługi ACTION_TAG_DISCOVERED
można korzystać tylko w ostateczności
dla aplikacji, które mają być filtrowane w przypadku, gdy nie są zainstalowane żadne inne aplikacje do obsługi
Intencja ACTION_NDEF_DISCOVERED
lub ACTION_TECH_DISCOVERED
.
Implementacja tagów NFC jest różna i często nie zależy od Ciebie, dlatego nie zawsze jest to możliwe. dlatego w razie potrzeby zawsze możesz skorzystać z 2 pozostałych intencji. Jeśli masz nad typami tagów i zapisywanych danych, zalecamy użycie NDEF do formatowania . W sekcjach poniżej opisujemy, jak filtrować dane pod kątem poszczególnych typów intencji.
ACTION_NDEF_DISCOVERED
Aby filtrować intencje ACTION_NDEF_DISCOVERED
, zadeklaruj klucz
filtr intencji wraz z typem danych, według których chcesz filtrować.
te przykładowe filtry dla zapytania ACTION_NDEF_DISCOVERED
intencje 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>
Poniższy przykład filtruje identyfikator URI w formie
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 Twoja aktywność filtruje treści pod kątem intencji ACTION_TECH_DISCOVERED
,
musisz utworzyć plik zasobów XML określający technologie, które obsługuje Twoja aktywność
w zbiorze tech-list
. Twoja aktywność to
uznaje się za dopasowanie, jeśli zbiór tech-list
jest podzbiorem technologii, które są
obsługiwane przez tag. Można je uzyskać, wywołując metodę getTechList()
.
Jeśli na przykład skanowany tag obsługuje MifareClassic, NdefFormatable i NfcA, tag
Zbiór tech-list
musi określać wszystkie 3, 2 lub 1 z technologii (i nic
inne), aby Twoja aktywność była dopasowywana.
Poniższy przykład definiuje wszystkie technologie. Usuń te, które nie są
obsługiwane przez Twój tag NFC. Zapisz ten plik (nadaj mu dowolną nazwę) w
Folder <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
. tech-list
są rozpatrywane niezależnie, a Twoja aktywność zostanie uznana za dopasowanie, jeśli
Zbiór tech-list
to podzbiór technologii zwracanych przez funkcję getTechList()
. Ta funkcja zapewnia AND
i OR
semantyka technologii dopasowywania. Poniższy przykład pasuje do tagów, które mogą obsługiwać
technologii NfcA i Ndef lub obsługuje technologie 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
wskaż utworzony przed chwilą plik zasobów.
w elemencie <meta-data>
wewnątrz <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 korzystaniu z technologii tagów i intencji ACTION_TECH_DISCOVERED
znajdziesz w artykule Praca z obsługiwanym tagiem
Technologie w dokumencie Advanced NFC.
ACTION_TAG_DISCOVERED
Aby filtrować dane według parametru ACTION_TAG_DISCOVERED
, użyj tej intencji
filtr:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Uzyskiwanie informacji z intencji
Jeśli aktywność zostanie uruchomiona z powodu intencji NFC, możesz uzyskać informacje o zeskanowanym urządzeniu z intencji. W zależności od skanowanego tagu intencje mogą zawierać te dodatki:
EXTRA_TAG
(wymagany): obiektTag
co oznacza zeskanowany tag.EXTRA_NDEF_MESSAGES
(opcjonalnie): tablica komunikatów NDEF przeanalizowany z tagu. Ten dodatek jest obowiązkowy wACTION_NDEF_DISCOVERED
intencje.EXTRA_ID
(opcjonalny): identyfikator tagu niskiego poziomu.
Aby uzyskać te dodatki, sprawdź, czy Twoja aktywność została uruchomiona przy użyciu jednego z
w celu sprawdzenia, czy tag został przeskanowany, a następnie uzyskania dodatków
intencji. Ten przykład pozwala sprawdzić stan ACTION_NDEF_DISCOVERED
i pobiera wiadomości NDEF z dodatkowej 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ć z intencji obiekt Tag
, który
zawierają ładunek i pozwalają wymienić technologie tagu:
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Tworzenie typowych typów rekordów NDEF
W tej sekcji opisano tworzenie typowych typów rekordów NDEF ułatwiających pisanie
wysyłanie tagów NFC lub danych za pomocą Android Beam; Począwszy od Androida 4.0 (poziom interfejsu API 14)
Metoda createUri()
, która pomoże Ci utworzyć
automatycznie rekordy URI. Od Androida 4.1 (poziom interfejsu API 16)
createExternal()
i createMime()
mogą pomóc Ci w tworzeniu
Rekordy NDEF typu MIME i zewnętrzne. W miarę możliwości korzystaj z tych metod pomocniczych, aby uniknąć błędów
podczas ręcznego tworzenia rekordów NDEF.
W tej sekcji znajdują się również informacje na temat tworzenia odpowiednich filtr intencji dla rekordu. Wszystkie te przykładowe rekordy NDEF powinny znajdować się w pierwszym NDEF zapisu wiadomości NDEF, którą piszesz do tagu lub przesyłasz.
TNF_ABSOLUTE_URI
Uwaga: zalecamy użycie atrybutu
Zamiast tego wpisz RTD_URI
od TNF_ABSOLUTE_URI
, ponieważ jest skuteczniejszy.
Rekord NDEF TNF_ABSOLUTE_URI
można utworzyć w następujący 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żna utworzyć na następujące 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")));
Ręczne utworzenie 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 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żna utworzyć w następujący 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 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 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);
Ręczne utworzenie 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 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ć w tych usługach
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 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 zasady TNF_EXTERNAL_TYPE
, która zapewni lepszą obsługę obu rodzajów tagów
Urządzenia z systemem Android lub bez niego.
Uwaga: kanoniczne numery URN dla TNF_EXTERNAL_TYPE
mają następujący format:
urn:nfc:ext:example.com:externalType
, jednak specyfikacja RTD Forum
deklaruje, że część urn:nfc:ext:
identyfikatora URN musi zostać pominięta w
rekord NDEF. Wystarczy więc podać domenę (w tym przykładzie example.com
).
i typ (w przykładzie externalType
) rozdzielone dwukropkiem.
Podczas wysyłania żądania 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
deklaruje filtr intencji.
Rekordy aplikacji na Androida
Wprowadzony w Androidzie 4.0 (poziom interfejsu API 14) rekord aplikacji na Androida (AAR) zapewnia aby mieć pewność, że aplikacja zostanie uruchomiona w przypadku skanowania tagu NFC. AAR ma nazwę pakietu aplikacji umieszczonej w rekordzie NDEF. Możesz dodać AAR do dowolnego rekordu NDEF swojego NDEF ponieważ Android przeszukuje całą wiadomość NDEF pod kątem zapytań AAR. Jeśli je znajdzie, uruchamia się aplikacji na podstawie nazwy pakietu w AAR. Jeśli aplikacji nie ma na urządzenia, zostaje uruchomiony Google Play, aby pobrać aplikację.
Są one przydatne, jeśli chcesz zapobiec filtrowaniu przez inne aplikacje pod kątem tych samych intencji może obsługiwać konkretne tagi, które wdrożysz. Oferty AAR są obsługiwane tylko w na poziomie aplikacji ze względu na ograniczenie nazwy pakietu, a nie na poziomie aktywności, jak w przypadku przez filtrowanie intencji. Jeśli chcesz obsługiwać intencję na poziomie aktywności, użyj filtrów intencji.
Jeśli tag zawiera atrybut AAR, system wysyłania tagów wysyła go w taki sposób:
- Spróbuj jak zwykle rozpocząć aktywność, korzystając z filtra intencji. Jeśli aktywność pasująca do zapytania intencja jest zgodna z AAR, rozpocznij działanie.
- Jeśli działanie, które filtruje intencję, nie pasuje do parametru AAR, jeśli wiele działań może obsłużyć intencję lub żadne działanie nie obsługuje intencji, rozpocznij aplikacji określonej przez AAR.
- Jeśli żadna aplikacja nie może zaczynać się od atrybutu AAR, przejdź do Google Play, aby pobrać zgodnie z dokumentem AAR.
Uwaga: reguły AAR i system wysyłania intencji możesz zastąpić funkcją pierwszy plan system wysyłania, który umożliwia priorytetowe traktowaniu aktywności na pierwszym planie, gdy tag NFC jest odkrycie. W przypadku tej metody działanie musi być na pierwszym planie, aby można było zastąpić błędy AAR i system dyspozytorów intencji.
Jeśli mimo to chcesz filtrować wyniki pod kątem zeskanowanych tagów, które nie zawierają atrybutu AAR, możesz zadeklarować filtrów intencji. Przydaje się to, gdy Twoja aplikacja jest zainteresowana innymi tagami które nie zawierają kodu AAR. Jeśli na przykład chcesz zagwarantować, że aplikacja będzie obsługiwać własne tagi i tagi ogólne wdrażane przez Ciebie, jak również tagi ogólne wdrożone przez inne firmy. Pamiętaj że certyfikaty AAR są dostosowane do urządzeń z Androidem 4.0 lub nowszym, więc przy wdrażaniu tagów warto aby użyć kombinacji identyfikatorów AAR i typów MIME/URI w celu obsługi najszerszego zakresu urządzeń. W Jeśli wdrażasz tagi NFC, zastanów się, jak chcesz je zapisać, obsługą większości urządzeń (z systemem Android i innych). Możesz to zrobić w następujący sposób: zdefiniowanie stosunkowo unikalnego typu MIME lub identyfikatora URI, aby aplikacje mogły łatwiej je odróżnić.
Android udostępnia prosty interfejs API do tworzenia AAR,
createApplicationRecord()
Wszystko, czego potrzebujesz
wystarczy umieścić plik AAR w dowolnym miejscu w NdefMessage
. Nie chcesz
aby użyć pierwszego rekordu z: NdefMessage
, chyba że AAR jest jedynym
wpis w NdefMessage
. To dlatego, że Android
system sprawdza pierwszy rekord NdefMessage
, aby określić typ MIME lub
Identyfikator URI tagu, który jest używany do tworzenia intencji filtrowania przez aplikacje. Następujący kod:
pokazuje, jak utworzyć automatyczny klucz 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")} ); )
Przesyłaj wiadomości NDEF do innych urządzeń
Android Beam umożliwia prostą wymianę danych peer-to-peer między dwoma urządzeniami z Androidem. aplikacja, która chce przesyłać dane do innego urządzenia, musi działać na pierwszym planie, a urządzenie odbieranie danych nie może być zablokowane. Gdy urządzenie wysyłające znajdzie się wystarczająco blisko urządzenia odbierającego, na urządzeniu wysyłającym wyświetli się komunikat „Dotknij, by przesłać”. Interfejs. Użytkownik może wtedy wybrać czy wysłać wiadomość do urządzenia odbierającego.
Uwaga: przekazywanie NDEF na pierwszym planie było dostępne na poziomie API 10,
który oferuje funkcje podobne do Android Beam. Te interfejsy API zostały już wycofane, ale
są dostępne na starszych urządzeniach. Przeczytaj enableForegroundNdefPush()
, by dowiedzieć się więcej.
Możesz włączyć Android Beam dla swojej aplikacji, wywołując jedną z dwóch metod:
setNdefPushMessage()
: akceptujeNdefMessage
, aby ustawić ją jako wiadomość do przesłania. Automatycznie przesyła wiadomość zbliżeniowo gdy 2 urządzenia znajdują się w odpowiedniej odległości od siebie.setNdefPushMessageCallback()
: Akceptuje wywołanie zwrotne zawierającecreateNdefMessage()
która jest wywoływana, gdy urządzenie znajduje się w zasięgu, do którego można przesłać dane. Wywołanie zwrotne umożliwia utworzenie komunikatu NDEF tylko wtedy, gdy jest to konieczne.
Aktywność może przekazać tylko 1 wiadomość NDEF naraz, więc zasada setNdefPushMessageCallback()
ma pierwszeństwo
więcej niż setNdefPushMessage()
, jeśli oba są ustawione. Aby użyć funkcji
Android Beam, musisz przestrzegać tych ogólnych wytycznych:
- Działanie przesyłające dane musi znajdować się na pierwszym planie. Oba urządzenia muszą mieć odblokowane ekrany.
- Dane, które przesyłasz, musisz umieścić w
NdefMessage
obiektu. - Urządzenie NFC odbierające przesyłane dane musi obsługiwać
com.android.npp
Protokół push NDEF lub SNEP forum NFC (Simple NDEF Exchange) Protokół). Protokółcom.android.npp
jest wymagany w przypadku urządzeń z interfejsem API poziomu 9 (Android 2.3) do poziomu API 13 (Android 3.2). Zarównocom.android.npp
, jak i SNEP są wymagane na Interfejs API poziomu 14 (Android 4.0) i nowsze.
Uwaga: jeśli w aktywności włączona jest funkcja Android Beam, na pierwszym planie system standardowego wysyłania intencji jest wyłączony. Jeśli jednak Twoja aktywność włącza wysyłanych na pierwszym planie, nadal może skanować tagi pasujące do filtrów intencji ustawionych w parametrze wysyłanie danych na pierwszym planie.
Aby włączyć Android Beam:
- Utwórz obiekt
NdefMessage
zawierającyNdefRecord
który chcesz rozesłać na drugie urządzenie. - Wywołaj funkcję
setNdefPushMessage()
za pomocą funkcjiNdefMessage
lub wywołajsetNdefPushMessageCallback
przekazywane w obiekcieNfcAdapter.CreateNdefMessageCallback
w metodzieonCreate()
Twojej aktywności. Te metody wymagają co najmniej 1 działania, które chcesz włączyć na Androidzie Beam oraz opcjonalną listę innych aktywności, które możesz aktywować.Zazwyczaj używasz
setNdefPushMessage()
wtedy, gdy aktywność wysyłania tego samego komunikatu NDEF przez cały czas, gdy 2 urządzenia znajdują się w zasięgu komunikacji. UżywaszsetNdefPushMessageCallback
, gdy aplikacja dba o bieżący kontekst aplikacji i chce wysłać komunikat NDEF w zależności od tego, co użytkownik robi w aplikacji.
Poniższy przykład pokazuje, jak prosta aktywność wywołuje NfcAdapter.CreateNdefMessageCallback
w metodzie onCreate()
funkcji
(zobacz AndroidBeamDemo)
, gdzie znajduje się cała próbka). Ten przykład przedstawia też metody tworzenia rekordu MIME:
Kotlin
package com.example.android.beam import android.app.Activity import android.content.Intent import android.nfc.NdefMessage import android.nfc.NdefRecord import android.nfc.NfcAdapter import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.NfcEvent import android.os.Bundle import android.os.Parcelable import android.widget.TextView import android.widget.Toast import java.nio.charset.Charset class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback { private var nfcAdapter: NfcAdapter? = null private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) textView = findViewById(R.id.textView) // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show() finish() return } // Register callback nfcAdapter?.setNdefPushMessageCallback(this, this) } override fun createNdefMessage(event: NfcEvent): NdefMessage { val text = "Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis() return NdefMessage( arrayOf( createMime("application/vnd.com.example.android.beam", text.toByteArray()) ) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. *///,NdefRecord.createApplicationRecord("com.example.android.beam") ) } override fun onResume() { super.onResume() // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { processIntent(intent) } } override fun onNewIntent(intent: Intent) { // onResume gets called after this to handle the intent setIntent(intent) } /** * Parses the NDEF Message from the intent and prints to the TextView */ private fun processIntent(intent: Intent) { textView = findViewById(R.id.textView) // only one message sent during the beam intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs -> (rawMsgs[0] as NdefMessage).apply { // record 0 contains the MIME type, record 1 is the AAR, if present textView.text = String(records[0].payload) } } } }
Java
package com.example.android.beam; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; public class Beam extends Activity implements CreateNdefMessageCallback { NfcAdapter nfcAdapter; TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); finish(); return; } // Register callback nfcAdapter.setNdefPushMessageCallback(this, this); } @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = ("Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis()); NdefMessage msg = new NdefMessage( new NdefRecord[] { createMime( "application/vnd.com.example.android.beam", text.getBytes()) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") }); return msg; } @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { textView = (TextView) findViewById(R.id.textView); Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present textView.setText(new String(msg.getRecords()[0].getPayload())); } }
Pamiętaj, że ten kod komentuje plik AAR, który możesz usunąć. Jeśli włączysz automatyczne stosowanie rekomendacji, aplikacja określona w AAR zawsze otrzymuje wiadomość Android Beam. Jeśli aplikacja nie jest rozpocznie się pobieranie aplikacji przez Google Play. W związku z tym następujący zamiar W przypadku urządzeń z Androidem 4.0 i nowszym stosowanie filtru AAR nie jest technicznie konieczne:
<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>
Dzięki temu filtrowi intencji można teraz uruchomić aplikację com.example.android.beam
gdy skanuje tag NFC lub odbiera sygnał Android Beam z kodem AAR ustawionym na poziomie
wpisz com.example.android.beam
lub jeśli wiadomość w formacie NDEF zawiera rekord MIME
typu application/vnd.com.example.android.beam
.
Chociaż AAR gwarantują uruchomienie lub pobranie aplikacji, filtry intencji są zalecane, bo pozwalają rozpocząć aktywność na aplikacji zamiast zawsze uruchamiać główne działanie w pakiecie określonym przez AAR. Rekomendacje AAR nie mają szczegółowości na poziomie aktywności. Ponadto, ponieważ niektóre urządzenia z systemem Android obsługuje aplikacje AAR, należy również umieścić informacje identyfikacyjne w pierwszym rekordzie NDEF dokumentu NDEF wiadomości i filtrować je, tak na wszelki wypadek. Zobacz Tworzenie wspólnych Typy rekordów NDEF.