Aller au contenu
Langue : FR

Comment détecter qu'un tag a quitté le champ ?

Sur Android, l'échange suivant lève TagLostException, et depuis l'API de niveau 24 NfcAdapter.ignore() appelle un auditeur une fois que le tag est resté absent pendant un délai choisi. Sur iOS, isAvailable passe à faux et la commande suivante échoue. Aucune des deux ne signale l'instant lui-même, et un tag qui revient compte pour un nouveau.

Sur Android

Le déroulement ordinaire n'a aucun événement de retrait. La plateforme vérifie qu'un tag découvert est toujours présent, et le mode lecteur laisse une application fixer la cadence par EXTRA_READER_PRESENCE_CHECK_DELAY, que la référence de NfcAdapter décrit comme le délai que la plateforme emploie pour ses contrôles de présence. Ce que l'application voit, c'est son appel d'entrée-sortie suivant qui échoue avec TagLostException, une sous-classe d'IOException.

isConnected() ne répond pas à la question. La référence de TagTechnology dit qu'elle rend vrai quand connect() a abouti, que close() n'a pas été appelée et que le tag n'est pas connu comme hors de portée, sans aucune activité radio : elle rapporte ce que la plateforme sait déjà, pas une vérification fraîche.

Pour un tag qui reste en place, celui d'un support de voiture par exemple, l'outil est NfcAdapter.ignore(), depuis l'API de niveau 24. Elle arrête la communication avec le tag tant qu'il reste à portée et appelle un OnTagRemovedListener une fois que le tag est hors de portée depuis debounceMs ; un tag qui revient plus tôt n'est pas redistribué. La référence ajoute trois limites : le contrôleur interroge toutes les 100 à 500 ms, si bien qu'un tag qui entre et sort peut être redistribué alors qu'il n'est jamais vraiment parti ; un autre tag annule l'appel ; et un tag à identifiant aléatoire la met en échec.

Sur iOS

Tout tag que Core NFC délivre hérite de NFCNDEFTag, dont isAvailable passe à faux quand le tag est retiré du champ ou déconnecté, selon la référence d'isAvailable. Aucun appel de délégué ne le signale : une application qui a besoin de le savoir lit la propriété, ou l'apprend d'une commande qui échoue avec readerTransceiveErrorTagConnectionLost.

Une connexion peut aussi finir pendant que le tag reste. Un tag reste connecté jusqu'à ce que l'application se connecte à un autre ou relance l'interrogation, selon la référence de connect, et la note d'Apple sur restartPolling() dit que les tags détectés avant une relance ne sont plus valides.

Une session NDEF attend d'elle-même. Avec un délégué qui reçoit des messages, la session relance l'interrogation une fois les tags détectés hors de portée, comme l'explique la page des tags multiples, si bien qu'un tag maintenu en place n'est pas lu deux fois de suite.

Pourquoi c'est toujours en retard

Le retrait se déduit d'un silence. Un téléphone apprend qu'un tag est parti quand un contrôle de présence ou une commande reste sans réponse, et la référence de NfcAdapter situe l'intervalle d'interrogation du contrôleur entre 100 et 500 ms. L'application entend parler du retrait après que la main a bougé, jamais à l'instant où elle bouge.

Concevez l'interface autour de ce décalage. Une écriture annoncée comme faite avant le retour de son appel est une supposition : montrez l'achèvement quand l'appel revient, et traitez une exception comme une issue inconnue, comme l'explique la page des écritures interrompues.

Les doubles lectures partent de là

Un tag qui part et revient est une nouvelle découverte. Sur Android il arrive comme un nouvel objet Tag, la référence de Tag en créant un à chaque fois que le tag revient à portée ; sur iOS la session le détecte à nouveau une fois qu'il est parti. La page du double déclenchement décrit comment une main produit cela sans le vouloir.

Une application qui doit agir une fois par contact décide donc de ce qui compte pour une répétition. Comparer l'identifiant au dernier lu, dans une fenêtre de temps que l'application choisit, attrape le cas courant, et ignore() fait la même chose sur Android pour un tag laissé en place. Ni l'un ni l'autre ne marche avec des identifiants aléatoires, où c'est au côté qui reçoit de tolérer les répétitions, la conclusion à laquelle la page du double déclenchement arrive pour les serveurs.

Questions fréquentes

isConnected() me dit-elle que le tag est toujours là ?

Non. Elle rapporte si connect a abouti et si close n'a pas été appelée, sans toucher à la radio. C'est l'appel d'entrée-sortie suivant qui vous le dit.

Existe-t-il un événement de départ sur Android ?

Seulement par NfcAdapter.ignore(), depuis l'API de niveau 24, dont l'auditeur se déclenche une fois le tag hors de portée pendant le délai que vous fixez.

Et sur iOS ?

Aucun appel de délégué ne le signale. La propriété isAvailable du tag passe à faux, et la commande suivante échoue sur une erreur de connexion perdue.

Pourquoi mon application lit-elle deux fois le même tag ?

Le tag a quitté le champ et est revenu, ce qui compte pour une nouvelle découverte. Comparez les identifiants dans une fenêtre de temps, ou employez ignore() sur Android pour un tag qui reste en place.