In questo documento vengono descritte le attività NFC di base che esegui in Android. Viene spiegato come inviare e Ricevere dati NFC sotto forma di messaggi NDEF e descrivere le API del framework Android che supportano queste funzionalità. Per argomenti più avanzati, inclusa una discussione sull'utilizzo di dati non NDEF, consulta la sezione NFC avanzata.
Esistono due casi d'uso principali quando si lavora con dati NDEF e Android:
- Lettura dei dati NDEF da un tag NFC
- Trasmettere messaggi NDEF da un dispositivo a un altro con Android BeamTM
La lettura dei dati NDEF da un tag NFC viene gestita con l'invio dei tag. , che analizza i tag NFC rilevati, classifica i dati in modo appropriato e inizia un'applicazione interessata ai dati categorizzati. un'applicazione che vuole gestire Il tag NFC scansionato può dichiarare un filtro per intent e una richiesta di gestione dei dati.
La funzione Android BeamTM consente a un dispositivo di inviare un messaggio NDEF a un altro dispositivo mettendo a contatto ciascun dispositivo. Questa interazione offre un modo più semplice di inviare dati rispetto ad altre tecnologie wireless come il Bluetooth, perché con NFC, nessun dispositivo manuale il rilevamento o l'accoppiamento è obbligatorio. La connessione viene avviata automaticamente quando si collegano due dispositivi nel raggio d'azione. Android Beam è disponibile tramite una serie di API NFC, che consentono a qualsiasi applicazione di trasmettere informazioni tra i dispositivi. Ad esempio, le applicazioni Contatti, Browser e YouTube utilizzano Android Beam per condividere contatti, pagine web e video con altri dispositivi.
Il sistema di invio tag
I dispositivi Android di solito cercano i tag NFC quando lo schermo è sbloccato, a meno che NFC non sia disattivata nel menu Impostazioni del dispositivo. Quando un dispositivo Android rileva un tag NFC, il comportamento desiderato è avere l'attività più appropriata per gestire l'intento senza chiedere all'utente quale applicazione per l'utilizzo. Dato che i dispositivi scansionano i tag NFC a un raggio molto breve, è probabile che gli utenti utilizzino manualmente la selezione di un'attività li costringe ad allontanare il dispositivo dal tag e a interrompere la connessione. Dovresti sviluppare la tua attività in modo da gestire solo i tag NFC che sono importanti per la tua attività. impediscono la visualizzazione del Selettore attività.
Per aiutarti a raggiungere questo obiettivo, Android offre uno speciale sistema di invio dei tag che analizza le scansioni i tag NFC, li analizza e prova a individuare le applicazioni interessate ai dati scansionati. it può farlo:
- Analisi del tag NFC e rilevamento del tipo MIME o di un URI che identifica il payload dei dati nel tag.
- Incapsulamento del tipo o dell'URI MIME e del payload in un intent. Queste due prime sono descritti in Come vengono mappati i tag NFC a tipi MIME e URI.
- Avvia un'attività in base all'intenzione. Questa operazione viene descritta Modalità di invio dei tag NFC alle applicazioni.
Come vengono mappati i tag NFC a tipi e URI MIME
Prima di iniziare a scrivere applicazioni NFC, è importante comprendere le diverse i tipi di tag NFC, la modalità di analisi dei tag NFC da parte del sistema di invio dei tag e il lavoro speciale svolto quando rileva un messaggio NDEF. I tag NFC sono disponibili un'ampia gamma di tecnologie e i dati possono essere scritti in molti modi diversi. Android offre il supporto maggiore per lo standard NDEF, definito dall'NFC Forum.
I dati NDEF sono incapsulati all'interno di un messaggio (NdefMessage
) che contiene
o più record (NdefRecord
). Ogni record NDEF deve essere formulato in modo corretto secondo
la specifica del tipo di record che vuoi creare. Android
supporta anche altri tipi di tag che non contengono dati NDEF, che puoi utilizzare 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
scrivere il tuo stack di protocollo per comunicare con i tag, quindi consigliamo di usare NDEF quando
possibile per una facilità di sviluppo e il massimo supporto dei dispositivi basati su Android.
Nota: Per scaricare le specifiche NDEF complete, vai alla pagina NFC Forum Specifications & Documenti d'applicazione e consultare il sito Creazione di tipi comuni di record NDEF per esempi su come creare record NDEF.
Ora che conosci le informazioni di base sui tag NFC, nelle sezioni seguenti vengono descritte in modo più dettagliato come
Android gestisce i tag formattati NDEF. Quando un dispositivo Android analizza un tag NFC contenente NDEF
dati formattati, analizza il messaggio e prova a individuare il tipo MIME dei dati o l'identificazione
URI. Per farlo, 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
- Descrive il tipo di record. Se usi
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 lunghezza variabile
- Un identificatore univoco del record. Questo campo non viene utilizzato spesso, ma se devi identificare un tag in modo univoco, puoi creare un ID.
- Carico di lunghezza variabile
- Il payload effettivo che vuoi leggere o scrivere. Un NDEF può contenere più record NDEF, quindi non dare per scontato che il payload completo sia nel primo NDEF record del messaggio NDEF.
Il sistema di invio dei tag utilizza i campi del tipo e del TNF per provare a mappare un URI o un tipo MIME alla
messaggio NDEF. In caso di esito positivo, il modello incapsula queste informazioni all'interno di un intent ACTION_NDEF_DISCOVERED
insieme al payload effettivo. Tuttavia,
sono i casi in cui il sistema di invio dei tag non è in grado di determinare il tipo di dati in base al primo NDEF
record. Questo accade quando i dati NDEF non possono essere mappati a un tipo o a un URI MIME o quando
Il tag NFC non contiene dati NDEF con cui iniziare. In questi casi, un oggetto Tag
che contiene informazioni sulle tecnologie del tag e sul payload vengono
incapsulati invece in un intent ACTION_TECH_DISCOVERED
.
La tabella 1 descrive in che modo il sistema di invio dei tag mappa il TNF e il tipo
ai tipi MIME o agli URI. Descrive inoltre quali TNF non possono essere mappati a un tipo o a un URI MIME.
In questi casi, il sistema di invio dei tag utilizza
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 di quel record
in un URI. Il sistema di invio dei tag incapsula l'URI nel campo dei dati di un intent ACTION_NDEF_DISCOVERED
insieme ad altre informazioni relative al tag.
come il payload. Se invece rileva un record di tipo TNF_UNKNOWN
, crea un intent che incapsula le tecnologie del tag
.
Formato nome tipo (TNF) | Mappatura |
---|---|
TNF_ABSOLUTE_URI |
URI in base al campo del tipo. |
TNF_EMPTY |
Torna a ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
URI basato sull'URN nel campo del tipo. L'URN è codificato nel campo di tipo NDEF in
un formato abbreviato: <domain_name>:<service_name> .
Android lo mappa a un URI nel formato:
vnd.android.nfc://ext/<domain_name>:<service_name> . |
TNF_MIME_MEDIA |
Tipo MIME in base al campo del 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 del Record Type Definition (RTD), impostato nel . Consulta la Tabella 2 per ulteriori informazioni su gli RTD disponibili 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 tag ha terminato di creare un intent che incapsula il tag NFC e i relativi identificare le informazioni, invia l'intento a un'applicazione interessata filtri per l'intent. Se più applicazioni sono in grado di gestire l'intent, il Selettore attività così che l'utente possa selezionare l'attività. Il sistema di invio dei tag definisce tre intent, elencati in ordine di priorità, dalla più alta alla più bassa:
-
ACTION_NDEF_DISCOVERED
: questo intent viene utilizzato per avviare un Attività quando un tag che contiene un payload NDEF viene analizzato ed è di un tipo riconosciuto. Questo è l'intent con la priorità più alta e il sistema di invio dei tag prova ad avviare un'attività con l'intenzione prima di qualsiasi altro intento, quando possibile. ACTION_TECH_DISCOVERED
: se non viene registrata alcuna attività gestireACTION_NDEF_DISCOVERED
, il sistema di invio dei tag prova ad avviare un'applicazione con questo intent. Questo anche l'intent viene avviato direttamente (senza iniziare primaACTION_NDEF_DISCOVERED
) se il tag viene analizzato Contiene dati NDEF che non possono essere mappati a un URI o un tipo MIME oppure il tag non contiene NDEF dati, ma fa parte di una tecnologia di tag nota.ACTION_TAG_DISCOVERED
: questo intent è stato avviato se nessuna attività gestisceACTION_NDEF_DISCOVERED
oACTION_TECH_DISCOVERED
intent.
Il funzionamento del sistema di invio tag è il seguente:
- Prova ad avviare un'attività con l'intent creato dal sistema di invio dei tag
durante l'analisi del tag NFC (ad esempio
ACTION_NDEF_DISCOVERED
oACTION_TECH_DISCOVERED
). - Se nessuna attività filtra per quell'intent, prova ad avviare un'attività con la
per intent con priorità più bassa (
ACTION_TECH_DISCOVERED
oACTION_TAG_DISCOVERED
) finché un'applicazione non filtra per o fino a quando il sistema di invio dei tag non prova tutti gli intent possibili. - Se nessuna applicazione filtra in base agli intent, non fare nulla.
Se possibile, lavora con i messaggi NDEF e l'intent ACTION_NDEF_DISCOVERED
, perché è il più specifico
i tre. Questo intent ti consente di presentare la tua domanda in un momento più appropriato rispetto a
altri due intent, offrendo all'utente un'esperienza migliore.
Richiedere l'accesso NFC nel file manifest Android
Prima di poter accedere all'hardware NFC di un dispositivo e gestire correttamente gli intent NFC, dichiara questi
elementi nel file AndroidManifest.xml
:
- 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
un numero limitato di tag tramite
ACTION_TAG_DISCOVERED
e restituisce solo accesso ai messaggi NDEF tramite l'ulterioreEXTRA_NDEF_MESSAGES
. No altre proprietà del tag o operazioni di I/O. Livello API 10 include un supporto completo per lettori/autore, nonché push NDEF in primo piano e livello API. 14 offre un modo più semplice per inviare messaggi NDEF ad altri dispositivi con Android Beam e per creare record NDEF.<uses-sdk android:minSdkVersion="10"/>
- L'elemento
uses-feature
in modo che la tua applicazione venga visualizzata in Google Play solo per i dispositivi dotati di hardware NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Se la tua applicazione utilizza la funzionalità NFC, ma questa non è fondamentale per il tuo puoi omettere l'elemento
uses-feature
e verificare la disponibilità della tecnologia NFC all'indirizzo di runtime controllando segetDefaultAdapter()
ènull
.
Filtra intent NFC
Per avviare l'applicazione quando viene scansionato un tag NFC che desideri gestire, l'applicazione
puoi filtrare per uno, due o tutti e tre gli intent NFC nel file manifest Android. Tuttavia,
di solito vogliono filtrare in base all'intent ACTION_NDEF_DISCOVERED
per
hai il massimo controllo sull'avvio dell'applicazione. L'intent ACTION_TECH_DISCOVERED
è un fallback per ACTION_NDEF_DISCOVERED
quando nessun filtro delle applicazioni filtra per
ACTION_NDEF_DISCOVERED
o quando il payload non è
NDEF. Il filtro per ACTION_TAG_DISCOVERED
di solito è troppo generico per
categoria in base alla quale applicare il filtro. Molte applicazioni filtreranno ACTION_NDEF_DISCOVERED
o ACTION_TECH_DISCOVERED
prima del giorno ACTION_TAG_DISCOVERED
, quindi la tua applicazione ha una bassa probabilità di
iniziare. ACTION_TAG_DISCOVERED
è disponibile solo come ultima risorsa
delle applicazioni da filtrare nei casi in cui non siano installate altre applicazioni per gestire
Per intent ACTION_NDEF_DISCOVERED
o ACTION_TECH_DISCOVERED
.
Poiché le implementazioni dei tag NFC variano e molte volte non sono sotto il tuo controllo, non sempre ed è per questo che puoi ricorrere agli altri due intent se necessario. Se hai sui tipi di tag e dati scritti, è consigliabile 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 a ACTION_NDEF_DISCOVERED
intent, dichiara il
insieme al tipo di dati da filtrare. La
i seguenti filtri di esempio per ACTION_NDEF_DISCOVERED
intent 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 in base a un URI sotto forma di
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>
TECNOLOGIA_AZIONE_DISCOVERED
Se la tua attività filtra in base all'intent ACTION_TECH_DISCOVERED
,
devi creare un file di risorse XML che specifichi le tecnologie supportate dalla tua attività
in un insieme di tech-list
. La tua attività è
viene considerata una corrispondenza se un insieme di tech-list
è un sottoinsieme delle tecnologie che
supportata dal tag, che puoi ottenere chiamando getTechList()
.
Ad esempio, se il tag analizzato supporta MifareClassic, NdefFormatable e NfcA, il tuo
Il set di tech-list
deve specificare tutte e tre le tecnologie, oppure una sola delle tecnologie (e nulla
altro) per far sì che la tua attività venga abbinata.
Il seguente esempio definisce tutte le tecnologie. Devi rimuovere quelle che non sono
supportata dal tag NFC. Salva il file (puoi assegnargli il nome che desideri) nella
<project-root>/res/xml
cartella.
<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ù set di tech-list
. Ciascuno dei tech-list
di set di dati viene considerata indipendente e la tua attività viene considerata una corrispondenza se
Il set tech-list
è un sottoinsieme delle tecnologie restituite da getTechList()
. In questo modo ottieni AND
e OR
la semantica per le tecnologie di corrispondenza. L'esempio seguente corrisponde a tag che possono supportare
tecnologie NfcA e Ndef o possono supportare 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 di <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 di tag e dell'intent ACTION_TECH_DISCOVERED
, consulta Utilizzo dei tag supportati
tecnologie nel documento NFC avanzata.
ACTION_TAG_DISCOVERED
Per filtrare in base a ACTION_TAG_DISCOVERED
, utilizza il seguente intent
filtro:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Ottenere informazioni dagli intent
Se un'attività inizia per un intent NFC, puoi ottenere informazioni sull'NFC scansionato dell'intent. Gli intent possono contenere i seguenti extra a seconda del tag analizzato:
EXTRA_TAG
(obbligatorio): un oggettoTag
che rappresenta il tag scansionato.EXTRA_NDEF_MESSAGES
(facoltativo): un array di messaggi NDEF analizzati dal tag. Questo extra è obbligatorioACTION_NDEF_DISCOVERED
intent.- (Facoltativo)
EXTRA_ID
: l'ID di basso livello del tag.
Per ottenere questi extra, controlla se la tua attività è stata avviata con uno di
gli intent NFC per garantire che un tag sia stato scansionato, quindi ricavarne gli extra dalla
l'intento. L'esempio seguente verifica la presenza di ACTION_NDEF_DISCOVERED
e ottiene i messaggi NDEF da un intent aggiuntivo.
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
contengono il payload e consentono 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 semplificare la scrittura
Tag NFC o invio di dati con Android Beam. A partire da Android 4.0 (livello API 14), la
Il metodo createUri()
è disponibile per aiutarti a creare
record URI automaticamente. A partire da Android 4.1 (livello API 16),
createExternal()
e createMime()
sono disponibili per aiutarti a creare
Record MIME e NDEF di tipo esterno. Se possibile, usa questi metodi di supporto per evitare errori
durante la creazione manuale di record NDEF.
Questa sezione descrive inoltre come creare il modello filtro per intent. Tutti questi esempi di record NDEF devono essere nel primo NDEF record del messaggio NDEF che stai scrivendo su un tag o tramite trasmissione.
TNF_ABSOLUTE_URI
Nota: ti consigliamo di utilizzare lo
RTD_URI
digita
di 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 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="developer.android.com" android:pathPrefix="/index.html" /> </intent-filter>
TNF_MIME_MEDIA
Puoi creare un record NDEF TNF_MIME_MEDIA
nei seguenti modi:
Se utilizzi il 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")));
Creazione manuale di NdefRecord
:
Kotlin
val mimeRecord = Charset.forName("US-ASCII").let { usAscii -> NdefRecord( NdefRecord.TNF_MIME_MEDIA, "application/vnd.com.example.android.beam".toByteArray(usAscii), ByteArray(0), "Beam me up, Android!".toByteArray(usAscii) ) }
Java
NdefRecord mimeRecord = new NdefRecord( NdefRecord.TNF_MIME_MEDIA , "application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")), new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
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="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:
Se utilizzi il 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>
TIPO_ESTERNO_TNF
Puoi creare un record NDEF TNF_EXTERNAL_TYPE
nel seguente
modi:
Se utilizzi il 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);
Creazione manuale di NdefRecord
:
Kotlin
var payload: ByteArray ... val extRecord = NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".toByteArray(Charset.forName("US-ASCII")), ByteArray(0), payload )
Java
byte[] payload; ... NdefRecord extRecord = new NdefRecord( NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType".getBytes(Charset.forName("US-ASCII")), new byte[0], payload);
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 più generiche di tag NFC in modo da supportare meglio entrambi
Dispositivi con e non Android.
Nota: gli URN di TNF_EXTERNAL_TYPE
hanno un formato canonico:
urn:nfc:ext:example.com:externalType
, tuttavia la specifica NFC Forum RTD
dichiara che la porzione urn:nfc:ext:
dell'URN deve essere omessa dal
record NDEF. Devi solo fornire il dominio (example.com
nell'esempio)
e il tipo (externalType
nell'esempio) separati dai due punti.
Quando invia TNF_EXTERNAL_TYPE
, Android converte l'URN di urn:nfc:ext:example.com:externalType
in un URI vnd.android.nfc://ext/example.com:externalType
, che è quello
del filtro per intent nell'esempio.
Record delle app Android
Introdotto in Android 4.0 (livello API 14), un Android Application Record (AAR) offre un la certezza che l'applicazione viene avviata quando viene scansionato un tag NFC. Un AAR ha il nome del pacchetto di un'applicazione incorporata in un record NDEF. Puoi aggiungere un AAR a qualsiasi record NDEF del tuo NDEF poiché Android cerca gli AAR in tutto il messaggio NDEF. Se trova un AAR, inizia l'applicazione in base al nome del pacchetto all'interno dell'AAR. Se l'applicazione non è presente nel dispositivo, viene avviato Google Play per scaricare l'applicazione.
Gli AAR sono utili se vuoi impedire ad altre applicazioni di filtrare in base allo stesso intento potenzialmente gestire tag specifici di cui hai eseguito il deployment. I rivenditori autorizzati sono supportati solo a livello di applicazione, a causa del vincolo di nome del pacchetto, e non al livello di attività, come e il filtro per intent. Se vuoi gestire un intent a livello di attività, utilizza i filtri per intent.
Se un tag contiene un AAR, il sistema di invio dei tag effettua l'invio nel seguente modo:
- Prova ad avviare un'attività utilizzando un filtro per intent, come di consueto. Se l'attività corrispondente anche l'intent corrisponde all'AAR, avvia l'attività.
- Se l'attività che filtra per l'intent non corrisponde alla AAR, se più attività possono gestire l'intento, oppure se nessuna attività gestisce l'intent, dell'applicazione specificata dall'AAR.
- Se nessuna applicazione supporta l'AAR, accedi a Google Play per scaricare l'app un'applicazione basata sull'AAR.
Nota: puoi sostituire gli AAR e il sistema di invio dell'intent con il in primo piano di tracciamento delle spedizioni, che consente a un'attività in primo piano di avere la priorità quando un tag NFC viene sono state rilevate. Con questo metodo, l'attività deve essere in primo piano per eseguire l'override di AAR e di invio per intenzione.
Se vuoi comunque filtrare i tag scansionati che non contengono un AAR, puoi dichiarare filtri per intent come di consueto. È utile se la tua applicazione è interessata ad altri tag che non contengono un AAR. Ad esempio, potresti voler garantire che la tua applicazione gestisca così come i tag generici implementati da terze parti. Aspetti da tenere presenti che i AAR siano specifici per i dispositivi con Android 4.0 o versioni successive. Pertanto, quando implementi i tag, una combinazione di AAR e tipi MIME/URI in modo da supportare la più ampia gamma di dispositivi. Nella Inoltre, quando implementi i tag NFC, pensa a come desideri scriverli per abilitare il supporto per la maggior parte dei dispositivi (dispositivi basati su Android e di altro tipo). A tale scopo, procedi nel seguente modo: la definizione di un URI o un tipo MIME relativamente univoco per facilitare la distinzione da parte delle applicazioni.
Android offre una semplice API per creare un AAR,
createApplicationRecord()
. Tutto ciò che ti serve
incorpora l'AAR in qualsiasi punto di NdefMessage
. Non vuoi
per utilizzare il primo record di NdefMessage
, a meno che l'AAR non sia l'unico
record in NdefMessage
. Questo perché Android
controlla il primo record di un NdefMessage
per determinare il tipo MIME o
URI del tag, utilizzato per creare un intent che le applicazioni filtrano. 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")} ); )
Trasmetti messaggi NDEF ad altri dispositivi
Android Beam consente un semplice scambio di dati peer-to-peer tra due dispositivi Android. La l'applicazione che desidera trasmettere dati a un altro dispositivo deve essere in primo piano e il dispositivo la ricezione dei dati non deve essere bloccata. Quando il dispositivo raggiante entra in contatto abbastanza vicino con una dispositivo ricevente, il dispositivo di trasmissione visualizza il messaggio "Tocca per trasmettere" nell'interfaccia utente. L'utente può quindi scegliere se trasmettere o meno il messaggio al dispositivo ricevente.
Nota: il push NDEF in primo piano era disponibile a livello API 10,
che offre funzionalità simili ad Android Beam. Queste API sono state ritirate, ma
per supportare i dispositivi meno recenti. Leggi i enableForegroundNdefPush()
per avere ulteriori informazioni.
Puoi attivare Android Beam per la tua applicazione chiamando uno dei due metodi:
setNdefPushMessage()
: accetta unNdefMessage
da impostare come messaggio da trasmettere. Trasmette automaticamente il messaggio quando due dispositivi sono abbastanza vicini.setNdefPushMessageCallback()
: Accetta un callback che contiene uncreateNdefMessage()
che viene chiamato quando un dispositivo è nel raggio d'azione per trasmettere dati. Il callback ti consente di creare il messaggio NDEF solo quando necessario.
Un'attività può eseguire il push di un solo messaggio NDEF alla volta, quindi setNdefPushMessageCallback()
ha la precedenza
maggiore di setNdefPushMessage()
se sono impostati entrambi. Per utilizzare
Android Beam, devono essere rispettate le seguenti linee guida generali:
- L'attività che trasmette i dati deve essere in primo piano. Entrambi i dispositivi devono avere si sbloccavano gli schermi.
- Devi incapsulare i dati che stai trasmettendo in un
NdefMessage
. - Il dispositivo NFC che riceve i dati trasmessi deve supportare la
Protocollo push NDEF
com.android.npp
o SNEP (Simple NDEF Exchange) del forum NFC del protocollo). Per i dispositivi con livello API 9 (Android), è richiesto il protocollocom.android.npp
2.3) al livello API 13 (Android 3.2).com.android.npp
e SNEP sono entrambi obbligatori Livello API 14 (Android 4.0) e versioni successive.
Nota. Se per la tua attività è attivo Android Beam ed è in primo piano, il sistema di invio per intent standard è disattivato. Tuttavia, se anche la tua attività attiva l'invio in primo piano, può comunque analizzare i tag che corrispondono ai filtri di intent impostati l'invio in primo piano.
Per attivare Android Beam:
- Crea un
NdefMessage
che contenga iNdefRecord
che vuoi inviare all'altro dispositivo. - Chiama
setNdefPushMessage()
conNdefMessage
osetNdefPushMessageCallback
che passa in un oggettoNfcAdapter.CreateNdefMessageCallback
nel metodoonCreate()
di la tua attività. Questi metodi richiedono almeno un'attività che vuoi attivare con Android Beam, insieme a un elenco facoltativo di altre attività da attivare.In generale, solitamente usi
setNdefPushMessage()
se la tua Attività ha bisogno solo di invia sempre lo stesso messaggio NDEF quando due dispositivi sono nel raggio d'azione per comunicare. UtilizzisetNdefPushMessageCallback
quando l'applicazione si preoccupa del contesto corrente dell'applicazione e vuole eseguire il push di un messaggio NDEF a seconda di ciò che fa l'utente nella tua applicazione.
L'esempio seguente mostra come un'attività semplice chiama NfcAdapter.CreateNdefMessageCallback
nel metodo onCreate()
di un
attività (vedi AndroidBeamDemo)
per l'esempio completo). Questo esempio include anche dei metodi per aiutarti a creare un record MIME:
Kotlin
package com.example.android.beam import android.app.Activity import android.content.Intent import android.nfc.NdefMessage import android.nfc.NdefRecord import android.nfc.NfcAdapter import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.NfcEvent import android.os.Bundle import android.os.Parcelable import android.widget.TextView import android.widget.Toast import java.nio.charset.Charset class Beam : Activity(), NfcAdapter.CreateNdefMessageCallback { private var nfcAdapter: NfcAdapter? = null private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) textView = findViewById(R.id.textView) // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this) if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show() finish() return } // Register callback nfcAdapter?.setNdefPushMessageCallback(this, this) } override fun createNdefMessage(event: NfcEvent): NdefMessage { val text = "Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis() return NdefMessage( arrayOf( createMime("application/vnd.com.example.android.beam", text.toByteArray()) ) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. *///,NdefRecord.createApplicationRecord("com.example.android.beam") ) } override fun onResume() { super.onResume() // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) { processIntent(intent) } } override fun onNewIntent(intent: Intent) { // onResume gets called after this to handle the intent setIntent(intent) } /** * Parses the NDEF Message from the intent and prints to the TextView */ private fun processIntent(intent: Intent) { textView = findViewById(R.id.textView) // only one message sent during the beam intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMsgs -> (rawMsgs[0] as NdefMessage).apply { // record 0 contains the MIME type, record 1 is the AAR, if present textView.text = String(records[0].payload) } } } }
Java
package com.example.android.beam; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcEvent; import android.os.Bundle; import android.os.Parcelable; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; public class Beam extends Activity implements CreateNdefMessageCallback { NfcAdapter nfcAdapter; TextView textView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView textView = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) { Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show(); finish(); return; } // Register callback nfcAdapter.setNdefPushMessageCallback(this, this); } @Override public NdefMessage createNdefMessage(NfcEvent event) { String text = ("Beam me up, Android!\n\n" + "Beam Time: " + System.currentTimeMillis()); NdefMessage msg = new NdefMessage( new NdefRecord[] { createMime( "application/vnd.com.example.android.beam", text.getBytes()) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") }); return msg; } @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { textView = (TextView) findViewById(R.id.textView); Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present textView.setText(new String(msg.getRecords()[0].getPayload())); } }
Tieni presente che questo codice commenta un AAR, che puoi rimuovere. Se attivi l'AAR, specificata nell'AAR riceve sempre il messaggio Android Beam. Se l'applicazione non è presente, Google Play inizia a scaricare l'applicazione. Pertanto, il seguente intento tecnicamente non è necessario per i dispositivi Android 4.0 o versioni successive se si utilizza l'AAR:
<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>
Con questo filtro per intent, ora è possibile avviare l'applicazione com.example.android.beam
quando scansiona un tag NFC o riceve un Android Beam con un AAR di
tipo com.example.android.beam
o quando un messaggio in formato NDEF contiene un record MIME
di tipo application/vnd.com.example.android.beam
.
Anche se gli AAR garantiscono che un'applicazione venga avviata o scaricata, i filtri per intent vengono consigliata, perché ti consente di avviare un'attività a tua scelta nei dell'applicazione invece di avviare sempre l'attività principale all'interno del pacchetto specificato da un AAR. I rivenditori autorizzati non dispongono di granularità del livello di attività. Inoltre, poiché alcuni dispositivi Android non supportano supportare gli AAR, dovresti anche incorporare le informazioni identificative nel primo record NDEF del tuo NDEF messaggi e filtrarli, per sicurezza. Consulta la sezione Creare Tipi di record NDEF per ulteriori informazioni su come creare i record.