Erweiterte NFC – Übersicht

In diesem Dokument werden fortgeschrittene NFC-Themen wie die Arbeit mit verschiedenen Tag-Technologien beschrieben. das Schreiben in NFC-Tags und das Weiterleiten im Vordergrund, wodurch eine Anwendung im Vordergrund Intents auch dann verarbeiten, wenn andere Anwendungen nach denselben filtern.

Unterstützte Tag-Technologien verwenden

Bei der Arbeit mit NFC-Tags und Android-Geräten wird das Hauptformat zum Lesen und „Daten in Tags schreiben“ ist NDEF. Wenn ein Gerät ein Tag mit NDEF-Daten scannt, unterstützt Android beim Parsen und Zustellen der Nachricht in einem NdefMessage, wenn möglich. Es gibt jedoch Fälle, in denen Sie ein Tag scannen, das keine NDEF-Daten oder wenn die NDEF-Daten keinem MIME-Typ oder URI zugeordnet werden konnten. In diesen Fällen müssen Sie die Kommunikation direkt mit dem Tag öffnen und mit Ihr eigenes Protokoll (in Rohbyte) Android bietet generische Unterstützung für diese Anwendungsfälle mit der android.nfc.tech-Paket, das in Tabelle 1 beschrieben wird. Sie können Verwenden Sie die Methode getTechList(), um die Technologien zu bestimmen. vom Tag unterstützt wird, und erstellen Sie die entsprechende TagTechnology Objekt mit einer der von android.nfc.tech bereitgestellten Klassen

Tabelle 1 Unterstützte Tag-Technologien

Klasse Beschreibung
TagTechnology Die Schnittstelle, die von allen Tag-Technologieklassen implementiert werden muss.
NfcA Bietet Zugriff auf NFC-A-Eigenschaften (ISO 14443-3A) und E/A-Vorgänge.
NfcB Bietet Zugriff auf NFC-B-Eigenschaften (ISO 14443-3B) und E/A-Vorgänge.
NfcF Bietet Zugriff auf NFC-F-Eigenschaften (JIS 6319-4) und E/A-Vorgänge.
NfcV Bietet Zugriff auf NFC-V-Eigenschaften (ISO 15693) und E/A-Vorgänge.
IsoDep Bietet Zugriff auf ISO-DEP-Eigenschaften (ISO 14443-4) und E/A-Vorgänge.
Ndef Bietet Zugriff auf NDEF-Daten und Vorgänge für NFC-Tags, die als NDEF
NdefFormatable Stellt Formatvorgänge für Tags bereit, die NDEF-formatierbar sein können.

Die folgenden Tag-Technologien müssen von Android-Geräten nicht unterstützt werden.

Tabelle 2: Optional unterstützte Tag-Technologien

Klasse Beschreibung
MifareClassic Bietet Zugriff auf MIFARE Classic-Properties und E/A-Vorgänge, wenn dieses Android-Gerät verwendet wird unterstützt MIFARE.
MifareUltralight Bietet Zugriff auf MIFARE Ultralight-Eigenschaften und E/A-Vorgänge, wenn dieses Android-Gerät Gerät MIFARE unterstützt.

Tag-Technologien und den Intent ACTION_TECH_DISCOVERED verwenden

Wenn ein Gerät ein Tag scannt, das NDEF-Daten enthält, aber keinem MIME oder URI zugeordnet werden konnte, versucht das Tag-Weiterleitungssystem, eine Aktivität mit der ACTION_TECH_DISCOVERED zu starten. die Nutzerabsicht verstehen. ACTION_TECH_DISCOVERED wird auch verwendet, wenn ein Tag mit Nicht-NDEF-Daten werden gescannt. Mit diesem Fallback können Sie mit den Daten im Tag arbeiten, wenn das Tag-Weiterleitungssystem sie nicht für Sie parsen konnte. Die grundlegenden Schritte bei der Arbeit mit sind folgende Tag-Technologien:

  1. Filtern Sie nach einem ACTION_TECH_DISCOVERED-Intent, der Folgendes angibt: die Sie verarbeiten möchten. Siehe Filter für NFC Intents. Im Allgemeinen versucht das Tag-Weiterleitungssystem, einen ACTION_TECH_DISCOVERED-Intent zu starten, wenn eine NDEF-Nachricht darf keinem MIME-Typ oder URI zugeordnet werden oder wenn das gescannte Tag keine NDEF-Daten enthielt. Für Weitere Informationen zur Ermittlung dieses Werts finden Sie unter Tag-Versandsystem.
  2. Wenn Ihre Anwendung den Intent empfängt, rufen Sie das Tag-Objekt von die Absicht haben:

    Kotlin

    var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
    

    Java

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    
  3. Rufen Sie eine TagTechnology-Instanz ab, indem Sie eine der get-Factory-Methoden der Klassen im android.nfc.tech-Paket. Sie können Führen Sie die unterstützten Technologien des Tags auf, indem Sie getTechList() und dann eine get-Factory-Methode aufrufen. Um z. B. eine Instanz abzurufen, von MifareUltralight aus einem Tag:

    Kotlin

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
    

    Java

    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
    

Tags lesen und in Tags schreiben

Beim Lesen und Schreiben eines NFC-Tags wird das Tag vom Intent abgerufen um die Kommunikation mit dem Tag zu öffnen. Sie müssen einen eigenen Protokollstack definieren, um Daten lesen und schreiben zu können hinzugefügt. Denken Sie jedoch daran, dass Sie NDEF-Daten weiterhin lesen und schreiben können, wenn Sie direkt mit einem Tag. Es liegt an Ihnen, wie Sie die Dinge strukturieren möchten. Die Das folgende Beispiel zeigt, wie Sie mit einem MIFARE Ultralight-Tag arbeiten.

Kotlin

package com.example.android.nfc
import android.nfc.Tag
import android.nfc.tech.MifareUltralight
import java.io.IOException
import java.nio.charset.Charset

class MifareUltralightTagTester {

    fun writeTag(tag: Tag, tagText: String) {
        MifareUltralight.get(tag)?.use { ultralight ->
            ultralight.connect()
            Charset.forName("US-ASCII").also { usAscii ->
                ultralight.writePage(4, "abcd".toByteArray(usAscii))
                ultralight.writePage(5, "efgh".toByteArray(usAscii))
                ultralight.writePage(6, "ijkl".toByteArray(usAscii))
                ultralight.writePage(7, "mnop".toByteArray(usAscii))
            }
        }
    }

    fun readTag(tag: Tag): String? {
        return MifareUltralight.get(tag)?.use { mifare ->
            mifare.connect()
            val payload = mifare.readPages(4)
            String(payload, Charset.forName("US-ASCII"))
        }
    }
}

Java

package com.example.android.nfc;

import android.nfc.Tag;
import android.nfc.tech.MifareUltralight;
import android.util.Log;
import java.io.IOException;
import java.nio.charset.Charset;

public class MifareUltralightTagTester {

    private static final String TAG = MifareUltralightTagTester.class.getSimpleName();

    public void writeTag(Tag tag, String tagText) {
        MifareUltralight ultralight = MifareUltralight.get(tag);
        try {
            ultralight.connect();
            ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII")));
            ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII")));
        } catch (IOException e) {
            Log.e(TAG, "IOException while writing MifareUltralight...", e);
        } finally {
            try {
                ultralight.close();
            } catch (IOException e) {
                Log.e(TAG, "IOException while closing MifareUltralight...", e);
            }
        }
    }

    public String readTag(Tag tag) {
        MifareUltralight mifare = MifareUltralight.get(tag);
        try {
            mifare.connect();
            byte[] payload = mifare.readPages(4);
            return new String(payload, Charset.forName("US-ASCII"));
        } catch (IOException e) {
            Log.e(TAG, "IOException while reading MifareUltralight message...", e);
        } finally {
            if (mifare != null) {
               try {
                   mifare.close();
               }
               catch (IOException e) {
                   Log.e(TAG, "Error closing tag...", e);
               }
            }
        }
        return null;
    }
}

Weiterleitungssystem im Vordergrund verwenden

Das Weiterleitungssystem im Vordergrund ermöglicht es einer Aktivität, einen Intent und einen Anspruch abzufangen Vorrang vor anderen Aktivitäten mit demselben Intent. Die Verwendung dieses Systems umfasst einige Datenstrukturen für das Android-System konstruieren, Intents zu Ihrer Anwendung hinzufügen. So aktivieren Sie das Weiterleitungssystem im Vordergrund:

  1. Fügen Sie den folgenden Code in die onCreate()-Methode Ihrer Aktivität ein: <ph type="x-smartling-placeholder">
      </ph>
    1. Änderbares PendingIntent-Objekt erstellen, damit es vom Android-System befüllt werden kann mit den Details des Tags an, wenn es gescannt wird.

      Kotlin

      val intent = Intent(this, javaClass).apply {
          addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
      }
      var pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent,
              PendingIntent.FLAG_MUTABLE)
      

      Java

      PendingIntent pendingIntent = PendingIntent.getActivity(
          this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
          PendingIntent.FLAG_MUTABLE);
      
    2. Deklarieren Sie Intent-Filter, um die Intents zu verarbeiten, die Sie abfangen möchten. Vordergrund Weiterleitungssystem prüft die angegebenen Intent-Filter mit dem Intent, der empfangen wird, wenn scannt das Gerät ein Tag. Bei einer Übereinstimmung verarbeitet Ihre Anwendung den Intent. Falls ja, nicht übereinstimmen, greift das Weiterleitungssystem im Vordergrund auf das Intent-Weiterleitungssystem zurück. Wenn Sie ein null-Array von Intent-Filtern und Technologiefiltern angeben, wird Folgendes angegeben: nach allen Tags filtern möchten, die auf TAG_DISCOVERED die Nutzerabsicht verstehen. Das folgende Code-Snippet verarbeitet alle MIME-Typen für NDEF_DISCOVERED. Ich die Sie benötigen.

      Kotlin

      val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
          try {
              addDataType("*/*")    /* Handles all MIME based dispatches.
                                       You should specify only the ones that you need. */
          } catch (e: IntentFilter.MalformedMimeTypeException) {
              throw RuntimeException("fail", e)
          }
      }
      
      intentFiltersArray = arrayOf(ndef)
      

      Java

      IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
          try {
              ndef.addDataType("*/*");    /* Handles all MIME based dispatches.
                                             You should specify only the ones that you need. */
          }
          catch (MalformedMimeTypeException e) {
              throw new RuntimeException("fail", e);
          }
         intentFiltersArray = new IntentFilter[] {ndef, };
      
    3. Richten Sie ein Array mit Tag-Technologien ein, die Ihre Anwendung verarbeiten möchte. Rufen Sie die Methode Object.class.getName()-Methode, um die Klasse der Technologie abzurufen, die Sie die Sie unterstützen möchten.

      Kotlin

      techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
      

      Java

      techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
      
  2. Überschreiben Sie die folgenden Aktivitätslebenszyklus-Callbacks und fügen Sie Logik zum Aktivieren und Deaktivieren der Weiterleitung im Vordergrund, wenn die Aktivität abbricht (onPause()) und wieder (onResume()) konzentriert. enableForegroundDispatch() muss aufgerufen werden von im Hauptthread und nur dann, wenn die Aktivität im Vordergrund ausgeführt wird. Ein Aufruf in onResume() garantiert dies. Außerdem musst du den onNewIntent-Callback implementieren, um die Daten aus der gescannten NFC-Funktion zu verarbeiten. Tag.
  3. Kotlin

    public override fun onPause() {
        super.onPause()
        adapter.disableForegroundDispatch(this)
    }
    
    public override fun onResume() {
        super.onResume()
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
    }
    
    public override fun onNewIntent(intent: Intent) {
        val tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        // do something with tagFromIntent
    }
    

    Java

    public void onPause() {
        super.onPause();
        adapter.disableForegroundDispatch(this);
    }
    
    public void onResume() {
        super.onResume();
        adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
    }
    
    public void onNewIntent(Intent intent) {
        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        // do something with tagFromIntent
    }