Nozioni di base su NFC

In questo documento vengono descritte le attività NFC di base che esegui in Android. Spiega come inviare e ricevere dati NFC sotto forma di messaggi NDEF e descrive le API del framework Android che supportano queste funzionalità. Per argomenti più avanzati, inclusa una discussione sull'utilizzo di dati non NDEF, consulta NFC avanzato.

La lettura dei dati NDEF da un tag NFC viene gestita con il sistema di invio dei tag, che analizza i tag NFC rilevati, classifica i dati in modo appropriato e avvia un'applicazione interessata ai dati classificati. Un'applicazione che vuole gestire il tag NFC scansionato può dichiarare un filtro intent e richiedere di gestire i dati.

Il sistema di invio tag

I dispositivi Android in genere cercano i tag NFC quando lo schermo è sbloccato, a meno che l'NFC non sia disattivato nel menu Impostazioni del dispositivo. Quando un dispositivo Android rileva un tag NFC, il comportamento desiderato è che l'attività più appropriata gestisca l'intento senza chiedere all'utente quale applicazione utilizzare. Poiché i dispositivi scansionano i tag NFC a un raggio molto ridotto, è probabile che chiedere agli utenti di selezionare manualmente un'attività li costringa a allontanare il dispositivo dal tag e a interrompere la connessione. Per impedire la visualizzazione del selettore di attività, devi sviluppare la tua attività in modo da gestire solo i tag NFC che ti interessano.

Per aiutarti a raggiungere questo obiettivo, Android fornisce un sistema speciale di invio dei tag che analizza i tag NFC scansionati, li analizza e tenta di individuare le applicazioni interessate ai dati scansionati. Lo fa in quanto:

  1. Analizza il tag NFC e individua il tipo MIME o un URI che identifica il payload dei dati nel tag.
  2. Incapsulare il tipo MIME o l'URI e il payload in un'intenzione. Questi primi due passaggi sono descritti in Come i tag NFC vengono mappati a tipi MIME e URI.
  3. Avvia un'attività in base all'intent. Come descritto in Come vengono inviati i tag NFC alle applicazioni.

Come i tag NFC vengono mappati a tipi MIME e URI

Prima di iniziare a scrivere le applicazioni NFC, è importante comprendere i diversi tipi di tag NFC, come il sistema di invio dei tag analizza i tag NFC e il lavoro speciale svolto dal sistema di invio dei tag quando rileva un messaggio NDEF. I tag NFC sono disponibili in una vasta gamma di tecnologie e possono anche essere scritti in molti modi diversi. Android offre il maggior supporto per lo standard NDEF, definito dal NFC Forum.

I dati NDEF sono incapsulati all'interno di un messaggio (NdefMessage) contenente uno o più record (NdefRecord). Ogni record NDEF deve essere in un formato corretto in base alla specifica del tipo di record che vuoi creare. Android supporta anche altri tipi di tag che non contengono dati NDEF, con i quali puoi lavorare utilizzando le classi del pacchetto android.nfc.tech. Per scoprire di più su queste tecnologie, consulta l'argomento NFC avanzata. L'utilizzo di questi altri tipi di tag comporta la scrittura del tuo stack di protocollo per comunicare con i tag, quindi consigliamo di utilizzare NDEF quando possibile per facilitare lo sviluppo e il massimo supporto per i dispositivi basati su Android.

Nota:per scaricare le specifiche NDEF complete, vai al sito NFC Forum Specifications & Application Documents e consulta Creating common types of NDEF records per esempi su come compilare i record NDEF.

Ora che hai alcune nozioni sui tag NFC, le sezioni seguenti descrivono in modo più dettagliato come Android gestisce i tag con formato NDEF. Quando un dispositivo Android esegue la scansione di un tag NFC contenente dati con formato NDEF, analizza il messaggio e tenta di capire il tipo MIME o l'URI di identificazione dei dati. A questo scopo, il sistema legge il primo NdefRecord all'interno di NdefMessage per determinare come interpretare l'intero messaggio NDEF (un messaggio NDEF può avere più record NDEF). In un messaggio NDEF ben formato, il primo NdefRecord contiene i seguenti campi:

TNF (Type Name Format) a 3 bit
Indica come interpretare il campo del tipo di lunghezza variabile. I valori validi sono descritti nella Tabella 1.
Tipo di lunghezza variabile
Descrivi il tipo di record. Se utilizzi TNF_WELL_KNOWN, usa questo campo per specificare la definizione del tipo di record (RTD). I valori RTD validi sono descritti nella Tabella 2.
ID di lunghezza variabile
Un identificatore univoco per la registrazione. Questo campo non viene utilizzato spesso, ma se devi identificare in modo univoco un tag, puoi creare un ID.
Payload di lunghezza variabile
Il payload dei dati effettivi che vuoi leggere o scrivere. Un messaggio NDEF può contenere più record NDEF, quindi non dare per scontato che il payload completo si trovi nel primo record NDEF del messaggio NDEF.

Il sistema di invio dei tag utilizza i campi TNF e type per provare a mappare un tipo MIME o un URI al messaggio NDEF. In caso di esito positivo, queste informazioni vengono incapsulate in un'intenzione ACTION_NDEF_DISCOVERED insieme al payload effettivo. Tuttavia, in alcuni casi il sistema di invio dei tag non è in grado di determinare il tipo di dati in base al primo record NDEF. Questo accade quando i dati NDEF non possono essere mappati a un tipo o URI MIME o quando il tag NFC non contiene dati NDEF con cui iniziare. In questi casi, un oggetto Tag contenente informazioni sulle tecnologie del tag e sul payload viene invece incapsulato all'interno di un'intenzione ACTION_TECH_DISCOVERED.

La Tabella 1 descrive in che modo il sistema di invio dei tag mappa i campi TNF e type a tipi MIME o URI. Descrive inoltre quali TNF non possono essere mappati a un tipo MIME o a un URI. In questi casi, il sistema di invio dei tag passa al valore ACTION_TECH_DISCOVERED.

Ad esempio, se il sistema di invio dei tag rileva un record di tipo TNF_ABSOLUTE_URI, mappa il campo del tipo di lunghezza variabile del record in un URI. Il sistema di invio dei tag incapsula questo URI nel campo dati di un'intenzione ACTION_NDEF_DISCOVERED insieme ad altre informazioni sul tag, come il payload. Se invece rileva un record di tipo TNF_UNKNOWN, crea un'intenzione che incapsula le tecnologie del tag.

Tabella 1. TNF supportati e relative mappature

Formato del nome del tipo (TNF) Mappatura
TNF_ABSOLUTE_URI URI in base al campo di tipo.
TNF_EMPTY Torna a ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPE URI basato sull'URN nel campo del tipo. L'URN viene codificato nel campo del tipo NDEF in una forma abbreviata: <domain_name>:<service_name>. Android mappa questo valore a un URI nel seguente formato: vnd.android.nfc://ext/<domain_name>:<service_name>.
TNF_MIME_MEDIA Tipo MIME basato sul campo Tipo.
TNF_UNCHANGED Non valido nel primo record, quindi torna a ACTION_TECH_DISCOVERED.
TNF_UNKNOWN Torna a ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWN Tipo MIME o URI a seconda della definizione del tipo di record (RTD), impostata nel campo type. Per ulteriori informazioni sui parametri RTD disponibili e sulle relative mappature, consulta la Tabella 2.

Tabella 2. RTD supportati per TNF_WELL_KNOWN e le relative mappature

Record Type Definition (RTD) Mappatura
RTD_ALTERNATIVE_CARRIER Torna a ACTION_TECH_DISCOVERED.
RTD_HANDOVER_CARRIER Torna a ACTION_TECH_DISCOVERED.
RTD_HANDOVER_REQUEST Torna a ACTION_TECH_DISCOVERED.
RTD_HANDOVER_SELECT Torna a ACTION_TECH_DISCOVERED.
RTD_SMART_POSTER URI basato sull'analisi del payload.
RTD_TEXT Tipo MIME di text/plain.
RTD_URI URI basato sul payload.

Come vengono inviati i tag NFC alle applicazioni

Quando il sistema di invio dei tag ha completato la creazione di un'intenzione che incapsula il tag NFC e le relative informazioni di identificazione, invia l'intenzione a un'applicazione interessata che filtra in base all'intenzione. Se più di un'applicazione può gestire l'intent, viene visualizzato il selettore di attività per consentire all'utente di selezionare l'attività. Il sistema di invio dei tag definisce tre intent, elencati in ordine di priorità, dalla più alta alla più bassa:

  1. ACTION_NDEF_DISCOVERED: questo intent viene utilizzato per avviare un'attività quando viene scansionato un tag contenente un payload NDEF di tipo riconosciuto. Si tratta dell'intent con la priorità più alta e, se possibile, il sistema di invio dei tag tenta di avviare un'attività con questo intent prima di qualsiasi altro.
  2. ACTION_TECH_DISCOVERED: se non vengono registrate attività per gestire l'intent ACTION_NDEF_DISCOVERED, il sistema di invio dei tag tenta di avviare un'applicazione con questo intent. Questo intento viene avviato direttamente anche (senza avviare prima ACTION_NDEF_DISCOVERED) se il tag scansionato contiene dati NDEF che non possono essere mappati a un tipo MIME o a un URI oppure se il tag non contiene dati NDEF, ma è di una tecnologia di tag nota.
  3. ACTION_TAG_DISCOVERED: questo intento viene avviato se nessuna attività gestisce gli intent ACTION_NDEF_DISCOVERED o ACTION_TECH_DISCOVERED.

Il funzionamento del sistema di invio tag è il seguente:

  1. Prova ad avviare un'attività con l'intent creato dal sistema di invio dei tag durante l'analisi del tag NFC (ACTION_NDEF_DISCOVERED o ACTION_TECH_DISCOVERED).
  2. Se non sono presenti filtri per l'intent, prova a avviare un'attività con l'intent di priorità più bassa successiva (ACTION_TECH_DISCOVERED o ACTION_TAG_DISCOVERED) finché un'applicazione non filtra per l'intent o finché il sistema di invio dei tag non prova tutti gli intent possibili.
  3. Se nessuna applicazione filtra per nessuno degli intent, non fare nulla.
Figura 1. Sistema di invio dei tag

Se possibile, utilizza i messaggi NDEF e l'intent ACTION_NDEF_DISCOVERED, poiché è il più specifico tra i tre. Questo intent ti consente di avviare l'applicazione in un momento più appropriato rispetto agli altri due intent, offrendo all'utente un'esperienza migliore.

Richiedere l'accesso NFC nel file manifest di Android

Prima di poter accedere all'hardware NFC di un dispositivo e gestire correttamente le intent NFC, dichiara questi elementi nel file AndroidManifest.xml:

  • L'elemento NFC <uses-permission> per accedere all'hardware NFC:
    <uses-permission android:name="android.permission.NFC" />
    
  • La versione minima dell'SDK che la tua applicazione può supportare. Il livello API 9 supporta solo la spedizione di tag limitata tramite ACTION_TAG_DISCOVERED e consente di accedere ai messaggi NDEF solo tramite l'extra EXTRA_NDEF_MESSAGES. Non è possibile accedere ad altre proprietà dei tag o operazioni di I/O. Il livello API 10 include il supporto completo di lettori/scrittori, nonché l'invio di NDEF in primo piano, mentre il livello API 14 fornisce metodi di praticità aggiuntivi per creare record NDEF.
    <uses-sdk android:minSdkVersion="10"/>
    
  • L'elemento uses-feature per fare in modo che la tua applicazione venga visualizzata su Google Play solo per i dispositivi con hardware NFC:
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    

    Se la tua applicazione utilizza la funzionalità NFC, ma questa funzionalità non è fondamentale per l'applicazione, puoi omettere l'elemento uses-feature e verificare la disponibilità del protocollo NFC in fase di esecuzione controllando se getDefaultAdapter() è null.

Filtra intent NFC

Per avviare l'applicazione quando viene scansionato un tag NFC che vuoi gestire, l'applicazione può filtrare per uno, due o tutti e tre gli intent NFC nel file Android manifest. Tuttavia, solitamente conviene filtrare in base all'intent ACTION_NDEF_DISCOVERED per avere il massimo controllo sull'avvio dell'applicazione. L'intent ACTION_TECH_DISCOVERED è un valore di riserva per ACTION_NDEF_DISCOVERED quando nessuna applicazione filtra per ACTION_NDEF_DISCOVERED o quando il payload non è NDEF. In genere, la categoria ACTION_TAG_DISCOVERED è troppo generica per essere utilizzata come criterio di filtro. Molte applicazioni filtreranno ACTION_NDEF_DISCOVERED o ACTION_TECH_DISCOVERED prima del giorno ACTION_TAG_DISCOVERED, pertanto è molto probabile che l'applicazione venga avviata. ACTION_TAG_DISCOVERED è disponibile solo come ultima risorsa per le applicazioni da filtrare nei casi in cui non siano installate altre applicazioni per gestire l'intent ACTION_NDEF_DISCOVERED o ACTION_TECH_DISCOVERED.

Poiché i deployment dei tag NFC variano e spesso non sono sotto il tuo controllo, questo non è sempre possibile, motivo per cui puoi ricorrere agli altri due intent se necessario. Quando hai il controllo sui tipi di tag e sui dati scritti, ti consigliamo di utilizzare NDEF per formattare i tag. Le seguenti sezioni descrivono come filtrare in base a ciascun tipo di intent.

ACTION_NDEF_DISCOVERED

Per filtrare in base agli intent ACTION_NDEF_DISCOVERED, dichiara il filtro per intent insieme al tipo di dati da filtrare. Il seguente esempio di filtro per gli intent ACTION_NDEF_DISCOVERED con un tipo 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>

L'esempio seguente filtra per un URI nella forma 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

Se la tua attività filtra per l'intent ACTION_TECH_DISCOVERED, devi creare un file di risorse XML che specifichi le tecnologie supportate dalla tua attività all'interno di un insieme tech-list. La tua attività è considerata una corrispondenza se un insieme tech-list è un sottoinsieme delle tecnologie supportate dal tag, che puoi ottenere chiamando getTechList().

Ad esempio, se il tag scansionato supporta MifareClassic, NdefFormatable e NfcA, il valore impostato per tech-list deve specificare tutte e tre le tecnologie, due o una (e nient'altro) affinché la tua attività venga associata.

L'esempio seguente definisce tutte le tecnologie. Devi rimuovere quelli non supportati dal tuo tag NFC. Salva questo file (puoi assegnargli il nome che preferisci) nella cartella <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>

Puoi anche specificare più insiemi tech-list. Ciascuno degli insiemi tech-list viene considerato in modo indipendente e la tua attività è considerata una corrispondenza se un singolo insieme tech-list è un sottoinsieme delle tecnologie restituite da getTechList(). Fornisce la semantica di AND e OR per la corrispondenza delle tecnologie. L'esempio seguente corrisponde ai tag che possono supportare le tecnologie NfcA e Ndef o le tecnologie NfcB e 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>

Nel file AndroidManifest.xml, specifica il file di risorse che hai appena creato nell'elemento <meta-data> all'interno dell'elemento <activity> come nell'esempio seguente:

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

Per ulteriori informazioni sull'utilizzo delle tecnologie dei tag e sull'intent ACTION_TECH_DISCOVERED, consulta la sezione Utilizzo delle tecnologie dei tag supportate nel documento NFC avanzato.

ACTION_TAG_DISCOVERED

Per filtrare in base a ACTION_TAG_DISCOVERED, utilizza il seguente filtro per intent:

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

Ottenere informazioni dagli intent

Se un'attività viene avviata a causa di un intent NFC, puoi ottenere informazioni sul tag NFC scansionato dall'intent. Gli intent possono contenere i seguenti extra, a seconda del tag analizzato:

Per ottenere questi extra, controlla se la tua attività è stata avviata con uno degli intent NFC per assicurarti che sia stato scansionato un tag, quindi ottieni gli extra dall'intent. L'esempio seguente controlla l'intent ACTION_NDEF_DISCOVERED e recupera i messaggi NDEF da un extra intent.

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

In alternativa, puoi ottenere un oggetto Tag dall'intent, che conterrà il payload e ti consentirà di enumerare le tecnologie del tag:

Kotlin

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

Java

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

Creazione di tipi comuni di record NDEF

Questa sezione descrive come creare tipi comuni di record NDEF per aiutarti a scrivere nei tag NFC. A partire da Android 4.0 (livello API 14), è disponibile il metodo createUri() per aiutarti a creare automaticamente i record URI. A partire da Android 4.1 (livello API 16), createExternal() e createMime() sono disponibili per aiutarti a creare record NDEF di tipo MIME ed esterno. Utilizza questi metodi di assistenza, se possibile, per evitare errori prilikom creare manualmente i record NDEF.

Questa sezione descrive anche come creare il corrispondente filtro per l'intenzione per il record. Tutti questi esempi di record NDEF devono trovarsi nel primo record NDEF del messaggio NDEF che stai scrivendo su un tag.

TNF_ABSOLUTE_URI

Nota: ti consigliamo di utilizzare il tipo RTD_URI anziché TNF_ABSOLUTE_URI, perché è più efficiente.

Puoi creare un record NDEF TNF_ABSOLUTE_URI nel seguente modo :

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

Il filtro per intent per il record NDEF precedente sarà simile al seguente:

<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

Puoi creare un record NDEF TNF_MIME_MEDIA nei seguenti modi:

Utilizzo del metodo 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")));

Creare NdefRecord manualmente:

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

Il filtro per intent per il record NDEF precedente sarà simile al seguente:

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

Puoi creare un record NDEF TNF_WELL_KNOWN nel seguente modo:

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

Il filtro per intent per il record NDEF precedente avrebbe il seguente aspetto:

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

Puoi creare un record NDEF TNF_WELL_KNOWN nei seguenti modi:

Utilizzo del metodo createUri(String):

Kotlin

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

Java

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

Se utilizzi il metodo 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);

Creazione manuale di 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);

Il filtro per intent per il record NDEF precedente avrebbe il seguente aspetto:

<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

Puoi creare un record NDEF TNF_EXTERNAL_TYPE nei seguenti modi:

Utilizzo del metodo 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);

Creare NdefRecord manualmente:

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

Il filtro per intent per il record NDEF precedente avrebbe il seguente aspetto:

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

Utilizza TNF_EXTERNAL_TYPE per implementazioni di tag NFC più generiche per supportare meglio i dispositivi Android e non Android.

Nota: le URN per TNF_EXTERNAL_TYPE hanno un formato canonico di: urn:nfc:ext:example.com:externalType, tuttavia la specifica RTD del NFC Forum dichiara che la parte urn:nfc:ext: dell'URN deve essere omessa dal record NDEF. Pertanto, devi fornire solo il dominio (example.com nell'esempio) e il tipo (externalType nell'esempio) separati da due punti. Quando invia TNF_EXTERNAL_TYPE, Android converte l'ARN urn:nfc:ext:example.com:externalType in un URI vnd.android.nfc://ext/example.com:externalType, che è ciò che dichiara il filtro intent nell'esempio.

Record delle app per Android

Introdotto in Android 4.0 (livello API 14), un record dell'applicazione Android (AAR) garantisce con maggiore certezza che l'applicazione venga avviata quando viene scansionato un tag NFC. Un AAR contiene il nome del pacchetto di un'applicazione incorporato in un record NDEF. Puoi aggiungere un AAR a qualsiasi record NDEF del messaggio NDEF, perché Android cerca gli AAR nell'intero messaggio NDEF. Se ne trova uno, avvia l'applicazione in base al nome del pacchetto all'interno dell'AAR. Se l'applicazione non è presente sul dispositivo, viene avviato Google Play per scaricarla.

Gli AAR sono utili se vuoi impedire ad altre applicazioni di filtrare in base allo stesso intent e potenzialmente gestire tag specifici di cui hai eseguito il deployment. Gli AAR sono supportati solo a livello di applicazione, a causa del vincolo di nome del pacchetto, e non a livello di attività, come nel caso del filtro per intent. Se vuoi gestire un'intenzione a livello di attività, utilizza i filtri di intent.

Se un tag contiene un AAR, il sistema di invio dei tag esegue l'invio nel seguente modo:

  1. Prova a avviare un'attività utilizzando un filtro intent come di consueto. Se l'attività che corrisponde all'intent corrisponde anche all'AAR, avvia l'attività.
  2. Se l'attività che filtra per l'intent non corrisponde all'Aar, se più attività possono gestire l'intent o se nessuna attività gestisce l'intent, avvia l'applicazione specificata dall'Aar.
  3. Se nessuna applicazione può essere avviata con l'ARA, accedi a Google Play per scaricare l'applicazione in base al certificato AAR.

Nota:puoi ignorare le AAR e il sistema di invio degli intent con il sistema di invio in primo piano, che consente a un'attività in primo piano di avere la priorità quando viene rilevato un tag NFC. Con questo metodo, l'attività deve essere in primo piano per eseguire l'override degli annunci adattabili della rete di ricerca e del sistema di invio degli intent.

Se vuoi comunque filtrare i tag sottoposti a scansione che non contengono un AAR, puoi dichiarare i filtri di intent come di consueto. Questa opzione è utile se la tua applicazione è interessata ad altri tag che non contengono un AAR. Ad esempio, potresti voler garantire che la tua applicazione gestisca i tag proprietari che implementi, nonché i tag generici implementati da terze parti. Tieni presente che gli annunci adattabili della rete di ricerca sono specifici per i dispositivi Android 4.0 o versioni successive, pertanto, quando implementi i tag, molto probabilmente vorrai utilizzare una combinazione di annunci adattabili della rete di ricerca e tipi MIME/URI per supportare la gamma più ampia di dispositivi. Inoltre, quando implementi i tag NFC, pensa a come vuoi scriverli per attivare il supporto per la maggior parte dei dispositivi (Android e altri dispositivi). Puoi farlo definendo un tipo MIME o un URI relativamente univoco per semplificare il compito delle applicazioni.

Android fornisce un'API semplice per creare un AAR,createApplicationRecord(). Devi solo incorporare l'AAR in qualsiasi punto del tuo NdefMessage. Non vuoi utilizzare il primo record di NdefMessage, a meno che l'AAR non sia l'unico record nel NdefMessage. Questo accade perché il sistema Android controlla il primo record di un NdefMessage per determinare il tipo MIME o l'URI del tag, che viene utilizzato per creare un'intent da filtrare per le applicazioni. Il seguente codice mostra come creare un 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")}
        );
)