NFC – Grundlagen

In diesem Dokument werden die grundlegenden NFC-Aufgaben beschrieben, die Sie in Android ausführen. Darin wird erläutert, wie NFC-Daten in Form von NDEF-Nachrichten gesendet und empfangen werden, und die Android-Framework-APIs beschrieben, die diese Funktionen unterstützen. Weiterführende Themen, einschließlich einer Erläuterung zum Arbeiten mit Nicht-NDEF-Daten, finden Sie unter Erweiterte NFC-Funktionen.

Das Lesen von NDEF-Daten aus einem NFC-Tag wird über das Tag-Dispatch-System abgewickelt. Dieses analysiert erkannte NFC-Tags, kategorisiert die Daten entsprechend und startet eine Anwendung, die sich für die kategorisierten Daten interessiert. 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 in der Regel nach NFC-Tags, wenn der Bildschirm entsperrt ist, es sei denn, NFC ist in den Geräteeinstellungen deaktiviert. Wenn ein Android-Gerät ein NFC-Tag erkennt, soll die am besten geeignete Aktivität den Intent verarbeiten, ohne den Nutzer zu fragen, welche Anwendung verwendet werden soll. Da Geräte NFC-Tags in sehr kurzer Entfernung scannen, müssten Nutzer das Gerät wahrscheinlich vom Tag entfernen und die Verbindung unterbrechen, wenn sie eine Aktivität manuell auswählen müssten. Sie sollten Ihre Aktivität so entwickeln, dass nur die NFC-Tags verarbeitet werden, die für Ihre Aktivität relevant sind, damit die Aktivitätsauswahl nicht angezeigt wird.

Um Sie bei diesem Ziel zu unterstützen, bietet Android ein spezielles Tag-Dispatch-System, das gescannte NFC-Tags analysiert, parst und versucht, Anwendungen zu finden, die an den gescannten Daten interessiert sind. Das funktioniert so:

  1. Das NFC-Tag wird geparst und der MIME-Typ oder ein URI, der die Daten-Payload im Tag identifiziert, wird ermittelt.
  2. MIME-Typ oder URI und Nutzlast in einem Intent kapseln. Die ersten beiden Schritte werden unter NFC-Tags MIME-Typen und URIs zuordnen beschrieben.
  3. Startet eine Aktivität basierend auf dem Intent. Dies wird unter NFC-Tags an Anwendungen senden beschrieben.

Zuordnung von NFC-Tags zu MIME-Typen und URIs

Bevor Sie mit dem Schreiben von NFC-Anwendungen beginnen, sollten Sie sich mit den verschiedenen Arten von NFC-Tags, der Art und Weise, wie das Tag-Dispatch-System NFC-Tags parst, und den besonderen Aufgaben vertraut machen, die das Tag-Dispatch-System ausführt, wenn es eine NDEF-Nachricht erkennt. NFC-Tags sind in einer Vielzahl von Technologien verfügbar und können auf viele verschiedene Arten beschrieben werden. Android bietet die beste Unterstützung für den NDEF-Standard, der vom NFC-Forum definiert wird.

NDEF-Daten werden in einer Nachricht (NdefMessage) gekapselt, die einen oder mehrere Einträge (NdefRecord) enthält. Jeder NDEF-Eintrag muss gemäß der Spezifikation des Typs des Eintrags, den Sie erstellen möchten, wohlgeformt sein. Android unterstützt auch andere Arten von Tags, die keine NDEF-Daten enthalten. Sie können mit den Klassen im Paket android.nfc.tech darauf zugreifen. Weitere Informationen zu diesen Technologien finden Sie im Thema Erweiterte NFC-Funktionen. Für die Verwendung dieser anderen Arten von Tags müssen Sie einen eigenen Protokollstapel schreiben, um mit den Tags zu kommunizieren. Wir empfehlen daher, NDEF zu verwenden, wenn möglich, um die Entwicklung zu vereinfachen und die Unterstützung für Android-Geräte zu maximieren.

Hinweis:Wenn Sie vollständige NDEF-Spezifikationen herunterladen möchten, rufen Sie die Website NFC Forum Specifications & Application Documents auf. Beispiele für das Erstellen von NDEF-Einträgen finden Sie unter Creating common types of NDEF records.

Nachdem Sie nun einige Grundlagen zu NFC-Tags kennengelernt haben, wird in den folgenden Abschnitten genauer 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 es wird versucht, den MIME-Typ oder den identifizierenden URI der Daten zu ermitteln. Dazu wird das erste NdefRecord im NdefMessage gelesen, um zu bestimmen, wie die gesamte NDEF-Nachricht interpretiert werden soll. Eine NDEF-Nachricht kann mehrere NDEF-Einträge enthalten. In einer wohlgeformten NDEF-Nachricht enthält der erste NdefRecord die folgenden Felder:

3-Bit-TNF (Type Name Format)
Gibt an, wie das Feld für den Typ mit variabler Länge zu interpretieren ist. Gültige Werte werden in Tabelle 1 beschrieben.
Typ mit variabler Länge
Beschreibt den Typ des Datensatzes. Wenn Sie TNF_WELL_KNOWN verwenden, geben Sie mit diesem Feld die Definition des Datensatztyps (Record Type Definition, RTD) an. Gültige RTD-Werte werden in Tabelle 2 beschrieben.
ID mit variabler Länge
Eindeutige Kennung für den Datensatz. Dieses Feld wird nicht oft verwendet. Wenn Sie ein Tag jedoch eindeutig identifizieren müssen, können Sie eine ID dafür erstellen.
Nutzlast variabler Länge
Die tatsächliche Daten-Payload, die Sie lesen oder schreiben möchten. Eine NDEF-Nachricht kann mehrere NDEF-Einträge enthalten. Gehen Sie daher nicht davon aus, dass sich die gesamte Nutzlast im ersten NDEF-Eintrag der NDEF-Nachricht befindet.

Das Tag-Versandsystem verwendet die Felder „TNF“ und „Type“, um zu versuchen, einen MIME-Typ oder URI der NDEF-Nachricht zuzuordnen. Wenn der Vorgang erfolgreich ist, werden diese Informationen zusammen mit der eigentlichen Nutzlast in einem ACTION_NDEF_DISCOVERED-Intent gekapselt. Es gibt jedoch Fälle, in denen das Tag-Versandsystem den Datentyp nicht anhand des ersten NDEF-Datensatzes bestimmen kann. Das passiert, wenn die NDEF-Daten nicht einem MIME-Typ oder URI zugeordnet werden können oder wenn das NFC-Tag von vornherein 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 einem ACTION_TECH_DISCOVERED-Intent gekapselt.

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

Wenn das Tag-Versandsystem beispielsweise auf einen Datensatz vom Typ TNF_ABSOLUTE_URI trifft, wird das Feld mit variabler Länge dieses Datensatzes in einen URI umgewandelt. Das Tag-Dispatch-System kapselt diesen URI im Datenfeld eines ACTION_NDEF_DISCOVERED-Intents zusammen mit anderen Informationen zum Tag, z. B. der Nutzlast. Wenn der Code jedoch auf einen Datensatz vom Typ TNF_UNKNOWN trifft, wird stattdessen eine Absicht erstellt, die die Technologien des Tags umfasst.

Tabelle 1 Unterstützte TNFs und ihre Zuordnungen

Typnameformat (TNF) Zuordnung
TNF_ABSOLUTE_URI URI basierend auf dem Typfeld.
TNF_EMPTY Fällt auf ACTION_TECH_DISCOVERED zurück.
TNF_EXTERNAL_TYPE URI basierend auf dem URN im Typfeld. Die URN wird in einer gekürzten Form im NDEF-Typfeld codiert: <domain_name>:<service_name>. Unter Android wird dies einem URI im folgenden Format zugeordnet: vnd.android.nfc://ext/<domain_name>:<service_name>.
TNF_MIME_MEDIA MIME-Typ basierend auf dem Typfeld.
TNF_UNCHANGED Ungültig im ersten Datensatz, daher wird auf ACTION_TECH_DISCOVERED zurückgegriffen.
TNF_UNKNOWN Fällt auf ACTION_TECH_DISCOVERED zurück.
TNF_WELL_KNOWN MIME-Typ oder URI, je nach der Definition des Datensatztyps (Record Type Definition, RTD), die Sie im Feld „type“ 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

Definition des Eintragstyps (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 Fällt auf ACTION_TECH_DISCOVERED zurück.
RTD_SMART_POSTER URI basierend auf dem Parsen der Nutzlast.
RTD_TEXT MIME-Typ von text/plain.
RTD_URI URI basierend auf der Nutzlast.

So werden NFC-Tags an Anwendungen gesendet

Wenn das Tag-Dispatch-System einen Intent erstellt hat, der das NFC-Tag und seine Identifikationsinformationen enthält, wird der Intent an eine interessierte Anwendung gesendet, die nach dem Intent filtert. Wenn mehr als eine Anwendung den Intent verarbeiten kann, 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 der höchsten zur niedrigsten Priorität aufgeführt sind:

  1. ACTION_NDEF_DISCOVERED: Mit dieser Absicht wird eine Aktivität gestartet, wenn ein Tag mit einer NDEF-Nutzlast gescannt wird und einen erkannten Typ hat. Dies ist die Intention mit der höchsten Priorität. Das Tag-Versandsystem versucht, eine Aktivität mit dieser Intention zu starten, bevor es eine andere Intention verwendet.

    Hinweis:Ab Android 16 wird beim Scannen von NFC-Tags, in denen URL-Links gespeichert sind (d. h. das URI-Schema ist „https://“ oder „http://“), der Intent ACTION_VIEW anstelle des Intents ACTION_NDEF_DISCOVERED ausgelöst.

  2. ACTION_TECH_DISCOVERED: Wenn keine Aktivitäten registriert sind, um den ACTION_NDEF_DISCOVERED-Intent zu verarbeiten, versucht das Tag-Versandsystem, eine Anwendung mit diesem Intent zu starten. Diese Intention wird auch direkt gestartet (ohne ACTION_NDEF_DISCOVERED zu starten), wenn das gescannte Tag NDEF-Daten enthält, die keinem MIME-Typ oder URI zugeordnet werden können, oder wenn das Tag keine NDEF-Daten enthält, aber eine bekannte Tag-Technologie ist.
  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-Versandsystem im Grunde:

  1. Versuchen Sie, eine Aktivität mit dem Intent zu starten, der vom Tag-Dispatch-System beim Parsen des NFC-Tags erstellt wurde (entweder ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED).
  2. Wenn kein Aktivitätsfilter für diese Intention vorhanden ist, versuchen Sie, eine Aktivität mit der Intention mit der nächstniedrigsten Priorität (entweder ACTION_TECH_DISCOVERED oder ACTION_TAG_DISCOVERED) zu starten, bis eine Anwendung die Intention filtert oder das Tag-Dispatch-System alle möglichen Intentionen ausprobiert hat.
  3. Wenn für keinen der Intents Anwendungsfilter vorhanden sind, tun Sie nichts.
Abbildung 1. Tag Dispatch System

Verwenden Sie nach Möglichkeit NDEF-Nachrichten und die ACTION_NDEF_DISCOVERED-Absicht, da sie die spezifischste der drei ist. Mit dieser Absicht können Sie Ihre Anwendung zu einem geeigneteren Zeitpunkt als bei den beiden anderen Absichten starten, was zu einer besseren Nutzererfahrung führt.

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 Datei AndroidManifest.xml deklarieren:

  • Das NFC-Element <uses-permission> für den Zugriff auf die NFC-Hardware:
    <uses-permission android:name="android.permission.NFC" />
  • Die Mindest-SDK-Version, die von Ihrer Anwendung unterstützt werden kann. API-Level 9 unterstützt nur eingeschränkte Tag-Weiterleitung über ACTION_TAG_DISCOVERED und bietet nur über das Extra EXTRA_NDEF_MESSAGES Zugriff auf NDEF-Nachrichten. Auf andere Tag-Attribute oder E/A-Vorgänge kann nicht zugegriffen werden. API-Level 10 umfasst umfassende Unterstützung für Reader/Writer sowie das Pushen von NDEF im Vordergrund. API-Level 14 bietet zusätzliche Convenience-Methoden zum Erstellen von NDEF-Datensätzen.
    <uses-sdk android:minSdkVersion="10"/>
  • Das uses-feature-Element, damit Ihre Anwendung 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 aber nicht entscheidend für die Anwendung sind, können Sie das uses-feature-Element weglassen und die NFC-Verfügbarkeit zur Laufzeit prüfen, indem Sie prüfen, ob getDefaultAdapter() null ist.

Nach NFC-Intents filtern

Wenn Ihre Anwendung gestartet werden soll, wenn ein NFC-Tag gescannt wird, das Sie verarbeiten möchten, kann Ihre Anwendung im Android-Manifest nach einem, zwei oder allen drei NFC-Intents filtern. Normalerweise sollten Sie jedoch nach dem Intent ACTION_NDEF_DISCOVERED filtern, um die größtmögliche Kontrolle darüber zu haben, wann Ihre Anwendung gestartet wird. Der Intent ACTION_TECH_DISCOVERED ist ein Fallback für ACTION_NDEF_DISCOVERED, wenn keine Anwendungen für ACTION_NDEF_DISCOVERED gefiltert werden oder wenn die Nutzlast nicht NDEF ist. Das Filtern nach ACTION_TAG_DISCOVERED ist in der Regel zu allgemein. Viele Anwendungen filtern vor ACTION_TAG_DISCOVERED nach ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED. Daher ist die Wahrscheinlichkeit, dass Ihre Anwendung gestartet wird, gering. ACTION_TAG_DISCOVERED ist nur als letzter Ausweg für Anwendungen verfügbar, die gefiltert werden sollen, wenn keine anderen Anwendungen installiert sind, die den Intent ACTION_NDEF_DISCOVERED oder ACTION_TECH_DISCOVERED verarbeiten können.

Da NFC-Tag-Bereitstellungen variieren und oft nicht in Ihrer Hand liegen, ist dies nicht immer möglich. Daher können Sie bei Bedarf auf die beiden anderen Intents zurückgreifen. Wenn Sie die Arten von Tags und Daten, die geschrieben werden, selbst bestimmen können, empfehlen wir, Ihre Tags mit NDEF zu formatieren. In den folgenden Abschnitten wird beschrieben, wie Sie nach den einzelnen Intentionstypen 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 im Format 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 dem Intent ACTION_TECH_DISCOVERED 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 gilt als Übereinstimmung, wenn ein tech-list-Satz eine Teilmenge der Technologien ist, die vom Tag unterstützt werden. Diese können Sie durch Aufrufen von getTechList() abrufen.

Wenn das gescannte Tag beispielsweise MifareClassic, NdefFormatable und NfcA unterstützt, muss in Ihrem tech-list-Set mindestens eine dieser Technologien angegeben sein, damit Ihre Aktivität zugeordnet werden kann.

Im folgenden Beispiel werden alle Technologien definiert. Sie müssen die Tags 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-Sets angeben. Jeder der tech-list-Sätze wird unabhängig voneinander betrachtet. Ihre Aktivität gilt als Übereinstimmung, 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 Matching-Technologien. Im folgenden Beispiel werden Tags abgeglichen, die die Technologien „NfcA“ und „Ndef“ oder „NfcB“ und „Ndef“ 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 Ihrer AndroidManifest.xml-Datei die gerade erstellte Ressourcendatei im <meta-data>-Element innerhalb des <activity>-Elements 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 zum Arbeiten mit Tag-Technologien und der ACTION_TECH_DISCOVERED-Absicht finden Sie im Dokument „NFC für Fortgeschrittene“ 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>

ACTION_VIEW

Ab Android 16 wird beim Scannen von NFC-Tags, in denen URL-Links gespeichert sind, der Intent ACTION_VIEW ausgelöst. Informationen zum Filtern nach ACTION_VIEW finden Sie unter this. Verwenden Sie Android app links, um Ihre App für die URL zu öffnen.

Informationen aus Intents abrufen

Wenn eine Aktivität aufgrund eines NFC-Intents gestartet wird, können Sie Informationen zum gescannten NFC-Tag aus dem Intent abrufen. Intents können je nach gescanntem Tag 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. Rufen Sie die Extras dann aus dem Intent ab. Im folgenden Beispiel wird nach dem Intent ACTION_NDEF_DISCOVERED gesucht und die NDEF-Nachrichten aus einem Intent-Extra 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 ein Tag-Objekt aus dem Intent abrufen, das die Nutzlast enthält und mit dem Sie die Technologien des Tags aufzählen können:

Kotlin

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

Java

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

Häufige NDEF-Einträge erstellen

In diesem Abschnitt wird beschrieben, wie Sie gängige NDEF-Datensätze erstellen, um das Schreiben auf NFC-Tags zu erleichtern. Ab Android 4.0 (API-Level 14) ist die Methode createUri() verfügbar, mit der Sie URI-Datensätze automatisch erstellen können. Ab Android 4.1 (API-Level 16) sind createExternal() und createMime() verfügbar, mit denen Sie NDEF-Einträge für MIME- und externe Typen erstellen können. Verwenden Sie diese Hilfsmethoden nach Möglichkeit, um Fehler beim manuellen Erstellen von NDEF-Datensätzen zu vermeiden.

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

TNF_ABSOLUTE_URI

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

So erstellen Sie einen TNF_ABSOLUTE_URI-NDEF-Datensatz:

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

Sie haben folgende Möglichkeiten, einen TNF_MIME_MEDIA-NDEF-Datensatz zu erstellen:

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

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

Sie haben folgende Möglichkeiten, einen TNF_WELL_KNOWN-NDEF-Datensatz zu erstellen:

createUri(String)-Methode verwenden:

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 können Sie einen TNF_EXTERNAL_TYPE-NDEF-Datensatz erstellen:

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-Bereitstellungen, 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. Die RTD-Spezifikation des NFC-Forums besagt jedoch, dass der urn:nfc:ext:-Teil der URN aus dem NDEF-Datensatz entfernt werden muss. Sie müssen also nur die Domain (example.com im Beispiel) und den Typ (externalType im Beispiel) angeben, getrennt durch einen Doppelpunkt. Beim Senden von TNF_EXTERNAL_TYPE konvertiert Android den urn:nfc:ext:example.com:externalType -URN in einen vnd.android.nfc://ext/example.com:externalType-URI, der im Beispiel im Intent-Filter deklariert wird.

Einträge für Android-Apps

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

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

Wenn ein Tag ein AAR enthält, wird es vom Tag-Dispatch-System so weitergeleitet:

  1. Versuchen Sie, eine Aktivität wie gewohnt mit einem Intent-Filter zu starten. Wenn die Aktivität, die dem Intent entspricht, auch dem AAR entspricht, starten Sie die Aktivität.
  2. Wenn die Aktivität, die nach dem Intent filtert, nicht mit dem AAR übereinstimmt, wenn mehrere Aktivitäten den Intent verarbeiten können oder wenn keine Aktivität den Intent verarbeitet, starten Sie die im AAR angegebene Anwendung.
  3. Wenn keine Anwendung mit dem AAR gestartet werden kann, rufen Sie Google Play auf, um die Anwendung anhand des AAR herunterzuladen.

Hinweis:Sie können AARs und das Intent-Dispatch-System mit dem Foreground-Dispatch-System überschreiben. Dadurch kann eine Foreground-Aktivität Priorität haben, wenn ein NFC-Tag erkannt wird. Bei dieser Methode muss die Aktivität im Vordergrund sein, um AARs und das Intent-Dispatch-System zu überschreiben.

Wenn Sie weiterhin nach gescannten Tags filtern möchten, die keinen 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 sicherstellen, dass Ihre Anwendung sowohl eigene Tags, die Sie bereitstellen, als auch allgemeine Tags, die von Drittanbietern bereitgestellt werden, verarbeitet. AARs sind nur für Geräte mit Android 4.0 oder höher verfügbar. Wenn Sie Tags bereitstellen, sollten Sie daher eine Kombination aus AARs und MIME-Typen/URIs verwenden, um möglichst viele Geräte zu unterstützen. Wenn Sie NFC-Tags bereitstellen, sollten Sie außerdem darüber nachdenken, wie Sie die NFC-Tags schreiben möchten, um die Unterstützung für die meisten Geräte (Android-Geräte und andere Geräte) zu ermöglichen. Dazu können Sie einen relativ eindeutigen MIME-Typ oder URI definieren, damit Anwendungen die Inhalte leichter unterscheiden können.

Android bietet eine einfache API zum Erstellen einer AAR-Datei, createApplicationRecord(). Sie müssen die AAR nur an einer beliebigen Stelle in Ihre NdefMessage einbetten. Sie sollten nicht den ersten Datensatz Ihres NdefMessage verwenden, es sei denn, der AAR ist der einzige Datensatz im NdefMessage. Das liegt daran, dass das Android-System den ersten Datensatz eines NdefMessage prüft, um den MIME-Typ oder URI des Tags zu ermitteln. Dieser wird verwendet, um einen Intent für Anwendungen zu erstellen, nach dem gefiltert werden kann. Der folgende Code zeigt, wie Sie eine AAR erstellen:

Kotlin

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

Java

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

Zulassungsliste für Apps für das Scannen von NFC-Tags

Ab Android 16 werden Nutzer benachrichtigt, wenn eine App zum ersten Mal eine NFC-Absicht zum Scannen von NFC-Tags empfängt. In der Benachrichtigung hat der Nutzer die Möglichkeit, der App zu verbieten, weiterhin nach NFC-Tags zu suchen.

Hinweis:Die Zulassungsliste für NFC-Tag-Scan-Apps ist unter Settings > Apps > Special app access > Launch via NFC verfügbar.

Dieser Mechanismus wurde hinzugefügt, um Bedenken von Nutzern auszuräumen, bei denen einige Apps, die Intent-Filter für NFC-Tag-Intents registriert hatten, wiederholt in den Vordergrund gerückt wurden, wenn sie das Smartphone neben einen NFC-Tag (Kreditkarte, anderes Smartphone/Smartwatch usw.) hielten.