Guide#adb#python#automatisation
Automatiser une application Android avec ADB et Python en 2026
Un guide qui marche pour piloter un vrai téléphone Android depuis Python : activer ADB, injecter des clics assez rapides, trouver les éléments à l'écran, et les trois endroits où un premier bot casse toujours.

Tous ceux qui automatisent Android écrivent la même première version : adb shell input tap 540 1180 dans une boucle, avec un sleep entre chaque ligne. Ça tient à peu près une journée. Puis l'app se met à jour, vos coordonnées pointent sur une publicité, et vous recommencez.
Ce guide est la version d'après. Il couvre ce dont vous avez réellement besoin — un chemin d'entrée rapide, une façon de trouver les éléments plutôt que de deviner où ils sont, et une reprise propre quand une étape échoue — et il dit franchement où chaque approche s'arrête.
Faire voir le téléphone à ADB
Trois conditions doivent être réunies avant tout le reste.
Les options développeur activées. Paramètres → À propos du téléphone → tapez sept fois sur Numéro de build. Le menu apparaît ensuite dans Paramètres → Système.
Le débogage USB activé, dans ce nouveau menu. Sur Xiaomi, Oppo et Vivo, il faut en général aussi Débogage USB (paramètres de sécurité), qui exige d'être connecté au compte du constructeur — une contrainte à connaître avant d'en acheter douze.
L'invite de confiance acceptée sur l'appareil, la première fois que vous le branchez sur un PC donné. Si adb devices affiche unauthorized, c'est que l'invite a été refusée : révoquez les autorisations de débogage USB dans les options développeur et rebranchez.
adb devices -l
# List of devices attached
# R58M617DNAZ device product:beyond1 model:SM_G975F
Une note très pratique : un câble de charge n'est pas un câble de données. Si l'appareil n'apparaît jamais, changez de câble avant de chercher ailleurs.
Les clics, et pourquoi la méthode évidente est trop lente
La méthode documentée est celle-ci :
adb shell input tap 540 1180
Chacun de ces appels lance un processus sur l'appareil, charge une machine virtuelle Java, injecte un événement et sort. Mesuré sur un téléphone milieu de gamme, cela représente 150 à 250 ms de surcoût par clic. Une boucle de vingt interactions passe quatre à cinq secondes à ne rien faire d'autre que démarrer des processus, et la variabilité du timing la rend aussi peu fiable que lente.
Il y a deux sorties. Vous pouvez garder un shell ouvert en permanence et lui envoyer des commandes, ce qui supprime le coût de reconnexion mais pas le démarrage du runtime à chaque commande. Ou vous injectez les événements via un service résident sur l'appareil — c'est par exemple ce que fait scrcpy pour ses entrées. Ce chemin évite le surcoût de démarrage à chaque clic et rend possibles les vrais gestes, parce qu'un geste est un flux d'événements et non un seul.
Rien qu'en gardant une seule connexion ouverte au lieu de relancer adb à chaque appel, on va déjà plusieurs fois plus vite, et c'est suffisant pour démarrer.
Arrêtez d'utiliser des coordonnées
Le vrai problème, ce sont les coordonnées, pas la vitesse. Elles cassent au moindre changement de maquette, sur une autre taille d'écran, à la rotation, selon la position de défilement, et sur un test A/B dont personne ne vous a parlé.
L'échelle des alternatives, de la moins chère à la plus chère :
La hiérarchie de vues. adb shell uiautomator dump écrit un arbre XML de l'écran courant, avec les identifiants de ressources et les positions. Analysez-le, trouvez le nœud dont le resource-id finit par claim_button, cliquez au centre. C'est la meilleure option quand elle existe : exacte, insensible aux changements de maquette, sans entraînement. Elle n'existe pas dans les jeux, dans tout ce qui est dessiné sur un canvas, ni dans les apps qui posent FLAG_SECURE.
La reconnaissance de motif. Capturez l'écran, cherchez-y une image connue avec matchTemplate d'OpenCV, cliquez au centre de la correspondance. Fiable pour les icônes fixes, fragile face au redimensionnement, aux artefacts de compression, aux changements de thème et aux animations.
L'OCR. Quand ce qui identifie la cible, c'est son texte — un libellé, un solde, un compteur — lisez-le. Tesseract ou PaddleOCR sur une région découpée est rapide et ne demande aucun dataset.
Un détecteur entraîné. Quand la cible bouge, s'anime ou change d'apparence d'une version à l'autre, un petit modèle YOLO entraîné sur trente à cinquante de vos propres captures la trouve par son apparence plutôt que par sa position. Cela coûte un dataset et un entraînement, d'où sa place en bas de cette liste plutôt qu'en haut.
Les trois endroits où un premier bot casse
Il suppose que l'écran attendu est l'écran affiché. Chaque action devrait être précédée d'une vérification que l'app est bien là où vous le croyez, et suivie d'une vérification que l'action a produit un effet. wait_for(condition, timeout) est la fonction utilitaire la plus rentable que vous écrirez.
Il n'a pas de réessais. Les réseaux coincent, des boîtes de dialogue apparaissent, les publicités durent quatre secondes. Entourez chaque étape d'un réessai borné avec temporisation, et définissez ce que « abandonner proprement » veut dire — en général, forcer l'arrêt de l'app pour que le cycle suivant reparte d'un état connu.
Il repart de zéro après un plantage. Si votre boucle compte quinze étapes et meurt à la douzième, vous voulez qu'elle reprenne à la douzième. Écrivez l'étape courante sur le disque après chacune, et relisez-la au démarrage. C'est sans gloire, et c'est ce qui sépare un script que l'on surveille d'un script qui tourne la nuit.
Un timing de forme humaine
Si le service que vous automatisez y prête attention, des intervalles parfaitement réguliers sont la première chose qu'il remarque. time.sleep(2) à chaque itération est une signature. random.uniform(1.4, 2.9) n'en est pas une, et ne coûte rien.
Même chose pour les gestes : un swipe implémenté comme une ligne droite à vitesse constante ne ressemble en rien à un pouce. Ajoutez une légère courbe et une décélération. Rien de tout cela ne rend l'automatisation indétectable — rien ne le fait, et quiconque promet le contraire vous vend quelque chose — mais cela supprime les indices triviaux.
Quand arrêter de construire le sien
Tout ce qui précède, c'est un week-end. Le week-end suivant, c'est un pool de threads pour faire tourner cinq téléphones, la gestion des numéros de série, un planificateur, un format de log lisible à 4 h du matin, et un plan pour l'appareil qui a silencieusement quitté le bus.
C'est le moment où il devient légitime de se demander si l'outil est le projet ou le détour. AppsMobs livre les briques de cet article déjà assemblées — le chemin d'entrée rapide, la reconnaissance d'image et de texte, un détecteur entraînable, le planificateur et la relance automatique d'un script qui plante — pour que la partie que vous écrivez soit l'automatisation elle-même. Les fonctions sont injectées dans vos scripts, sans aucun import : voir les scripts Python et la liste des fonctions.
Dans un cas comme dans l'autre, la forme du problème est la même, et elle mérite d'être comprise avant de choisir un outil.

