Une application Android peut-elle réagir à un tag sans afficher d'écran ?
Presque. La distribution d'un tag lance toujours une activité, jamais un service, et le plus discret que la plateforme offre est une activité sans interface qui se termine avant d'être reprise. Le téléphone doit en outre être déverrouillé, et le son de détection reste joué.
Un tag lance toujours une activité
La référence de Tag ne décrit qu'une destination pour un tag découvert : une activité unique, lancée par startActivity. Ni service, ni récepteur, ni tâche planifiée n'apparaissent sur ce chemin.
Le mode lecteur et le dispatch au premier plan n'y changent rien. Tous deux exigent une activité au premier plan : ils servent une application déjà ouverte, pas une application qui réagit depuis l'arrière plan.
Une activité qui n'affiche rien
Android fournit un thème pour ce cas. La référence de R.style décrit Theme.NoDisplay comme le thème des activités qui n'affichent pas d'interface, parce qu'elles se terminent elles mêmes avant d'être reprises.
Ce minutage est la contrainte. Le travail doit tenir avant le moment où l'activité serait reprise, ce qui exclut un long échange avec le tag et convient à un contenu arrivé avec l'Intent.
Et le contenu arrive en général avec lui. Le guide des bases du NFC rend l'extra EXTRA_NDEF_MESSAGES obligatoire sur ACTION_NDEF_DISCOVERED : les messages analysés sont donc là sans nouvelle lecture.
Tout ce qui dure plus longtemps appartient à un composant fait pour le travail de fond : l'activité lit le message, passe la main, et se termine.
Ce qui limite encore
Le téléphone doit regarder. Le guide des bases du NFC indique que les appareils Android cherchent les tags en général pendant que l'écran est déverrouillé : un téléphone verrouillé dans une poche ne réagit à rien, si discrète que soit l'activité.
L'utilisateur entend le tag même quand rien ne s'affiche. La plateforme joue son son de détection, et le drapeau qui le coupe appartient au mode lecteur, lequel demande une activité visible.
L'application doit être éligible. Depuis Android 17, la documentation indique que les Intents NFC ne sont plus distribués à une application dans l'état arrêté, jamais lancée par l'utilisateur ou arrêtée de force, et depuis Android 16 l'utilisateur peut refuser les Intents de tag application par application.
Les liens web sont un cas à part. Depuis Android 16, un tag qui porte un lien http ou https part vers ACTION_VIEW, et depuis Android 17 il attend une action de l'utilisateur sur une notification : une réaction silencieuse à un lien web n'est donc pas proposée du tout.
Quand un écran visible vaut mieux
Un tap est une question, et le silence une réponse ambiguë. L'utilisateur ne distingue pas une action qui s'est exécutée d'un tag qui n'a pas été lu, et le tap suivant, destiné à réessayer, exécute l'action une seconde fois.
Confirmez donc, même brièvement, par une notification ou un message court. Une réaction entièrement silencieuse convient aux actions dont l'effet se voit ailleurs, une lampe qui s'allume par exemple.
Quand l'action vit déjà dans une application de routines, cette application s'en charge pour vous, comme le décrit la page des routines Android.
Questions fréquentes
Un service peut-il lire des tags en arrière plan ?
Aucun chemin documenté ne le permet. La distribution lance une activité, et le mode lecteur comme le dispatch au premier plan en exigent une au premier plan.
Cela fonctionne-t-il écran éteint ?
En général non. La documentation indique que les appareils cherchent les tags pendant que l'écran est déverrouillé, et les constructeurs peuvent différer : cela se teste modèle par modèle.
L'application recevra-t-elle des tags si l'utilisateur ne l'a jamais ouverte ?
Plus depuis Android 17. La documentation indique que les Intents NFC ne sont pas distribués à une application dans l'état arrêté, ce qui inclut celle que l'utilisateur n'a jamais lancée.
Le son de détection peut-il être coupé ?
Seulement en mode lecteur, avec FLAG_READER_NO_PLATFORM_SOUNDS, et le mode lecteur demande une activité visible. Une activité silencieuse l'est à l'écran, pas à l'oreille.