Ce document décrit les tâches NFC de base que vous effectuez dans Android. Il explique comment envoyer et recevoir des données NFC sous la forme de messages NDEF, et décrit les API du framework Android qui prennent en charge ces fonctionnalités. Pour en savoir plus sur des sujets plus avancés, y compris sur l'utilisation de données non NDEF, consultez NFC avancé.
La lecture des données NDEF à partir d'un tag NFC est gérée par le système de répartition des tags, qui analyse les tags NFC détectés, catégorise les données de manière appropriée et démarre une application intéressée par les données catégorisées. Une application qui souhaite gérer le tag NFC scanné peut déclarer un filtre d'intent et demander à gérer les données.
Système de distribution des balises
Les appareils Android recherchent généralement les tags NFC lorsque l'écran est déverrouillé, sauf si le NFC est désactivé dans le menu des paramètres de l'appareil. Lorsqu'un appareil Android détecte un tag NFC, le comportement souhaité est que l'activité la plus appropriée gère l'intent sans demander à l'utilisateur quelle application utiliser. Étant donné que les appareils scannent les tags NFC à très courte portée, il est probable que le fait de demander aux utilisateurs de sélectionner manuellement une activité les oblige à éloigner l'appareil du tag et à rompre la connexion. Vous devez développer votre activité pour qu'elle ne gère que les tags NFC qui l'intéressent afin d'empêcher l'affichage du sélecteur d'activité.
Pour vous aider à atteindre cet objectif, Android fournit un système spécial de distribution de tags qui analyse les tags NFC scannés, les analyse et tente de localiser les applications intéressées par les données scannées. Pour ce faire, il :
- Analyser le tag NFC et déterminer le type MIME ou un URI qui identifie la charge utile de données dans le tag.
- Encapsulez le type MIME ou l'URI et la charge utile dans un intent. Ces deux premières étapes sont décrites dans Comment les tags NFC sont mappés aux types MIME et aux URI.
- Lance une activité en fonction de l'intent. Ceci est décrit dans Comment les tags NFC sont distribués aux applications.
Comment les tags NFC sont mappés aux types MIME et aux URI
Avant de commencer à écrire vos applications NFC, il est important de comprendre les différents types de tags NFC, comment le système d'envoi de tags analyse les tags NFC et le travail spécial que le système d'envoi de tags effectue lorsqu'il détecte un message NDEF. Les tags NFC sont disponibles dans une large gamme de technologies et peuvent également être utilisés pour écrire des données de différentes manières. Android est le système d'exploitation qui prend le mieux en charge la norme NDEF, définie par le NFC Forum.
Les données NDEF sont encapsulées dans un message (NdefMessage) contenant un ou plusieurs enregistrements (NdefRecord). Chaque enregistrement NDEF doit être bien formé conformément à la spécification du type d'enregistrement que vous souhaitez créer. Android est également compatible avec d'autres types de tags qui ne contiennent pas de données NDEF. Vous pouvez les utiliser à l'aide des classes du package android.nfc.tech. Pour en savoir plus sur ces technologies, consultez l'article NFC avancé. Pour utiliser ces autres types de tags, vous devez écrire votre propre pile de protocoles pour communiquer avec les tags. Nous vous recommandons donc d'utiliser NDEF lorsque cela est possible pour faciliter le développement et assurer une compatibilité maximale avec les appareils fonctionnant sous Android.
Remarque : Pour télécharger les spécifications NDEF complètes, accédez au site NFC Forum Specifications & Application Documents et consultez Créer des types courants d'enregistrements NDEF pour obtenir des exemples de création d'enregistrements NDEF.
Maintenant que vous avez quelques connaissances sur les tags NFC, les sections suivantes décrivent plus en détail comment Android gère les tags au format NDEF. Lorsqu'un appareil Android lit un tag NFC contenant des données au format NDEF, il analyse le message et tente de déterminer le type MIME ou l'URI d'identification des données. Pour ce faire, le système lit le premier NdefRecord à l'intérieur de NdefMessage pour déterminer comment interpréter l'ensemble du message NDEF (un message NDEF peut contenir plusieurs enregistrements NDEF). Dans un message NDEF bien formé, le premier NdefRecord contient les champs suivants :
- TNF (Type Name Format) à 3 bits
- Indique comment interpréter le champ de type à longueur variable. Les valeurs valides sont décrites dans le Tableau 1.
- Type de longueur variable
- Décrit le type d'enregistrement. Si vous utilisez
TNF_WELL_KNOWN, utilisez ce champ pour spécifier la définition du type d'enregistrement (RTD, Record Type Definition). Les valeurs RTD valides sont décrites dans le Tableau 2. - ID de longueur variable
- Identifiant unique de l'enregistrement. Ce champ n'est pas souvent utilisé, mais si vous devez identifier une balise de manière unique, vous pouvez lui créer un ID.
- Charge utile de longueur variable
- Charge utile de données que vous souhaitez lire ou écrire. Un message NDEF peut contenir plusieurs enregistrements NDEF. Par conséquent, ne partez pas du principe que la charge utile complète se trouve dans le premier enregistrement NDEF du message NDEF.
Le système de répartition des tags utilise les champs TNF et type pour essayer de mapper un type MIME ou un URI au message NDEF. Si l'opération réussit, elle encapsule ces informations dans une intention ACTION_NDEF_DISCOVERED avec la charge utile réelle. Toutefois, il arrive que le système de distribution des tags ne puisse pas déterminer le type de données en fonction du premier enregistrement NDEF. Cela se produit lorsque les données NDEF ne peuvent pas être mappées à un type MIME ou à un URI, ou lorsque la balise NFC ne contient pas de données NDEF au départ. Dans ce cas, un objet Tag contenant des informations sur les technologies et la charge utile du tag est encapsulé dans une intention ACTION_TECH_DISCOVERED.
Le tableau 1 décrit comment le système de répartition des tags mappe les champs TNF et type aux types MIME ou aux URI. Il décrit également les TNF qui ne peuvent pas être mappés à un type MIME ou à un URI.
Dans ce cas, le système de répartition des balises revient à ACTION_TECH_DISCOVERED.
Par exemple, si le système de répartition des tags rencontre un enregistrement de type TNF_ABSOLUTE_URI, il mappe le champ de type à longueur variable de cet enregistrement dans un URI. Le système d'envoi de tag encapsule cet URI dans le champ de données d'un intent ACTION_NDEF_DISCOVERED, ainsi que d'autres informations sur le tag, telles que la charge utile. En revanche, s'il rencontre un enregistrement de type TNF_UNKNOWN, il crée une intention qui encapsule les technologies de la balise.
Tableau 1. TNF compatibles et leurs mappages
| Format du nom de type (TNF) | Mappage |
|---|---|
TNF_ABSOLUTE_URI |
URI basé sur le champ de type. |
TNF_EMPTY |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
TNF_EXTERNAL_TYPE |
URI basé sur l'URN dans le champ "type". L'URN est encodé dans le champ de type NDEF sous une forme abrégée : <domain_name>:<service_name>.
Android mappe cela à un URI au format suivant :
vnd.android.nfc://ext/<domain_name>:<service_name>. |
TNF_MIME_MEDIA |
Type MIME basé sur le champ de type. |
TNF_UNCHANGED |
Non valide dans le premier enregistrement, donc remplacé par ACTION_TECH_DISCOVERED. |
TNF_UNKNOWN |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
TNF_WELL_KNOWN |
Type MIME ou URI selon la définition du type d'enregistrement (RTD) que vous définissez dans le champ "type". Pour en savoir plus sur les RTD disponibles et leurs mappages, consultez le tableau 2. |
Tableau 2. RTD compatibles pour TNF_WELL_KNOWN et leurs mappages
| Définition du type d'enregistrement (DTE) | Mappage |
|---|---|
RTD_ALTERNATIVE_CARRIER |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
RTD_HANDOVER_CARRIER |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
RTD_HANDOVER_REQUEST |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
RTD_HANDOVER_SELECT |
Utilise ACTION_TECH_DISCOVERED en cas de besoin. |
RTD_SMART_POSTER |
URI basé sur l'analyse de la charge utile. |
RTD_TEXT |
Type MIME de text/plain. |
RTD_URI |
URI basé sur la charge utile. |
Comment les tags NFC sont-ils distribués aux applications ?
Une fois que le système de répartition des balises a créé un intent qui encapsule la balise NFC et ses informations d'identification, il envoie l'intent à une application intéressée qui filtre l'intent. Si plusieurs applications peuvent gérer l'intent, le sélecteur d'activité s'affiche pour permettre à l'utilisateur de sélectionner l'activité. Le système de répartition des tags définit trois intents, listés par ordre de priorité décroissant :
-
ACTION_NDEF_DISCOVERED: cette intention est utilisée pour démarrer une activité lorsqu'une balise contenant une charge utile NDEF est scannée et est d'un type reconnu. Il s'agit de l'intent de priorité la plus élevée. Le système de répartition des tags tente de démarrer une activité avec cet intent avant tout autre intent, dans la mesure du possible.Remarque : À partir d'Android 16, la lecture des tags NFC qui stockent des liens URL (c'est-à-dire dont le schéma URI est "https://" ou "http://") déclenchera l'intent
ACTION_VIEWau lieu de l'intentACTION_NDEF_DISCOVERED. ACTION_TECH_DISCOVERED: si aucune activité n'est enregistrée pour gérer l'intentACTION_NDEF_DISCOVERED, le système de distribution de tags tente de démarrer une application avec cet intent. Cette intention est également lancée directement (sans lancerACTION_NDEF_DISCOVEREDau préalable) si le tag scanné contient des données NDEF qui ne peuvent pas être mappées à un type MIME ou à un URI, ou si le tag ne contient pas de données NDEF, mais qu'il est d'une technologie de tag connue.ACTION_TAG_DISCOVERED: cet intent est lancé si aucune activité ne gère les intentsACTION_NDEF_DISCOVEREDouACTION_TECH_DISCOVERED.
Voici comment fonctionne le système de répartition des balises :
- Essayez de démarrer une activité avec l'intent créé par le système de répartition des balises lors de l'analyse de la balise NFC (
ACTION_NDEF_DISCOVEREDouACTION_TECH_DISCOVERED). - Si aucun filtre d'activité ne correspond à cet intent, essayez de démarrer une activité avec l'intent de priorité immédiatement inférieure (
ACTION_TECH_DISCOVEREDouACTION_TAG_DISCOVERED) jusqu'à ce qu'une application filtre l'intent ou jusqu'à ce que le système de répartition des tags essaie tous les intents possibles. - Si aucune application ne filtre pour l'un des intents, ne faites rien.
Dans la mesure du possible, utilisez les messages NDEF et l'intention ACTION_NDEF_DISCOVERED, car il s'agit de la plus spécifique des trois. Cette intention vous permet de démarrer votre application à un moment plus approprié que les deux autres intentions, ce qui offre une meilleure expérience à l'utilisateur.
Demander l'accès NFC dans le fichier manifeste Android
Avant de pouvoir accéder au matériel NFC d'un appareil et gérer correctement les intents NFC, déclarez les éléments suivants dans votre fichier AndroidManifest.xml :
- L'élément NFC
<uses-permission>pour accéder au matériel NFC :<uses-permission android:name="android.permission.NFC" />
- Version minimale du SDK compatible avec votre application. Le niveau d'API 9 ne prend en charge qu'un envoi de tag limité via
ACTION_TAG_DISCOVEREDet ne donne accès qu'aux messages NDEF via l'extraEXTRA_NDEF_MESSAGES. Aucune autre propriété de tag ni opération d'E/S n'est accessible. Le niveau d'API 10 inclut une prise en charge complète des lecteurs/enregistreurs ainsi que l'envoi au premier plan de messages NDEF. Le niveau d'API 14 fournit des méthodes pratiques supplémentaires pour créer des enregistrements NDEF.<uses-sdk android:minSdkVersion="10"/> - L'élément
uses-featurepour que votre application n'apparaisse sur Google Play que pour les appareils disposant d'un matériel NFC :<uses-feature android:name="android.hardware.nfc" android:required="true" />
Si votre application utilise la fonctionnalité NFC, mais que cette fonctionnalité n'est pas essentielle à votre application, vous pouvez omettre l'élément
uses-featureet vérifier la disponibilité de la fonctionnalité NFC au moment de l'exécution en vérifiant sigetDefaultAdapter()estnull.
Filtrer les intents NFC
Pour démarrer votre application lorsqu'un tag NFC que vous souhaitez gérer est scanné, votre application peut filtrer un, deux ou les trois intents NFC dans le fichier manifeste Android. Toutefois, vous souhaitez généralement filtrer l'intent ACTION_NDEF_DISCOVERED pour contrôler au mieux le moment où votre application démarre. L'intention ACTION_TECH_DISCOVERED est une solution de repli pour ACTION_NDEF_DISCOVERED lorsqu'aucun filtre d'application n'est défini pour ACTION_NDEF_DISCOVERED ou lorsque la charge utile n'est pas NDEF. Le filtrage par ACTION_TAG_DISCOVERED est généralement une catégorie trop générale pour être utilisée comme filtre. De nombreuses applications filtreront ACTION_NDEF_DISCOVERED ou ACTION_TECH_DISCOVERED avant ACTION_TAG_DISCOVERED. La probabilité de démarrage de votre application est donc faible. ACTION_TAG_DISCOVERED n'est disponible qu'en dernier recours pour les applications à filtrer dans les cas où aucune autre application n'est installée pour gérer l'intent ACTION_NDEF_DISCOVERED ou ACTION_TECH_DISCOVERED.
Comme les déploiements de tags NFC varient et ne sont souvent pas sous votre contrôle, cela n'est pas toujours possible. C'est pourquoi vous pouvez revenir aux deux autres intents si nécessaire. Lorsque vous contrôlez les types de tags et les données écrites, il est recommandé d'utiliser NDEF pour formater vos tags. Les sections suivantes décrivent comment filtrer chaque type d'intention.
ACTION_NDEF_DISCOVERED
Pour filtrer les intents ACTION_NDEF_DISCOVERED, déclarez le filtre d'intent avec le type de données que vous souhaitez filtrer. L'exemple suivant filtre les intents ACTION_NDEF_DISCOVERED avec un type 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'exemple suivant filtre un URI au format 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
Si votre activité filtre l'intent ACTION_TECH_DISCOVERED, vous devez créer un fichier de ressources XML qui spécifie les technologies compatibles avec votre activité dans un ensemble tech-list. Votre activité est considérée comme une correspondance si un ensemble tech-list est un sous-ensemble des technologies compatibles avec la balise, que vous pouvez obtenir en appelant getTechList().
Par exemple, si la balise scannée est compatible avec MifareClassic, NdefFormatable et NfcA, votre ensemble tech-list doit spécifier les trois, deux ou une de ces technologies (et rien d'autre) pour que votre activité soit mise en correspondance.
L'exemple suivant définit toutes les technologies. Vous devez supprimer ceux qui ne sont pas compatibles avec votre tag NFC. Enregistrez ce fichier (vous pouvez lui donner le nom de votre choix) dans le dossier <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>
Vous pouvez également spécifier plusieurs ensembles tech-list. Chacun des ensembles tech-list est considéré indépendamment, et votre activité est considérée comme correspondante si un seul ensemble tech-list est un sous-ensemble des technologies renvoyées par getTechList(). Cela fournit la sémantique AND et OR pour les technologies correspondantes. L'exemple suivant correspond aux tags compatibles avec les technologies NfcA et Ndef, ou avec les technologies NfcB et 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>
Dans votre fichier AndroidManifest.xml, spécifiez le fichier de ressources que vous venez de créer dans l'élément <meta-data> à l'intérieur de l'élément <activity>, comme dans l'exemple suivant :
<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>
Pour en savoir plus sur l'utilisation des technologies de tag et de l'intention ACTION_TECH_DISCOVERED, consultez Utiliser les technologies de tag compatibles dans le document sur la technologie NFC avancée.
ACTION_TAG_DISCOVERED
Pour filtrer sur ACTION_TAG_DISCOVERED, utilisez le filtre d'intent suivant :
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
ACTION_VIEW
À partir d'Android 16, la lecture des tags NFC qui stockent des liens URL déclenchera l'intent ACTION_VIEW. Pour filtrer les données ACTION_VIEW, consultez this. Utilisez Android app links pour ouvrir votre application pour l'URL.
Obtenir des informations à partir d'intentions
Si une activité démarre en raison d'un intent NFC, vous pouvez obtenir des informations sur le tag NFC scanné à partir de l'intent. Les intents peuvent contenir les extras suivants en fonction du tag qui a été scanné :
EXTRA_TAG(obligatoire) : objetTagreprésentant le tag scanné.EXTRA_NDEF_MESSAGES(facultatif) : tableau de messages NDEF analysés à partir du tag. Cet extra est obligatoire pour les intentsACTION_NDEF_DISCOVERED.EXTRA_ID(facultatif) : ID de bas niveau du tag.
Pour obtenir ces extras, vérifiez si votre activité a été lancée avec l'une des intentions NFC pour vous assurer qu'un tag a été scanné, puis obtenez les extras à partir de l'intention. L'exemple suivant vérifie l'intent ACTION_NDEF_DISCOVERED et récupère les messages NDEF à partir d'un extra d'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. ... } } }
Vous pouvez également obtenir un objet Tag à partir de l'intention, qui contiendra la charge utile et vous permettra d'énumérer les technologies de la balise :
Kotlin
val tag: Tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
Java
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Créer des types courants d'enregistrements NDEF
Cette section explique comment créer des types courants d'enregistrements NDEF pour vous aider à écrire sur des tags NFC. À partir d'Android 4.0 (niveau d'API 14), la méthode createUri() est disponible pour vous aider à créer automatiquement des enregistrements URI. À partir d'Android 4.1 (niveau d'API 16), createExternal() et createMime() sont disponibles pour vous aider à créer des enregistrements NDEF de type MIME et externe. Utilisez ces méthodes d'assistance autant que possible pour éviter les erreurs lors de la création manuelle d'enregistrements NDEF.
Cette section explique également comment créer le filtre d'intent correspondant pour l'enregistrement. Tous ces exemples d'enregistrements NDEF doivent figurer dans le premier enregistrement NDEF du message NDEF que vous écrivez sur un tag.
TNF_ABSOLUTE_URI
Remarque : Nous vous recommandons d'utiliser le type RTD_URI plutôt que TNF_ABSOLUTE_URI, car il est plus efficace.
Vous pouvez créer un enregistrement NDEF TNF_ABSOLUTE_URI comme suit :
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]);
Le filtre d'intent pour l'enregistrement NDEF précédent se présenterait comme suit :
<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
Vous pouvez créer un enregistrement NDEF TNF_MIME_MEDIA de différentes manières :
Utiliser la méthode 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")));
Créer manuellement le 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")));
Le filtre d'intent pour l'enregistrement NDEF précédent se présenterait comme suit :
<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 avec RTD_TEXT
Vous pouvez créer un enregistrement NDEF TNF_WELL_KNOWN comme suit :
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; }
Le filtre d'intent pour l'enregistrement NDEF précédent se présenterait comme suit :
<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 avec RTD_URI
Vous pouvez créer un enregistrement NDEF TNF_WELL_KNOWN de différentes manières :
Utiliser la méthode createUri(String) :
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Utiliser la méthode 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);
Créer manuellement le 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);
Le filtre d'intent pour l'enregistrement NDEF précédent se présenterait comme suit :
<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
Vous pouvez créer un enregistrement NDEF TNF_EXTERNAL_TYPE de différentes manières :
Utiliser la méthode 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);
Créer manuellement le 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);
Le filtre d'intent pour l'enregistrement NDEF précédent se présenterait comme suit :
<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>
Utilisez TNF_EXTERNAL_TYPE pour les déploiements de tags NFC plus génériques afin de mieux prendre en charge les appareils Android et non Android.
Remarque : Les URN pour TNF_EXTERNAL_TYPE ont un format canonique de urn:nfc:ext:example.com:externalType. Toutefois, la spécification RTD du forum NFC indique que la partie urn:nfc:ext: de l'URN doit être omise de l'enregistrement NDEF. Il vous suffit donc de fournir le domaine (example.com dans l'exemple) et le type (externalType dans l'exemple) séparés par un deux-points.
Lors de l'envoi de TNF_EXTERNAL_TYPE, Android convertit l'URN urn:nfc:ext:example.com:externalType
en URI vnd.android.nfc://ext/example.com:externalType, qui est ce que déclare le filtre d'intent dans l'exemple.
Enregistrements des applications Android
Introduit dans Android 4.0 (niveau d'API 14), un enregistrement d'application Android (AAR) offre une plus grande certitude que votre application est lancée lorsqu'un tag NFC est scanné. Un enregistrement AAR contient le nom du package d'une application intégrée dans un enregistrement NDEF. Vous pouvez ajouter un AAR à n'importe quel enregistrement NDEF de votre message NDEF, car Android recherche les AAR dans l'ensemble du message NDEF. S'il trouve un fichier AAR, il démarre l'application en fonction du nom du package à l'intérieur du fichier AAR. Si l'application n'est pas présente sur l'appareil, Google Play est lancé pour la télécharger.
Les AAR sont utiles si vous souhaitez empêcher d'autres applications de filtrer la même intention et potentiellement de gérer des balises spécifiques que vous avez déployées. Les AAR ne sont compatibles qu'au niveau de l'application, en raison de la contrainte liée au nom du package, et non au niveau de l'activité comme avec le filtrage des intents. Si vous souhaitez gérer un intent au niveau de l'activité, utilisez des filtres d'intent.
Si un tag contient un AAR, le système de répartition des tags procède comme suit :
- Essayez de démarrer une activité à l'aide d'un filtre d'intent comme d'habitude. Si l'activité qui correspond à l'intent correspond également à l'AAR, démarrez l'activité.
- Si l'activité qui filtre l'intent ne correspond pas à l'AAR, si plusieurs activités peuvent gérer l'intent ou si aucune activité ne gère l'intent, démarrez l'application spécifiée par l'AAR.
- Si aucune application ne peut démarrer avec l'AAR, accédez à Google Play pour télécharger l'application basée sur l'AAR.
Remarque : Vous pouvez remplacer les AAR et le système de distribution d'intent avec le système de distribution au premier plan, qui permet à une activité au premier plan d'avoir la priorité lorsqu'une balise NFC est détectée. Avec cette méthode, l'activité doit être au premier plan pour remplacer les AAR et le système de distribution d'intent.
Si vous souhaitez toujours filtrer les tags analysés qui ne contiennent pas d'AAR, vous pouvez déclarer les filtres d'intent comme d'habitude. Cela peut être utile si votre application s'intéresse à d'autres tags qui ne contiennent pas d'AAR. Par exemple, vous souhaitez peut-être garantir que votre application gère les tags propriétaires que vous déployez, ainsi que les tags généraux déployés par des tiers. N'oubliez pas que les fichiers AAR sont spécifiques aux appareils Android 4.0 ou version ultérieure. Par conséquent, lorsque vous déployez des balises, vous devez probablement utiliser une combinaison de fichiers AAR et de types MIME/URI pour prendre en charge la plus large gamme d'appareils possible. De plus, lorsque vous déployez des tags NFC, réfléchissez à la manière dont vous souhaitez les écrire pour permettre la compatibilité avec le plus grand nombre d'appareils (appareils fonctionnant sous Android et autres appareils). Pour ce faire, définissez un type MIME ou un URI relativement unique afin de faciliter la distinction par les applications.
Android fournit une API simple pour créer un fichier AAR, createApplicationRecord(). Il vous suffit d'intégrer l'AAR n'importe où dans votre NdefMessage. Vous ne souhaitez pas utiliser le premier enregistrement de votre NdefMessage, sauf si l'AAR est le seul enregistrement du NdefMessage. En effet, le système Android vérifie le premier enregistrement d'un NdefMessage pour déterminer le type MIME ou l'URI du tag, qui est utilisé pour créer un intent que les applications peuvent filtrer. Le code suivant montre comment créer un fichier 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")} ); )
Liste d'autorisation des applications pour la lecture des tags NFC
À partir d'Android 16, les utilisateurs sont avertis lorsqu'une application reçoit sa première intention NFC pour scanner des tags NFC. L'utilisateur peut choisir d'empêcher l'application de scanner les tags NFC dans la notification.
- Les applications peuvent vérifier si l'utilisateur a autorisé l'application à scanner les tags NFC à l'aide de
NfcAdapter.isTagIntentAllowed(). - Les applications peuvent inviter l'utilisateur à autoriser à nouveau la lecture des tags NFC en envoyant l'intent
ACTION_CHANGE_TAG_INTENT_PREFERENCE.
Remarque : La liste des applications autorisées pour le scan de tags NFC est accessible sous Settings > Apps > Special app access > Launch via NFC.