NFC – Grundlagen

In diesem Dokument werden die grundlegenden NFC-Aufgaben beschrieben, die Sie unter Android ausführen. Es wird erläutert, wie NFC-Daten in Form von NDEF-Nachrichten gesendet und empfangen werden, und es werden die Android-Framework-APIs beschrieben, die diese Funktionen unterstützen. Fortgeschrittenere Themen, einschließlich einer Diskussion zur Arbeit mit Nicht-NDEF-Daten, finden Sie unter Erweiterte NFC.

Das Lesen von NDEF-Daten aus einem NFC-Tag erfolgt mit dem Tag-Weiterleitungssystem, das erkannte NFC-Tags analysiert, die Daten entsprechend kategorisiert und eine Anwendung startet, die an den kategorisierten Daten interessiert ist. Eine Anwendung, die das gescannte NFC-Tag verarbeiten möchte, kann einen Intent-Filter deklarieren und die Verarbeitung der Daten anfordern.

Das Tag-Dispatch-System

Android-Geräte suchen normalerweise nach NFC-Tags, wenn der Bildschirm entsperrt ist. Dies gilt nicht, wenn NFC im Menü "Einstellungen" des Geräts deaktiviert ist. Wenn ein Android-Gerät ein NFC-Tag erkennt, soll der Intent von der am besten geeigneten Aktivität verarbeitet werden, ohne dass der Nutzer gefragt wird, welche App er verwenden möchte. Da Geräte NFC-Tags in sehr kurzer Reichweite scannen, ist es wahrscheinlich, dass Nutzer, die eine Aktivität manuell auswählen, sie dazu zwingen würden, das Gerät vom Tag wegzubewegen und die Verbindung zu unterbrechen. Sie sollten Ihre Aktivität so entwickeln, dass nur die NFC-Tags verarbeitet werden, die für Ihre Aktivität relevant sind, um zu verhindern, dass die Aktivitätsauswahl angezeigt wird.

Um Sie bei diesem Ziel zu unterstützen, bietet Android ein spezielles Tag-Versandsystem, das gescannte NFC-Tags analysiert, parst und versucht, Anwendungen zu finden, die an den gescannten Daten interessiert sind. Dazu gehören:

  1. Parsen des NFC-Tags und Ermitteln des MIME-Typs oder eines URI, der die Datennutzlast im Tag identifiziert.
  2. Der MIME-Typ oder URI und die Nutzlast werden in einen Intent gekapselt. Diese ersten beiden Schritte werden unter NFC-Tags MIME-Typen und URIs zuordnen beschrieben.
  3. Startet eine Aktivität basierend auf dem Intent. Weitere Informationen finden Sie unter So werden NFC-Tags an Anwendungen gesendet.

Zuordnung von NFC-Tags zu MIME-Typen und URIs

Bevor Sie mit dem Schreiben Ihrer NFC-Anwendungen beginnen, sollten Sie sich mit den verschiedenen Arten von NFC-Tags, der Verarbeitung von NFC-Tags durch das Tag-Dispatch-System und den speziellen Aufgaben des Tag-Dispatch-Systems vertraut machen, wenn eine NDEF-Nachricht erkannt wird. NFC-Tags gibt es in vielen verschiedenen Technologien und Daten können auf viele verschiedene Arten darauf geschrieben werden. Android bietet die beste Unterstützung für den NDEF-Standard, der vom NFC Forum definiert wird.

NDEF-Daten sind in einer Nachricht (NdefMessage) gekapselt, die einen oder mehrere Einträge (NdefRecord) enthält. Jeder NDEF-Eintrag muss gemäß der Spezifikation des zu erstellenden Eintragstyps korrekt formatiert sein. Android unterstützt auch andere Arten von Tags, die keine NDEF-Daten enthalten. Sie können mit diesen Tags arbeiten, indem Sie die Klassen im Paket android.nfc.tech verwenden. Weitere Informationen zu diesen Technologien finden Sie im Hilfeartikel NFC-Funktionen. Wenn Sie mit diesen anderen Arten von Tags arbeiten, müssen Sie einen eigenen Protokollstack schreiben, um mit den Tags zu kommunizieren. Wir empfehlen daher, nach Möglichkeit NDEF zu verwenden, um die Entwicklung zu vereinfachen und die maximale Unterstützung für Android-Geräte zu erhalten.

Hinweis: Wenn Sie die vollständigen NDEF-Spezifikationen herunterladen möchten, rufen Sie die Website NFC-Forum: Spezifikationen und Anwendungsdokumente auf. Beispiele zum Erstellen von NDEF-Einträgen finden Sie unter Allgemeine Arten von NDEF-Einträgen erstellen.

Nachdem Sie nun einige Hintergrundinformationen zu NFC-Tags haben, wird in den folgenden Abschnitten ausführlicher beschrieben, wie Android mit NDEF-formatierten Tags umgeht. Wenn ein Android-Gerät ein NFC-Tag mit NDEF-formatierten Daten scannt, wird die Nachricht geparst und versucht, den MIME-Typ oder die URI der Daten zu ermitteln. Dazu liest das System die ersten NdefRecord innerhalb der NdefMessage, um zu bestimmen, wie die gesamte NDEF-Nachricht interpretiert werden soll (eine NDEF-Nachricht kann mehrere NDEF-Einträge haben). In einer korrekt formatierten NDEF-Nachricht enthält die erste NdefRecord die folgenden Felder:

3‑Bit-TNF (Type Name Format)
Gibt an, wie das Feld für den Variablenlängentyp zu interpretieren ist. Die gültigen Werte sind in Tabelle 1 beschrieben.
Typ mit variabler Länge
Hier wird der Datensatztyp beschrieben. Wenn Sie TNF_WELL_KNOWN verwenden, geben Sie in diesem Feld die Datensatztypdefinition (Record Type Definition, RTD) an. Gültige RTD-Werte sind in Tabelle 2 beschrieben.
ID der Variablenlänge
Eine eindeutige Kennung für den Datensatz. Dieses Feld wird nicht oft verwendet. Wenn Sie ein Tag jedoch eindeutig identifizieren möchten, können Sie eine ID dafür erstellen.
Nutzlast variabler Länge
Die tatsächliche Datennutzlast, die Sie lesen oder schreiben möchten. Eine NDEF-Nachricht kann mehrere NDEF-Einträge enthalten. Angenommen Sie also nicht, dass sich die vollständige Nutzlast im ersten NDEF-Eintrag der NDEF-Nachricht befindet.

Das Tag-Dispatch-System verwendet die TNF- und Typfelder, um einen MIME-Typ oder URI der NDEF-Nachricht zuzuordnen. Bei Erfolg werden diese Informationen zusammen mit der tatsächlichen Nutzlast in einer ACTION_NDEF_DISCOVERED-Intent-Nachricht gekapselt. Es gibt jedoch Fälle, in denen das Tag-Weiterleitungssystem den Datentyp nicht anhand des ersten NDEF-Eintrags ermitteln kann. Das passiert, wenn die NDEF-Daten keinem MIME-Typ oder URI zugeordnet werden können oder wenn das NFC-Tag gar keine NDEF-Daten enthält. In solchen Fällen wird ein Tag-Objekt mit Informationen zu den Technologien des Tags und der Nutzlast stattdessen in einer ACTION_TECH_DISCOVERED-Intention gekapselt.

In Tabelle 1 wird beschrieben, wie das Tag-Weiterleitungssystem TNF- und Typfelder den MIME-Typen oder URIs zuordnet. Außerdem wird beschrieben, welche TNFs keinem MIME-Typ oder URI zugeordnet werden können. In diesen Fällen greift das Tag-Dispatch-System auf ACTION_TECH_DISCOVERED zurück.

Wenn das Tag-Dispatch-System beispielsweise einen Datensatz vom Typ TNF_ABSOLUTE_URI findet, wird das Feld „Typ mit variabler Länge“ dieses Datensatzes in einen URI umgewandelt. Das Tag-Dispatch-System kapselt diesen URI zusammen mit anderen Informationen zum Tag, z. B. der Nutzlast, im Datenfeld einer ACTION_NDEF_DISCOVERED-Intention ein. Wenn hingegen ein Eintrag vom Typ TNF_UNKNOWN gefunden wird, wird eine Intent erstellt, die die Technologien des Tags umschließt.

Tabelle 1 Unterstützte TNFs und ihre Zuordnungen

Format des Typnamens (TNF) Zuordnung
TNF_ABSOLUTE_URI URI basierend auf dem Feld „type“.
TNF_EMPTY Es erfolgt ein Fallback auf ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPE URI basierend auf der URN im Feld „type“. Die URN wird im Feld NDEF-Typ in verkürzter Form codiert: <domain_name>:<service_name>. Android ordnet dies einem URI im folgenden Format zu: vnd.android.nfc://ext/<domain_name>:<service_name>.
TNF_MIME_MEDIA MIME-Typ basierend auf dem Typfeld.
TNF_UNCHANGED Im ersten Datensatz ungültig, daher wird ACTION_TECH_DISCOVERED zurückgegeben.
TNF_UNKNOWN Es erfolgt ein Fallback auf ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWN MIME-Typ oder URI, je nach der Definition des Datensatztyps (Record Type Definition, RTD), die Sie im Feld „Typ“ festlegen. Weitere Informationen zu verfügbaren RTDs und ihren Zuordnungen finden Sie in Tabelle 2.

Tabelle 2 Unterstützte RTDs für TNF_WELL_KNOWN und ihre Zuordnungen

Record Type Definition (RTD) Zuordnung
RTD_ALTERNATIVE_CARRIER Fällt auf ACTION_TECH_DISCOVERED zurück.
RTD_HANDOVER_CARRIER Fällt auf ACTION_TECH_DISCOVERED zurück.
RTD_HANDOVER_REQUEST Fällt auf ACTION_TECH_DISCOVERED zurück.
RTD_HANDOVER_SELECT Es erfolgt ein Fallback auf ACTION_TECH_DISCOVERED.
RTD_SMART_POSTER URI, der auf dem Parsen der Nutzlast basiert.
RTD_TEXT MIME-Typ von text/plain.
RTD_URI URI basierend auf Nutzlast.

Wie NFC-Tags an Apps gesendet werden

Sobald das Tag-Dispatch-System einen Intent erstellt hat, der das NFC-Tag und seine identifizierenden Informationen umschließt, sendet es den Intent an eine interessierte Anwendung, die nach dem Intent filtert. Wenn mehrere Anwendungen den Intent verarbeiten können, wird die Aktivitätsauswahl angezeigt, damit der Nutzer die Aktivität auswählen kann. Das Tag-Dispatch-System definiert drei Intents, die in der Reihenfolge von höchster zu niedrigster Priorität aufgeführt sind:

  1. ACTION_NDEF_DISCOVERED: Mit dieser Intent-Aktion wird eine Aktivität gestartet, wenn ein Tag mit einer NDEF-Nutzlast gescannt wird und zu einem erkannten Typ gehört. Dies ist der Intent mit der höchsten Priorität. Das Tag-Dispatch-System versucht, nach Möglichkeit eine Aktivität mit diesem Intent vor allen anderen Intents zu starten.
  2. ACTION_TECH_DISCOVERED: Wenn keine Aktivitäten für die Verarbeitung des ACTION_NDEF_DISCOVERED-Intents registriert sind, versucht das Tag-Dispatch-System, eine Anwendung mit diesem Intent zu starten. Dieser Intent wird auch direkt gestartet (ohne zuerst ACTION_NDEF_DISCOVERED zu starten), wenn das gescannte Tag NDEF-Daten enthält, die nicht einem MIME-Typ oder URI zugeordnet werden können, oder wenn das Tag keine NDEF-Daten enthält, aber eine bekannte Tag-Technologie verwendet.
  3. ACTION_TAG_DISCOVERED: Dieser Intent wird gestartet, wenn keine Aktivitäten die Intents ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED verarbeiten.

So funktioniert das Tag-Dispatch-System im Wesentlichen:

  1. Versuchen Sie, eine Aktivität mit der Absicht zu starten, die vom Tag-Dispatch-System beim Parsen des NFC-Tags erstellt wurde (entweder ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED).
  2. Wenn keine Aktivitäten nach diesem Intent gefiltert werden, versuchen Sie, eine Aktivität mit dem Intent mit der nächstniedrigeren Priorität (ACTION_TECH_DISCOVERED oder ACTION_TAG_DISCOVERED) zu starten, bis eine Anwendung nach dem Intent filtert oder das Tag-Dispatch-System alle möglichen Intents ausprobiert hat.
  3. Wenn keine Apps nach den Intents filtern, müssen Sie nichts unternehmen.
Abbildung 1. Tag Dispatch System

Arbeiten Sie nach Möglichkeit mit NDEF-Nachrichten und dem Intent ACTION_NDEF_DISCOVERED, da dies der spezifischste der drei ist. Mit diesem Intent können Sie Ihre Anwendung zu einem geeigneteren Zeitpunkt starten als mit den anderen beiden Intents. Das ist für die Nutzer angenehmer.

NFC-Zugriff im Android-Manifest anfordern

Bevor Sie auf die NFC-Hardware eines Geräts zugreifen und NFC-Intents richtig verarbeiten können, müssen Sie die folgenden Elemente in Ihrer AndroidManifest.xml-Datei deklarieren:

  • Das NFC-<uses-permission>-Element für den Zugriff auf die NFC-Hardware:
    <uses-permission android:name="android.permission.NFC" />
    
  • Die SDK-Mindestversion, die Ihre App unterstützt. API-Level 9 unterstützt nur einen eingeschränkten Tag-Versand über ACTION_TAG_DISCOVERED und gewährt nur über das EXTRA_NDEF_MESSAGES-Extra Zugriff auf NDEF-Nachrichten. Auf andere Tag-Properties oder E/A-Vorgänge kann nicht zugegriffen werden. API-Ebene 10 bietet umfassende Unterstützung für Leser/Autoren sowie NDEF-Übertragung im Vordergrund. API-Ebene 14 bietet zusätzliche praktische Methoden zum Erstellen von NDEF-Einträgen.
    <uses-sdk android:minSdkVersion="10"/>
    
  • Das Element uses-feature, damit Ihre App bei Google Play nur für Geräte mit NFC-Hardware angezeigt wird:
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    

    Wenn Ihre Anwendung NFC-Funktionen verwendet, diese Funktion aber nicht für Ihre Anwendung entscheidend ist, können Sie das Element uses-feature weglassen und die NFC-Verfügbarkeit zur Laufzeit prüfen, indem Sie prüfen, ob getDefaultAdapter() null ist.

Nach NFC-Intents filtern

Wenn Ihre App gestartet werden soll, wenn ein NFC-Tag gescannt wird, das Sie verarbeiten möchten, kann Ihre App nach einem, zwei oder allen drei NFC-Intents im Android-Manifest filtern. Normalerweise sollten Sie jedoch nach dem Intent ACTION_NDEF_DISCOVERED filtern, um den Start der Anwendung möglichst genau zu steuern. Der Intent ACTION_TECH_DISCOVERED ist ein Fallback für ACTION_NDEF_DISCOVERED, wenn keine Anwendungen nach ACTION_NDEF_DISCOVERED filtern oder wenn die Nutzlast nicht NDEF ist. Die Kategorie ACTION_TAG_DISCOVERED ist in der Regel zu allgemein, um nach ihr zu filtern. Viele Anwendungen filtern vor ACTION_TAG_DISCOVERED nach ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED. Die Wahrscheinlichkeit, dass Ihre Anwendung gestartet wird, ist also gering. ACTION_TAG_DISCOVERED steht nur als letzte Möglichkeit zum Filtern von Anwendungen zur Verfügung, in denen keine anderen Anwendungen zur Verarbeitung des Intents ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED installiert sind.

Da die NFC-Tag-Bereitstellung variiert und oft nicht von Ihnen gesteuert wird, ist dies nicht immer möglich. Daher können Sie bei Bedarf auf die anderen beiden Intents zurückgreifen. Wenn Sie die Typen der Tags und der geschriebenen Daten steuern können, sollten Sie Ihre Tags mit NDEF formatieren. In den folgenden Abschnitten wird beschrieben, wie Sie nach den einzelnen Arten von Intents filtern.

ACTION_NDEF_DISCOVERED

Wenn Sie nach ACTION_NDEF_DISCOVERED-Intents filtern möchten, deklarieren Sie den Intent-Filter zusammen mit dem Datentyp, nach dem Sie filtern möchten. Im folgenden Beispiel wird nach ACTION_NDEF_DISCOVERED-Intents mit dem MIME-Typ text/plain gefiltert:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
</intent-filter>

Im folgenden Beispiel wird nach einem URI in der Form https://developer.android.com/index.html gefiltert.

<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

Wenn Ihre Aktivität nach der ACTION_TECH_DISCOVERED-Intention filtert, müssen Sie eine XML-Ressourcendatei erstellen, in der die Technologien angegeben sind, die Ihre Aktivität in einem tech-list-Set unterstützt. Ihre Aktivität wird als Übereinstimmung betrachtet, wenn ein tech-list-Set eine Teilmenge der vom Tag unterstützten Technologien ist. Diese können Sie durch Aufrufen von getTechList() abrufen.

Wenn das gescannte Tag beispielsweise MifareClassic, NdefFormatable und NfcA unterstützt, müssen in Ihrem tech-list-Set alle drei, zwei oder eine der Technologien (und nichts anderes) angegeben werden, damit Ihre Aktivität abgeglichen werden kann.

Im folgenden Beispiel werden alle Technologien definiert. Sie müssen die entfernen, die von Ihrem NFC-Tag nicht unterstützt werden. Speichern Sie diese Datei (Sie können ihr einen beliebigen Namen geben) im Ordner <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>

Sie können auch mehrere tech-list-Gruppen angeben. Die einzelnen tech-list-Sätze werden unabhängig voneinander betrachtet. Ihre Aktivität wird als Übereinstimmung gewertet, wenn ein einzelner tech-list-Satz eine Teilmenge der Technologien ist, die von getTechList() zurückgegeben werden. Dies bietet AND- und OR-Semantik für Abgleichtechnologien. Im folgenden Beispiel werden Tags abgeglichen, die die NfcA- und Ndef-Technologien oder die NfcB- und Ndef-Technologien unterstützen können:

<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>

Geben Sie in der Datei AndroidManifest.xml die soeben erstellte Ressourcendatei im Element <meta-data> innerhalb des Elements <activity> an, wie im folgenden Beispiel:

<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>

Weitere Informationen zur Verwendung von Tag-Technologien und dem Intent ACTION_TECH_DISCOVERED finden Sie im Dokument zu erweiterten NFC unter Mit unterstützten Tag-Technologien arbeiten.

ACTION_TAG_DISCOVERED

Verwenden Sie den folgenden Intent-Filter, um nach ACTION_TAG_DISCOVERED zu filtern:

<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

Informationen aus Intents abrufen

Wenn eine Aktivität aufgrund eines NFC-Intents gestartet wird, können Sie über den Intent Informationen zum gescannten NFC-Tag abrufen. Je nach gescanntem Tag können Intents die folgenden Extras enthalten:

Um diese Extras zu erhalten, prüfen Sie, ob Ihre Aktivität mit einem der NFC-Intents gestartet wurde, um sicherzustellen, dass ein Tag gescannt wurde, und rufen Sie die Extras aus dem Intent ab. Im folgenden Beispiel wird nach dem Intent ACTION_NDEF_DISCOVERED gesucht und die NDEF-Nachrichten von einem Intent zusätzlich abgerufen.

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.
            ...
        }
    }
}

Alternativ können Sie über den Intent ein Tag-Objekt abrufen, das die Nutzlast enthält und mit dem Sie die Technologien des Tags auflisten können:

Kotlin

val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)

Java

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

Gängige NDEF-Eintragstypen erstellen

In diesem Abschnitt wird beschrieben, wie Sie gängige Arten von NDEF-Einträgen erstellen, um das Schreiben auf NFC-Tags zu erleichtern. Ab Android 4.0 (API-Level 14) ist die Methode createUri() zum automatischen Erstellen von URI-Einträgen verfügbar. Ab Android 4.1 (API-Ebene 16) sind createExternal() und createMime() verfügbar, um MIME- und externe NDEF-Einträge zu erstellen. Verwenden Sie nach Möglichkeit diese Hilfsmethoden, um Fehler beim manuellen Erstellen von NDEF-Einträgen zu vermeiden.

In diesem Abschnitt wird auch beschrieben, wie Sie den entsprechenden Intent-Filter für den Eintrag erstellen. Alle diese NDEF-Eintragsbeispiele sollten sich im ersten NDEF-Eintrag der NDEF-Nachricht befinden, die Sie in ein Tag schreiben.

TNF_ABSOLUTE_URI

Hinweis:Wir empfehlen, den Typ RTD_URI anstelle von TNF_ABSOLUTE_URI zu verwenden, da er effizienter ist.

So erstellen Sie einen TNF_ABSOLUTE_URI-NDEF-Eintrag:

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]);

Der Intent-Filter für den vorherigen NDEF-Eintrag würde so aussehen:

<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

So erstellen Sie einen NDEF-Eintrag für TNF_MIME_MEDIA:

createMime()-Methode verwenden:

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")));

NdefRecord manuell erstellen:

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")));

Der Intent-Filter für den vorherigen NDEF-Eintrag würde so aussehen:

<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 mit RTD_TEXT

So erstellen Sie einen TNF_WELL_KNOWN-NDEF-Eintrag:

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;
}

Der Intent-Filter für den vorherigen NDEF-Eintrag würde so aussehen:

<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 mit RTD_URI

So erstellen Sie einen NDEF-Eintrag für TNF_WELL_KNOWN:

Mithilfe der Methode createUri(String):

Kotlin

val rtdUriRecord1 = NdefRecord.createUri("https://example.com")

Java

NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");

createUri(Uri)-Methode verwenden:

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);

NdefRecord manuell erstellen:

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);

Der Intent-Filter für den vorherigen NDEF-Eintrag würde so aussehen:

<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

So erstellen Sie einen TNF_EXTERNAL_TYPE-NDEF-Eintrag:

createExternal()-Methode verwenden:

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);

NdefRecord manuell erstellen:

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);

Der Intent-Filter für den vorherigen NDEF-Eintrag würde so aussehen:

<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>

Verwenden Sie TNF_EXTERNAL_TYPE für allgemeinere NFC-Tag-Implementierungen, um sowohl Android- als auch Nicht-Android-Geräte besser zu unterstützen.

Hinweis: URNs für TNF_EXTERNAL_TYPE haben das kanonische Format urn:nfc:ext:example.com:externalType. In der RTD-Spezifikation des NFC-Forums wird jedoch festgelegt, dass der urn:nfc:ext:-Teil der URN im NDEF-Eintrag weggelassen werden muss. Sie müssen also nur die Domain (example.com im Beispiel) und den Typ (externalType im Beispiel) durch einen Doppelpunkt getrennt angeben. Beim Senden von TNF_EXTERNAL_TYPE wandelt Android die urn:nfc:ext:example.com:externalType -URN in einen vnd.android.nfc://ext/example.com:externalType-URI um, wie im Beispiel für den Intent-Filter angegeben.

Einträge zu Android-Apps

Ein Android Application Record (AAR), der in Android 4.0 (API-Level 14) eingeführt wurde, bietet eine größere Sicherheit, dass Ihre App gestartet wird, wenn ein NFC-Tag gescannt wird. Ein AAR enthält den Paketnamen einer Anwendung, der in einen NDEF-Eintrag eingebettet ist. Sie können jedem NDEF-Eintrag Ihrer NDEF-Nachricht einen AAR hinzufügen, da Android die gesamte NDEF-Nachricht nach AARs sucht. Wenn ein AAR gefunden wird, wird die Anwendung basierend auf dem Paketnamen im AAR gestartet. Wenn die App nicht auf dem Gerät vorhanden ist, wird Google Play gestartet, um die App herunterzuladen.

AARs sind nützlich, wenn Sie verhindern möchten, dass andere Anwendungen nach derselben Absicht filtern und möglicherweise bestimmte von Ihnen bereitgestellte Tags verarbeiten. AARs werden aufgrund der Einschränkung des Paketnamens nur auf Anwendungsebene unterstützt und nicht auf Aktivitätsebene wie beim Intent-Filter. Wenn Sie einen Intent auf Aktivitätsebene verarbeiten möchten, verwenden Sie Intent-Filter.

Wenn ein Tag einen AAR enthält, erfolgt der Versand durch das Tag-Dispatch-System auf folgende Weise:

  1. Versuchen Sie, wie gewohnt eine Aktivität mit einem Intent-Filter zu starten. Wenn die Aktivität, die mit dem Intent übereinstimmt, auch mit der AAR übereinstimmt, starten Sie die Aktivität.
  2. Wenn die Aktivität, die nach dem Intent gefiltert wird, nicht mit dem AAE übereinstimmt, wenn der Intent von mehreren Aktivitäten verarbeitet werden kann, oder wenn der Intent von keiner Aktivität verarbeitet wird, starten Sie die im AAE angegebene Anwendung.
  3. Wenn keine App mit automatisch angewendeten Empfehlungen beginnen kann, lade die entsprechende App bei Google Play herunter.

Hinweis:Sie können AARs und das Intent-Dispatch-System mit dem Dispatch-System für die Vordergrundaktivität überschreiben. Dadurch kann eine Aktivität im Vordergrund Vorrang haben, wenn ein NFC-Tag erkannt wird. Bei dieser Methode muss sich die Aktivität im Vordergrund befinden, um AAE und das Intent-Weiterleitungssystem zu überschreiben.

Wenn Sie weiterhin nach gescannten Tags filtern möchten, die keine AAR enthalten, können Sie Intent-Filter wie gewohnt deklarieren. Das ist nützlich, wenn Ihre Anwendung an anderen Tags interessiert ist, die keine AAR enthalten. Vielleicht möchten Sie beispielsweise dafür sorgen, dass Ihre Anwendung sowohl von Ihnen bereitgestellte eigene Tags als auch allgemeine Tags von Drittanbietern verarbeitet. Beachten Sie, dass AARs nur für Geräte mit Android 4.0 oder höher geeignet sind. Wenn Sie also Tags bereitstellen, sollten Sie am besten eine Kombination aus AARs und MIME-Typen/URIs verwenden, um möglichst viele Geräte zu unterstützen. Berücksichtigen Sie beim Bereitstellen von NFC-Tags auch, wie Sie sie beschreiben möchten, damit die meisten Geräte (Android- und andere Geräte) unterstützt werden. Dazu können Sie einen relativ eindeutigen MIME-Typ oder URI definieren, damit Anwendungen leichter unterschieden werden können.

Android bietet eine einfache API zum Erstellen von automatisch angewendeten Empfehlungen: createApplicationRecord(). Sie müssen den AAE lediglich an einer beliebigen Stelle in NdefMessage einbetten. Verwenden Sie den ersten Datensatz Ihrer NdefMessage nur, wenn der AAR der einzige Datensatz in der NdefMessage ist. Das liegt daran, dass das Android-System den ersten Eintrag einer NdefMessage prüft, um den MIME-Typ oder die URI des Tags zu ermitteln. Diese Informationen werden verwendet, um einen Intent für Anwendungen zu erstellen, der gefiltert werden soll. Im folgenden Code wird gezeigt, wie eine AAR erstellt wird:

Kotlin

val msg = NdefMessage(
        arrayOf(
                ...,
                NdefRecord.createApplicationRecord("com.example.android.beam")
        )
)

Java

NdefMessage msg = new NdefMessage(
        new NdefRecord[] {
            ...,
            NdefRecord.createApplicationRecord("com.example.android.beam")}
        );
)