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 compatibles ces fonctionnalités. Pour des sujets plus avancés, y compris une discussion sur le travail avec des données non-NDEF, consultez la section NFC avancé.
Il existe deux cas d'utilisation principaux lorsque vous travaillez avec des données NDEF et Android:
- Lire les données NDEF à partir d'un tag NFC
- Transfert de messages NDEF d'un appareil à un autre avec Android BeamTM
La lecture des données NDEF d'un tag NFC est gérée par le service de distribution des tags. de sécurité, qui analyse les tags NFC détectés, classe les données de manière appropriée et commence une application qui s'intéresse aux données catégorisées. Une application qui veut gérer le tag NFC scanné peut déclarer un filtre d'intent et pour traiter les données.
La fonctionnalité Android BeamTM permet à un appareil de transmettre un message NDEF à un autre appareil en tapotant physiquement les appareils ensemble. Cette interaction permet un moyen plus facile d'envoyer des données que d'autres technologies sans fil comme le Bluetooth, car avec la technologie NFC, découverte ou association est requise. La connexion démarre automatiquement lorsque deux appareils à portée. Android Beam est disponible via un ensemble d'API NFC, de sorte que toute application peut transmettre des informations entre les appareils. Par exemple, les applications Contacts, Navigateur et YouTube utilisent Android Beam pour partager des contacts, des pages Web et des vidéos avec d'autres appareils
Le système de répartition des balises
Les appareils Android recherchent généralement des tags NFC lorsque l'écran est déverrouillé, sauf si la technologie NFC est désactivée dans le menu "Paramètres" de l'appareil. Lorsqu'un appareil Android détecte un tag NFC, le comportement souhaité consiste à utiliser l'activité la plus appropriée pour gérer l'intent sans demander à l'utilisateur quelle application utiliser. Étant donné que les appareils scannent les tags NFC à une portée très courte, il est probable que les utilisateurs soient sélectionner une activité les oblige à éloigner l'appareil du Tag et à interrompre la connexion. Vous devez développer votre activité de manière à ne gérer que les tags NFC qui sont importants pour votre activité. empêcher l'affichage du sélecteur d'activité.
Pour vous aider à atteindre cet objectif, Android fournit un système spécial de distribution des balises qui analyse les Les tags NFC, les analyse et essaie de localiser les applications intéressées par les données scannées. Il le fait en:
- Analyser le tag NFC et déterminer le type MIME ou un URI qui identifie la charge utile des données dans le tag.
- Encapsuler le type MIME ou l'URI et la charge utile dans un intent. Ces deux premiers la procédure est décrite dans la section Mise en correspondance des tags NFC avec les types MIME et les URI.
- Lance une activité basée sur l'intent. Cette procédure est décrite à la section Modalités de distribution des tags NFC aux applications
Mappage des tags NFC avec les types MIME et les URI
Avant de commencer à écrire vos applications NFC, il est important de comprendre les différents les types de tags NFC, la façon dont le système de distribution des tags analyse les tags NFC et les tâches spécifiques que le tag effectue lorsqu'il détecte un message NDEF. Les tags NFC sont fournis un large éventail de technologies et peuvent également y écrire des données de nombreuses façons différentes. Android est le plus compatible avec la norme NDEF, qui est définie par le forum NFC.
Les données NDEF sont encapsulées dans un message (NdefMessage
) qui en contient 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
prend également en charge d'autres types de tags ne contenant pas de données NDEF, que vous pouvez utiliser en utilisant
les classes du package android.nfc.tech
. Pour en savoir plus
sur ces technologies, consultez la section NFC avancé. L'utilisation de ces autres types de tags implique
écrire votre propre pile de protocoles pour communiquer avec les tags. Nous vous recommandons donc d'utiliser NDEF lorsque
pour faciliter le développement et assurer
une compatibilité maximale avec les appareils Android.
Remarque: Pour télécharger les spécifications NDEF complètes, consultez la page NFC Forum Specifications & Application Documents (en anglais) et consultez Créer des types courants d'enregistrements NDEF pour découvrir comment créer des enregistrements NDEF.
Maintenant que vous en savez un peu plus 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 analyse un tag NFC contenant un NDEF
données formatées, il analyse le message et tente de déterminer le type MIME des données ou l'identification
URI. Pour ce faire, le système lit la première NdefRecord
dans NdefMessage
pour déterminer comment interpréter l'intégralité du message NDEF (un message NDEF peut
comporter plusieurs enregistrements NDEF). Dans un message NDEF bien formé, le premier élément NdefRecord
contient les champs suivants:
- TNF (Type Name Format) 3 bits
- Indique comment interpréter le champ de type de longueur variable. Les valeurs valides sont décrites dans le Tableau 1.
- Type de longueur variable
- Décrit le type de l'enregistrement. Si vous utilisez
TNF_WELL_KNOWN
, utilisez ce champ pour spécifier la définition du type d'enregistrement (RTD). 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 un tag de façon unique, vous pouvez créer un ID pour celui-ci.
- Charge utile de longueur variable
- La charge utile de données réelle que vous souhaitez lire ou écrire. Un 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 NDEF du message NDEF.
Le système de distribution des tags utilise les champs TNF et de 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 un intent ACTION_NDEF_DISCOVERED
avec la charge utile réelle. Cependant,
sont des cas où le système de distribution des tags ne peut pas déterminer le type de données en fonction du premier NDEF
enregistrer. Cela se produit lorsque les données NDEF ne peuvent pas être mappées à un type ou à un URI MIME, ou lorsque le
Le tag NFC ne contient pas de données NDEF pour commencer. Dans ce cas, un objet Tag
contenant des informations sur les technologies du tag et la charge utile sont
encapsulé dans un intent ACTION_TECH_DISCOVERED
.
Le tableau 1 décrit comment le système de distribution des balises mappe le TNF et le 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 tags fait appel
ACTION_TECH_DISCOVERED
Par exemple, si le système de distribution des tags rencontre un enregistrement de type TNF_ABSOLUTE_URI
, il mappe le champ de type de longueur variable de cet enregistrement.
dans un URI. Le système de distribution des tags encapsule cet URI dans le champ de données d'un intent ACTION_NDEF_DISCOVERED
ainsi que d'autres informations sur la balise.
comme la charge utile. En revanche, s'il rencontre un enregistrement de type TNF_UNKNOWN
, il crée un intent qui encapsule les technologies du tag.
à la place.
Format de nom de type (TNF) | Mappage |
---|---|
TNF_ABSOLUTE_URI |
URI basé sur le champ de type. |
TNF_EMPTY |
Retour à ACTION_TECH_DISCOVERED . |
TNF_EXTERNAL_TYPE |
URI basé sur l'URL dans le champ "Type". L'URL est encodée dans le champ de type NDEF dans
une forme abrégée: <domain_name>:<service_name> .
Android mappe cette valeur sur un URI au format suivant:
vnd.android.nfc://ext/<domain_name>:<service_name> |
TNF_MIME_MEDIA |
Type MIME en fonction du champ de type. |
TNF_UNCHANGED |
Non valide dans le premier enregistrement, donc revient à
ACTION_TECH_DISCOVERED |
TNF_UNKNOWN |
Retour à ACTION_TECH_DISCOVERED . |
TNF_WELL_KNOWN |
le type MIME ou l'URI, selon la définition du type d'enregistrement (RTD), que vous avez définie dans le . Consultez le Tableau 2 pour en savoir plus sur les RTD disponibles et leurs correspondances. |
Définition du type d'enregistrement (RTD) | Mappage |
---|---|
RTD_ALTERNATIVE_CARRIER |
Retour à ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_CARRIER |
Retour à ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_REQUEST |
Retour à ACTION_TECH_DISCOVERED . |
RTD_HANDOVER_SELECT |
Retour à ACTION_TECH_DISCOVERED . |
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 envoyés aux applications ?
Lorsque le système de distribution des tags a terminé, créez un intent qui encapsule le tag NFC et ses d'informations d'identification, il envoie l'intent à une application intéressée des filtres pour l'intent. Si plusieurs applications peuvent gérer l'intent, le sélecteur d'activité s'affiche afin que l'utilisateur puisse sélectionner l'activité. Le système de distribution des tags définit trois intents, qui sont classés par ordre décroissant de priorité:
-
ACTION_NDEF_DISCOVERED
: cet intent permet de démarrer une Activité lorsqu'un tag contenant une charge utile NDEF est analysé et de type reconnu. C'est l'intent ayant la priorité la plus élevée, et le système de distribution des balises tente de démarrer une activité avec cette intent avant tout autre intent, dans la mesure du possible. ACTION_TECH_DISCOVERED
: si aucune activité n'est enregistrée gérerACTION_NDEF_DISCOVERED
le système de distribution des tags tente de démarrer une application avec cet intent. Ce l'intent est également lancé directement (sans démarrerACTION_NDEF_DISCOVERED
au préalable) si la balise analysée contient des données NDEF qui ne peuvent pas être mappées avec un type MIME ou un URI, ou si le tag ne contient pas NDEF mais il s'agit d'une technologie d'ajout de balises connue.ACTION_TAG_DISCOVERED
: cet intent est démarré si aucune activité ne gèreACTION_NDEF_DISCOVERED
niACTION_TECH_DISCOVERED
les intents.
Le système de répartition des balises fonctionne de manière basique comme suit:
- Essayer de démarrer une activité avec l'intent créé par le système de distribution des tags
lors de l'analyse du tag NFC
ACTION_NDEF_DISCOVERED
ouACTION_TECH_DISCOVERED
). - Si aucun filtre d'activité n'est appliqué à cet intent, essayez de démarrer une activité avec l'élément
l'intent ayant la priorité la plus faible (
ACTION_TECH_DISCOVERED
ouACTION_TAG_DISCOVERED
) jusqu'à ce qu'une application filtre ou jusqu'à ce que le système de distribution des tags essaie tous les intents possibles. - Si aucune application ne filtre les intents, ne faites rien.
Dans la mesure du possible, utilisez les messages NDEF et l'intent ACTION_NDEF_DISCOVERED
, car il s'agit de l'intent le plus spécifique
les trois. Cet intent vous permet de lancer votre application à un moment plus approprié
deux autres intents, ce qui améliore
l'expérience utilisateur.
Demander un accès NFC dans le fichier manifeste Android
Avant de pouvoir accéder au matériel NFC d'un appareil et de gérer correctement les intents NFC, déclarez ces
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 n'accepte
une distribution limitée des tags via
ACTION_TAG_DISCOVERED
et ne donne l'accès aux messages NDEF via l'extraEXTRA_NDEF_MESSAGES
. Non d'autres propriétés de tag ou opérations d'E/S sont accessibles. Niveau d'API 10 Compatibilité complète avec les lecteurs/rédacteurs, transfert NDEF au premier plan et niveau d'API 14 permet de transférer plus facilement des messages NDEF vers d'autres appareils avec Android Beam et d'autres méthodes pratiques pour créer des enregistrements NDEF.<uses-sdk android:minSdkVersion="10"/>
- L'élément
uses-feature
afin que votre application s'affiche dans Google Play uniquement pour les appareils dotés de matériel NFC:<uses-feature android:name="android.hardware.nfc" android:required="true" />
Si votre application utilise la fonctionnalité NFC, mais que celle-ci n'est pas essentielle pour votre application, vous pouvez omettre l'élément
uses-feature
et vérifier la disponibilité de la technologie NFC à l'adresse l'environnement d'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. Cependant, vous
vous souhaitez généralement filtrer
l'intent ACTION_NDEF_DISCOVERED
pour
un contrôle maximal sur le démarrage de votre application. L'intent ACTION_TECH_DISCOVERED
est une solution de remplacement pour ACTION_NDEF_DISCOVERED
lorsqu'aucune application n'est filtrée
ACTION_NDEF_DISCOVERED
ou lorsque la charge utile n'est pas
NDEF. Le filtrage de ACTION_TAG_DISCOVERED
est généralement trop général
une catégorie à filtrer. De nombreuses applications filtreront ACTION_NDEF_DISCOVERED
ou ACTION_TECH_DISCOVERED
avant le ACTION_TAG_DISCOVERED
. Il est donc peu probable que votre application présente
à partir de zéro. ACTION_TAG_DISCOVERED
n'est disponible qu'en dernier recours
des applications lorsqu'aucune autre application n'est installée pour gérer
Intent ACTION_NDEF_DISCOVERED
ou ACTION_TECH_DISCOVERED
.
Les déploiements de tags NFC étant variables et souvent sous votre contrôle, ce n'est pas toujours le cas. c'est pourquoi vous pouvez revenir aux deux autres intents si nécessaire. Lorsque vous avez sur les types de tags et de données écrites, nous vous recommandons d'utiliser NDEF pour formater votre . Les sections suivantes décrivent comment filtrer chaque type d'intent.
ACTION_NDEF_DISCOVERED
Pour filtrer les intents ACTION_NDEF_DISCOVERED
, déclarez le
filtre d'intent et le type de données que vous souhaitez filtrer. La
exemples de filtres suivants pour ACTION_NDEF_DISCOVERED
intents avec un type MIME de 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 sous la forme suivante :
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>
TECHNOLOGIE D'ACTION DÉCOUVERTE
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
est considéré comme une correspondance si un ensemble tech-list
est un sous-ensemble des technologies
pris en charge par la balise, que vous pouvez obtenir en appelant getTechList()
.
Par exemple, si le tag analysé est compatible avec MifareClassic, NdefFormatable et NfcA, votre
L'ensemble tech-list
doit spécifier les trois, deux ou l'une des technologies (et aucun élément
else) pour que votre activité soit mise en correspondance.
L'exemple suivant définit toutes les technologies. Vous devez supprimer celles qui ne le sont pas
compatible avec votre tag NFC. Enregistrez ce fichier (vous pouvez lui attribuer le nom de votre choix) dans
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 tech-list
est considéré comme indépendant, et votre activité est considérée comme une correspondance si un
L'ensemble tech-list
est un sous-ensemble des technologies renvoyées par getTechList()
. Cela fournit AND
et OR
pour les technologies de mise en correspondance. L'exemple suivant correspond aux balises compatibles avec le paramètre
technologies NfcA et Ndef, ou compatibles 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 <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 balise et de l'intent ACTION_TECH_DISCOVERED
, consultez Utiliser des balises compatibles
technologies décrites dans le document "NFC avancé".
ACTION_TAG_DÉCOUVERTE
Pour filtrer sur ACTION_TAG_DISCOVERED
, utilisez l'intent suivant
filtre:
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
Obtenir des informations à partir des intents
Si une activité démarre en raison d'un intent NFC, vous pouvez obtenir des informations sur l'objet NFC scanné. de l'intent. Les intents peuvent contenir les extras suivants en fonction de la balise analysée:
EXTRA_TAG
(obligatoire): objetTag
représentant le tag scanné.EXTRA_NDEF_MESSAGES
(facultatif): tableau de messages NDEF analysées à partir de la balise. Cet extra est obligatoire pourACTION_NDEF_DISCOVERED
intents.EXTRA_ID
(facultatif): ID de bas niveau de la balise.
Pour obtenir ces extras, vérifiez si votre activité a été lancée avec l'un des
les intents NFC pour vérifier qu'un tag a bien été scanné, puis obtenir les extras
l'intention. L'exemple suivant vérifie la présence de ACTION_NDEF_DISCOVERED
intent et obtient les messages NDEF d'un intent supplémentaire.
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'intent, qui
contenir la charge utile et vous permettre d'énumérer les technologies du tag:
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 lors de l'écriture dans
Tags NFC ou envoi de données avec Android Beam À partir d'Android 4.0 (niveau d'API 14),
La méthode createUri()
est disponible pour vous aider à créer
automatiquement les enregistrements URI. À partir d'Android 4.1 (niveau d'API 16),
createExternal()
et createMime()
sont disponibles pour vous aider à créer
Enregistrements MIME et enregistrements NDEF de type 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 les d'intent pour l'enregistrement. Tous ces exemples d'enregistrements NDEF doivent se trouver dans le premier NDEF d'enregistrement du message NDEF que vous écrivez dans un tag ou via un partage partagé.
TNF_ABSOLUTE_URI
Remarque:Nous vous recommandons d'utiliser le
Saisissez RTD_URI
à la place.
de TNF_ABSOLUTE_URI
, car il est plus efficace.
Vous pouvez créer un enregistrement NDEF TNF_ABSOLUTE_URI
de la manière suivante :
:
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 ressemblerait à ceci:
<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:
Avec 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éez le NdefRecord
manuellement:
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 ressemblerait à ceci:
<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
de la manière suivante:
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 ressemblerait à ceci:
<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:
Avec la méthode createUri(String)
:
Kotlin
val rtdUriRecord1 = NdefRecord.createUri("https://example.com")
Java
NdefRecord rtdUriRecord1 = NdefRecord.createUri("https://example.com");
Avec 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éez le NdefRecord
manuellement:
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 ressemblerait à ceci:
<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
dans le code suivant :
différentes manières:
Avec 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éez le NdefRecord
manuellement:
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 ressemblerait à ceci:
<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 déployer davantage de tags NFC génériques afin de mieux prendre en charge ces deux types de tags.
Appareils Android et appareils non compatibles avec Android
Remarque: Les URN pour TNF_EXTERNAL_TYPE
ont le format canonique suivant:
urn:nfc:ext:example.com:externalType
, mais la spécification NFC Forum RTD
déclare que la partie urn:nfc:ext:
de l'URL doit être omise du
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 le signe deux-points.
Lors de l'envoi de TNF_EXTERNAL_TYPE
, Android convertit l'URL urn:nfc:ext:example.com:externalType
en URI vnd.android.nfc://ext/example.com:externalType
, ce qui correspond à
le filtre d'intent déclaré dans l'exemple.
Enregistrements d'applications Android
Introduit dans Android 4.0 (niveau d'API 14), un enregistrement d'application Android (AAR) offre une de certitude que votre application est démarrée lorsqu'un tag NFC est scanné. Un AAR a 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 car Android recherche des AAR dans l'ensemble du message NDEF. S'il trouve un AAR, il commence l'application en fonction du nom du package dans l'AAR. Si l'application n'est pas présente sur le appareil, Google Play est lancé pour télécharger l'application.
Les AAR sont utiles si vous souhaitez empêcher d'autres applications de filtrer pour le même intent et pour gérer potentiellement les balises que vous avez déployées. Les AAR ne sont acceptés qu'au niveau au niveau de l'application, en raison de la contrainte du nom du package, et non au niveau de l'activité, comme le filtrage d'intents. Si vous souhaitez gérer un intent au niveau de l'activité, utilisez des filtres d'intent.
Si une balise contient un fichier AAR, le système de répartition des balises 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, lancez l'activité.
- Si l'activité qui filtre l'intent ne correspond pas à AAR, si plusieurs activités peuvent gérer l'intent ou si aucune activité ne gère l'intent, 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 l'application en fonction de l'AAR.
Remarque:Vous pouvez ignorer les AAR et le système de distribution des intents avec la premier plan système de répartition, qui permet à une activité de premier plan d'avoir la priorité lorsqu'un tag NFC est découverte. Avec cette méthode, l'activité doit être au premier plan pour ignorer les AAR et du système de répartition des intents.
Si vous souhaitez toujours filtrer les tags analysés qui ne contiennent pas d'AAR, vous pouvez déclarer comme d'habitude. Ceci est utile si d'autres balises s'intéressent à votre application. qui ne contiennent pas d'AAR. Par exemple, vous voulez 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. À retenir que les AAR sont propres aux appareils Android 4.0 ou version ultérieure. Lorsque vous déployez des balises, pour utiliser une combinaison d'AAR et de types/URI MIME afin de prendre en charge une large gamme d'appareils. Dans De plus, lorsque vous déployez des tags NFC, réfléchissez à la manière dont vous souhaitez les écrire pour activer compatible avec la plupart des appareils (appareils Android et autres). Pour ce faire, vous pouvez définir un type MIME ou un URI relativement unique pour permettre aux applications de les distinguer plus facilement.
Android fournit une API simple pour créer un AAR,
createApplicationRecord()
Tout ce dont vous avez besoin pour
consiste à intégrer l'AAR n'importe où dans votre NdefMessage
. Vous ne voulez pas
pour utiliser le premier enregistrement de votre NdefMessage
, sauf si l'AAR est le seul
dans NdefMessage
. En effet, l'application Android
le système vérifie le premier enregistrement d'une NdefMessage
pour déterminer le type MIME, ou
URI de la balise, qui permet de créer un intent pour les applications à filtrer. Le code suivant
vous montre comment créer 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")} ); )
Partager des messages NDEF vers d'autres appareils
Android Beam permet d'échanger facilement des données peer-to-peer entre deux appareils Android. La l'application qui souhaite partager des données avec un autre appareil doit être exécutée au premier plan, et l'appareil la réception des données ne doivent pas être verrouillées. Lorsque l'appareil de partage est suffisamment proche du l'appareil récepteur, celui-ci affiche le message UI. L'utilisateur peut alors choisir si le message doit être partagé avec le périphérique destinataire.
Remarque:La transmission NDEF au premier plan était disponible au niveau d'API 10.
qui offre des fonctionnalités semblables à celles d'Android Beam. Ces API sont depuis
abandonnées, mais
sont disponibles pour prendre en charge
les appareils plus anciens. Pour en savoir plus, consultez les enableForegroundNdefPush()
.
Vous pouvez activer Android Beam pour votre application en appelant l'une des deux méthodes suivantes:
setNdefPushMessage()
: accepte unNdefMessage
à définir comme message à partager. Partage automatique du message lorsque deux appareils sont suffisamment proches.setNdefPushMessageCallback()
: Accepte un rappel contenant unecreateNdefMessage()
qui est appelée lorsqu'un appareil est à portée pour le partage de données. Le rappel vous permet de créer le message NDEF que si nécessaire.
Une activité ne peut envoyer qu'un seul message NDEF à la fois. setNdefPushMessageCallback()
est donc prioritaire.
supérieure à setNdefPushMessage()
si les deux sont définis. Pour utiliser
Android Beam, les consignes générales suivantes doivent être respectées:
- L'activité qui transmet les données doit se trouver au premier plan. Les deux appareils doivent avoir leurs écrans déverrouillés.
- Vous devez encapsuler les données que vous partagez dans un
NdefMessage
. . - Le périphérique NFC qui reçoit les données transmises doit être compatible avec la
Protocole push NDEF de
com.android.npp
ou protocole SNEP (Simple NDEF Exchange) du forum NFC Protocole). Le protocolecom.android.npp
est requis pour les appareils avec le niveau d'API 9 (Android). 2.3) au niveau d'API 13 (Android 3.2).com.android.npp
et SNEP sont tous deux obligatoires sur Niveau d'API 14 (Android 4.0) ou version ultérieure.
Remarque:Si votre activité active Android Beam et qu'elle est au premier plan, le système standard de distribution des intents est désactivé. Cependant, si votre activité active de premier plan, il peut toujours analyser les balises qui correspondent aux filtres d'intent définis dans le la répartition au premier plan.
Pour activer Android Beam:
- Créer un
NdefMessage
contenant lesNdefRecord
que vous souhaitez transmettre à l'autre appareil. - Appelez
setNdefPushMessage()
avec unNdefMessage
ou appelezsetNdefPushMessageCallback
en transmettant un objetNfcAdapter.CreateNdefMessageCallback
dans la méthodeonCreate()
de votre activité. Ces méthodes nécessitent au moins une activité que vous souhaitez activer avec Android Beam, avec une liste facultative d'autres activités à activer.En général, vous utilisez normalement
setNdefPushMessage()
si votre activité n'a besoin que transmettre le même message NDEF à tout moment, lorsque deux appareils sont à portée pour communiquer. Vous utilisezsetNdefPushMessageCallback
lorsque votre L'application se soucie du contexte actuel et souhaite transmettre un message NDEF en fonction de ce que l'utilisateur fait dans votre application.
L'exemple suivant montre comment une activité simple appelle NfcAdapter.CreateNdefMessageCallback
dans la méthode onCreate()
d'une
(voir AndroidBeamDemo)
pour l'échantillon complet). Cet exemple propose également des méthodes pour vous aider à créer un enregistrement 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())); } }
Notez que ce code commente un fichier AAR, que vous pouvez supprimer. Si vous activez l'AAR, l'application spécifiée dans l'AAR reçoit toujours le message Android Beam. Si l'application n'est pas présent, Google Play commence à télécharger l'application. Par conséquent, l'intent suivant n'est techniquement pas nécessaire pour les appareils Android 4.0 ou version ultérieure si l'AAR est utilisé:
<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>
Avec ce filtre d'intent, l'application com.example.android.beam
peut maintenant être lancée
lorsqu'il scanne un tag NFC ou reçoit un Android Beam avec un AAR de
Type com.example.android.beam
, ou lorsqu'un message au format NDEF contient un enregistrement MIME
de type application/vnd.com.example.android.beam
.
Même si les AAR garantissent qu'une application est lancée ou téléchargée, les filtres d'intent sont car ils vous permettent de démarrer l'activité de votre choix application au lieu de toujours démarrer l'activité principale dans le package spécifié par un AAR. Les AAR n'ont pas de précision au niveau de l'activité. De plus, certains appareils Android prendre en charge les AAR, vous devez également intégrer des informations d'identification dans le premier enregistrement NDEF de votre et les filtrer également, au cas où. Voir la section Création de rapports Types d'enregistrements NDEF pour en savoir plus sur la création d'enregistrements