Ce document aborde des sujets relatifs à la technologie NFC avancés, tels que l'utilisation de différentes technologies de tag, l'écriture dans des tags NFC et la distribution au premier plan, qui permet à une application au premier plan gérer les intents même lorsque d'autres applications filtrent les mêmes.
Utiliser les technologies de tag acceptées
Lorsque vous travaillez avec des tags NFC et des appareils Android, le format principal que vous utilisez pour lire
et écrire des données sur des tags est NDEF. Lorsqu'un appareil analyse un tag contenant des données NDEF, Android fournit une assistance
lors de l'analyse du message et de sa distribution dans une NdefMessage
possible. Toutefois, dans certains cas, lorsque vous analysez un tag qui ne contient pas
Données NDEF ou lorsque les données NDEF n'ont pas pu être mappées avec un type MIME ou un URI
Dans ce cas, vous devez ouvrir la communication directement avec le tag, et y lire et y écrire avec
votre propre protocole (en octets bruts). Android fournit une prise en charge générique pour ces cas d'utilisation avec le
le package android.nfc.tech
, décrit dans le tableau 1. Vous pouvez
utiliser la méthode getTechList()
pour déterminer les technologies
acceptée par la balise et crée l'élément TagTechnology
correspondant
objet avec l'une des classes fournies par android.nfc.tech
Classe | Description |
---|---|
TagTechnology |
Interface que toutes les classes de technologie de balise doivent implémenter. |
NfcA |
Permet d'accéder aux propriétés NFC-A (ISO 14443-3A) et aux opérations d'E/S. |
NfcB |
Permet d'accéder aux propriétés NFC-B (ISO 14443-3B) et aux opérations d'E/S. |
NfcF |
Permet d'accéder aux propriétés NFC-F (JIS 6319-4) et aux opérations d'E/S. |
NfcV |
Permet d'accéder aux propriétés NFC-V (ISO 15693) et aux opérations d'E/S. |
IsoDep |
Permet d'accéder aux propriétés ISO-DEP (ISO 14443-4) et aux opérations d'E/S. |
Ndef |
Fournit l'accès aux données et opérations NDEF sur des tags NFC mis en forme en tant que NDEF. |
NdefFormatable |
Fournit des opérations de mise en forme pour les tags pouvant être formatables NDEF. |
Les technologies de tag suivantes ne doivent pas nécessairement être compatibles avec les appareils Android.
Classe | Description |
---|---|
MifareClassic |
Fournit l'accès aux propriétés MIFARE Classic et aux opérations d'E/S, si cet appareil Android est compatible avec MIFARE. |
MifareUltralight |
Fournit l'accès aux propriétés MIFARE Ultralight et aux opérations d'E/S, si cet appareil Android est compatible avec MIFARE. |
Utiliser les technologies de tag et l'intent ACTION_TECH_DISCOVERED
Lorsqu'un appareil analyse un tag qui contient des données NDEF, mais qui n'a pas pu être mappé sur un MIME ou un URI,
le système de distribution des tags tente de démarrer une activité avec l'ACTION_TECH_DISCOVERED
.
l'intention. Le ACTION_TECH_DISCOVERED
est également utilisé lorsqu'un tag
avec des données non-NDEF. Cette création de remplacement vous permet de travailler avec les données de la balise
directement si le système de distribution
des balises ne parvient pas à l'analyser. Les étapes de base
lorsque vous travaillez avec
de tags sont les suivantes:
- Filtrez les résultats pour un intent
ACTION_TECH_DISCOVERED
spécifiant le de balises que vous souhaitez gérer. Consultez la section Filtrage NFC intents pour en savoir plus. En général, le système de distribution des tags tente de démarrer un intentACTION_TECH_DISCOVERED
lorsqu'un message NDEF ne peut pas être mappé sur un type MIME ni avec un URI, ou si le tag analysé ne contient pas de données NDEF. Pour Pour en savoir plus sur la façon dont cela est déterminé, consultez la page sur Tag Dispatch System. - Lorsque votre application reçoit l'intent, obtenez l'objet
Tag
à partir de l'intent:Kotlin
var tagFromIntent: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
- Obtenez une instance de
TagTechnology
en appelant l'une des Méthodes de fabriqueget
des classes du packageandroid.nfc.tech
. Vous pouvez énumérer les technologies compatibles avec la balise en appelantgetTechList()
avant d'appeler une méthode de fabriqueget
. Par exemple, pour obtenir une instance deMifareUltralight
à partir d'unTag
, procédez comme suit:Kotlin
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
Java
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
Lire et écrire dans les tags
La lecture et l'écriture dans un tag NFC impliquent d'obtenir le tag à partir de l'intent et d’ouverture de la communication avec la balise. Vous devez définir votre propre pile de protocoles pour lire et écrire des données au tag. Gardez toutefois à l'esprit que vous pouvez toujours lire et écrire des données NDEF lorsque vous travaillez directement à l'aide d'un tag. C'est à vous de décider comment vous voulez structurer les choses. La L'exemple suivant montre comment utiliser un tag MIFARE Ultralight.
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; } }
Utiliser le système de répartition au premier plan
Le système de répartition au premier plan permet à une activité d'intercepter un intent et une demande ont la priorité sur les autres activités qui gèrent le même intent. L'utilisation de ce système implique construire quelques structures de données pour que le système Android puisse envoyer les des intents à votre application. Pour activer le système de répartition au premier plan:
- Ajoutez le code suivant dans la méthode
onCreate()
de votre activité: <ph type="x-smartling-placeholder">- </ph>
- Créez un objet
PendingIntent
modifiable afin que le système Android puisse le remplir. avec les détails de la balise lors de son analyse.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);
- Déclarez des filtres d'intent pour gérer les intents que vous souhaitez intercepter. Le premier plan
le système de distribution vérifie les filtres d'intent spécifiés avec l'intent reçu lorsque
l'appareil scanne un tag. S'il correspond, votre application gère l'intent. Si c'est le cas
ne correspondent pas, le système de répartition au premier plan se rabat sur le système de répartition des intents.
Lorsque vous spécifiez un ensemble
null
de filtres d'intent et de filtres technologiques, que vous voulez filtrer pour toutes les balises de remplacement deTAG_DISCOVERED
l'intention. L'extrait de code ci-dessous gère tous les types MIME pourNDEF_DISCOVERED
. Toi ne doit gérer que celles dont vous avez besoin.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, };
- Configurez un ensemble de technologies de balises que votre application doit gérer. Appelez la méthode
Object.class.getName()
pour obtenir la classe de technologie que vous que vous souhaitez soutenir.Kotlin
techListsArray = arrayOf(arrayOf<String>(NfcF::class.java.name))
Java
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
- Créez un objet
- Remplacez les rappels de cycle de vie d'activité suivants et ajoutez une logique pour activer et désactiver le
distribution au premier plan lorsque l'activité perd (
onPause()
) et récupère la mise au point (onResume()
).enableForegroundDispatch()
doit être appelé depuis le thread principal et uniquement lorsque l'activité est au premier plan (l'appel dansonResume()
le garantit). Vous devez également implémenter le rappelonNewIntent
pour traiter les données issues de la technologie NFC scannée. .
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 }