La carte de Google, mes radars, une seule appli
Je voulais une seule chose sur l’écran de la voiture. La carte de Google, le trafic de Google et le guidage pas à pas de Google, avec mes propres données de radars par-dessus, qui ne m’alertent que pour les radars réellement braqués sur mon côté de la route.
Je n’ai rien trouvé sur Android Auto qui fasse ça. Google Maps a la carte et le guidage, mais impossible d’y charger votre propre base de radars. Alors je la construis.
Elle s’appelle AutoNavAlerts. C’est une appli de navigation Android Auto construite sur le Navigation SDK de Google, avec un système d’alertes radars et points d’intérêt écrit par-dessus. La première source de radars est PocketGPSWorld, avec mon propre abonnement payant. Le code est public sous Apache License 2.01 sur github.com/damo2929/AutoNavAlerts.
C’est la première partie d’une série. Elle couvre ce que fait l’appli, ce que Google permet ou non à une appli tierce sur un écran de voiture, et comment elle a été construite, parce que presque chaque ligne a été écrite par Claude, le modèle d’IA d’Anthropic, pendant que je fixais les règles, testais et assumais le résultat. Cette dernière partie est une histoire à elle seule.
C’est la version 0.1.0. Elle est installée à la main, pas sur le Play Store, et elle a fait un seul vrai trajet. Lisez ça comme un journal de construction, pas comme un lancement de produit.
Ce qu’elle fait aujourd’hui
Voici ce qu’il y a dans la version de test, et à quoi sert chaque partie :
| Domaine | Ce que ça fait |
|---|---|
| Navigation | Carte Google avec le trafic, recherche de lieux, aperçu de l’itinéraire avec l’heure d’arrivée, guidage pas à pas sur l’écran de la voiture, le bandeau latéral et l’écran conducteur |
| Aller chez un contact | Dites ou tapez un nom et les adresses enregistrées du contact apparaissent au-dessus des résultats Places. Seule l’adresse choisie part chez Google |
| Cohabite avec votre musique | Uniquement des modèles de navigation, donc la musique garde sa carte en écran partagé. La voix des alertes baisse la musique, elle ne la met jamais en pause |
| Alertes radars | Trois étapes par radar, seulement pour les radars tournés vers votre sens de circulation, sur la route où vous êtes |
| Zones de vitesse moyenne | Une zone ne démarre que si un autre radar avec la même limite est devant vous, et se termine au dernier radar |
| Panneau de vitesse | Votre vitesse et la limite de la route, toujours côte à côte, en bas à droite |
| Limites hors ligne | Un seul téléchargement des limites OpenStreetMap pour le Royaume-Uni : 1 326 619 routes en 29 Mo sur le téléphone. Rien n’est consulté en roulant |
| Itinéraires pour voiture électrique | L’itinéraire le plus rapide et l’itinéraire économe en énergie de Google côte à côte, et c’est vous qui choisissez |
| Données radars | Votre propre abonnement PocketGPSWorld, vérifié chaque jour, jamais remplacé pendant que vous naviguez. Ou importez des fichiers iGO, KML, GPX, OV2 ou CSV |
| Signaler un radar | Un appui dans la voiture enregistre la position, le cap et la limite, avec un commentaire vocal facultatif. La relecture et l’envoi se font sur le téléphone, jamais en roulant |
Les alertes radars sont la raison d’être de l’appli, alors elles ont droit à la section suivante.
Un radar ne compte que s’il vous fait face
Une alerte radar qui se déclenche pour l’autre chaussée est pire que pas d’alerte du tout. Elle vous apprend à ignorer la chose. Alors la première règle stricte de la conception, c’est qu’un radar n’alerte que s’il fait face à votre sens de circulation, et cette règle n’est jamais assouplie, jamais contournée par défaut et jamais abandonnée quand les données sont pénibles.
Le moteur tourne à chaque position, jusqu’à dix par seconde. Pour chaque radar proche, il pose quatre questions, dans l’ordre :
| Contrôle | Réussi quand | Pourquoi il est là |
|---|---|---|
| Assez près | dans la distance de déclenchement plus 200 m, plafonnée à 3 km | aucun travail perdu sur des radars à des kilomètres |
| Devant vous | relèvement vers le radar à moins de 45° de votre cap | un radar derrière vous, c’est du passé |
| Tourné vers vous | l’orientation du radar à moins de 45° de votre cap, ou du relèvement vers le radar dans un virage | l’autre chaussée reste muette |
| Sur votre route | à moins de 50 m de l’itinéraire devant, ou un couloir de 40 m qui s’élargit avec la distance en conduite libre | la route parallèle reste muette |
Les 45° ne sont pas généreux. Les fichiers TomTom de PocketGPSWorld donnent l’orientation d’un radar en huit points cardinaux, donc 22,5° partent dans les données avant tout le reste. Un cap GPS coûte encore quelques degrés, et la courbe de la route encore quelques-uns. C’est pour ça que rien d’autre n’a le droit d’empiéter dessus.
Un radar qui échoue au contrôle d’orientation est quand même dessiné sur la carte, atténué, avec une flèche qui montre dans quel sens il regarde. Vous le voyez. Il ne vous parle simplement pas.
Les étapes sont calculées en temps, pas en distances fixes. La première alerte tombe à 15 secondes à votre vitesse actuelle et la deuxième à la moitié, toutes deux avec un plancher pour qu’elles n’empiètent jamais sur la troisième. La troisième est fixée à 100 yards, et elle est obligatoire dès que le son est activé. La distance de déclenchement ne fait que grandir pendant une approche, donc freiner fort ne raccourcit pas l’avertissement qu’on vous devait déjà.
Ce que Google permet à une appli sur l’écran de la voiture
C’est là que ça devient intéressant, parce qu’une appli tierce sur Android Auto n’est pas Google Maps. Elle tourne dans les règles fixées par la Car App Library d’Android Auto, qui donne aux applis « a set of visual templates approved for driver safety »2, et dans ce que le Navigation SDK choisit d’exposer.
Trois manques ont façonné l’appli plus que tout ce que j’ai choisi de construire :
| Quoi | Google Maps dans la voiture | Une appli sur le Navigation SDK |
|---|---|---|
| Signaler un accident, la police ou des travaux | intégré | non proposé. La documentation de Google elle-même : « real-time disruptions are not available on Android Auto »3 |
| La limitation de vitesse de la route | affichée | seulement le pourcentage de dépassement, et seulement pendant que vous dépassez4 |
| Le toucher sur les commandes de carte du SDK | sans objet | aucun. Android Auto « limits screen surface interaction to a series of SurfaceCallback methods »2 |
Prenez la limitation de vitesse. Google la connaît. Google dira à une appli de combien vous la dépassez, en pourcentage et en niveau de gravité, et rien du tout tant que vous êtes en dessous. Puis-je demander pourquoi un conducteur n’a le droit de connaître la limite qu’une fois qu’il est déjà en train de l’enfreindre ? Je n’aurai pas de réponse, alors l’appli contourne le problème. Quand vous dépassez, elle recalcule la limite à partir de votre vitesse et du pourcentage. En dessous, elle utilise le radar dont vous approchez, puis le téléchargement OpenStreetMap, et elle affiche un tiret plutôt que rien quand elle n’a aucune limite.
Le signalement d’incidents a la même forme. Les API de signalement existent sur la vue de navigation du téléphone et pas sur celle de la voiture. Quelqu’un l’a déjà demandé à Google5, et la demande est toujours ouverte. L’appli vérifie la présence de ces API à l’exécution, donc si un futur SDK les ajoute, le bouton de signalement de Google apparaît sans aucun changement dans mon code. Une tâche GitHub Actions vérifie chaque trimestre et ouvre un ticket le jour où ça arrive.
La règle du toucher m’a bien eu. La carte du SDK dans la voiture dessine sa propre carte d’arrivée, son en-tête, son bouton de recentrage, son compteur de vitesse et sa barre de trajet. Aucun ne peut recevoir un appui, parce qu’aucun toucher n’atteint la vue du SDK. Ils ressemblent à des boutons et ne font rien du tout. Alors ils sont tous désactivés, et l’appli dessine ses propres commandes là où un appui arrive vraiment.
Apportez votre clé, apportez vos données
Deux décisions gardent cette appli honnête sur l’argent et les licences, et les deux sont délibérées.
Il n’y a pas de clé Maps intégrée. Google Maps Platform exige « a billing-enabled Cloud project »6, et le Navigation SDK exige un projet où il est activé7. Si je livrais une clé, la conduite de tout le monde me serait facturée, ou la clé fuiterait et me serait facturée quand même. Alors chaque utilisateur apporte sa propre clé, dans son propre compte Google Cloud. L’appli du téléphone peut en créer une avec votre propre compte Google, ou vous en collez une. Elle est stockée chiffrée sur le téléphone. Il n’y a aucune solution de repli, et l’appli ne fera pas un seul appel au SDK tant que votre clé n’est pas là.
Il n’y a pas de données radars dans l’appli. PocketGPSWorld accorde sa base sous licence pour un usage individuel, marque chaque téléchargement au nom du membre, et interdit de la placer où que ce soit d’accessible à quelqu’un d’autre que l’acheteur. Alors l’appli ne la livre jamais, ne l’héberge jamais et ne la synchronise jamais entre téléphones. Vous vous connectez avec votre propre abonnement, et le téléphone télécharge votre propre copie marquée dans un stockage privé exclu des sauvegardes. Sur le banc, ça faisait 19 826 radars en 33 jeux, un jeu par fichier, jamais fusionnés.
La synchronisation automatique reste polie. Elle lit le flux RSS public de PocketGPSWorld une fois par jour8 et ne se connecte que quand il y a une nouvelle version. Elle ne remplace jamais les radars pendant que vous naviguez.
Une clause de leur licence n’est pas complètement réglée par tout ça, celle sur l’intégration des données dans une application. Pour mon propre usage, je l’accepte. Avant que l’appli aille à qui que ce soit d’autre, PocketGPSWorld recevra un e-mail pour poser la question.
Deux jours, 87 commits, et un document de conception d’abord
Maintenant la partie dont les gens vont débattre. Je n’ai pas tapé ce code. Claude l’a fait, via Claude Code, avec deux modèles, Claude Fable et Claude Opus. J’ai écrit les exigences, pris chaque décision, fait tourner le banc, conduit la voiture et relu ce qui revenait. Chaque commit qui contient des changements écrits par l’IA porte une mention qui le dit, et le README aussi.
Voici les chiffres, relevés sur le dépôt :
| Mesure | Valeur |
|---|---|
| Commits | 87, de 22:10 le 11 octobre à 12:44 le 13 octobre 2026 |
| Commits avec une ligne de co-auteur Claude | 83 (56 Fable, 27 Opus) |
| Kotlin dans l’appli et sa bibliothèque principale | 15 334 lignes |
| Tests unitaires | 211, en 3 464 lignes |
DESIGN.md, la spécification | 1 763 lignes, écrites avant tout code |
Le document de conception est venu en premier, et c’est la chose la plus utile que je puisse dire à quiconque fait la même chose. Sa première ligne dit qu’aucun code n’est écrit tant qu’il n’est pas approuvé, et que tout changement ultérieur s’y fait d’abord. Chaque classe a une tâche écrite en face d’elle. Chaque seuil a une raison. Chaque règle que j’ai fixée est marquée comme la mienne, avec la date.
Ça compte parce qu’un modèle oublie. Une longue session est résumée, et le résumé garde l’essentiel et perd le détail, et c’est dans le détail que sont les bugs. Le propre AGENTS.md du dépôt le dit clairement : ne vous fiez pas à un résumé de ces fichiers, de mémoire ou d’une session précédente. L’agent retourne au document. À chaque fois.
Deux agents ont aussi travaillé en parallèle sur la deuxième phase, l’un sur le guidage, la carte et les écrans, l’autre sur la localisation, les alertes, la voix et les marqueurs de carte. Chacun possédait une liste écrite de fichiers, et les interfaces entre eux étaient fixées d’avance : on ajoute, on ne renomme pas. Ils ont fusionné proprement parce que la frontière avait été décidée avant que l’un ou l’autre commence, pas découverte après coup.
Chaque règle stricte vient de quelque chose que j’ai vu
La conception a une liste de règles strictes, et pas une n’est sortie d’un tableau blanc. Chacune vient de l’avoir vu tourner sur la Desktop Head Unit9, l’émulateur d’écran de voiture de Google sur le PC, ou dans la voiture, et de l’avoir vu faire quelque chose de travers.
| Règle stricte | Ce que j’ai vu et qui en a fait une règle |
|---|---|
| Un radar n’alerte que s’il est tourné vers vous | les alertes pour l’autre chaussée sont du bruit qui apprend à ignorer les alertes |
| Rien sur l’écran de la voiture qui ne marche pas | deux boutons stop à l’écran, dont un mort |
| Aucune fonction affichée deux fois | cette même paire, plus deux boutons de recentrage, deux affichages de vitesse |
| Une seule annulation, celle de Google | la carte dans le coin avec le X est celle d’Android Auto, dessinée à partir du trajet que l’appli publie, alors le bouton stop de l’appli a disparu |
| Pas de tremblement sur l’écran de la voiture | l’écran Plus qui tressautait voiture garée, parce qu’il renvoyait un écran identique chaque seconde et qu’Android Auto anime chaque rafraîchissement |
| Tous les boutons sur le côté droit | les boutons de carte restaient en haut à gauche jusqu’à ce que l’écran de la voiture donne sa taille ; maintenant une colonne le long du bord droit dès le départ, rien à nous sur la gauche |
| Pas de clé Maps intégrée, jamais | la conduite de personne n’est facturée à quelqu’un d’autre |
Le tremblement est mon préféré, parce qu’il est tout petit et qu’il aurait été livré. Une ligne GPS en direct se mettait à jour une fois par seconde. Chaque mise à jour renvoyait l’écran entier, inchangé, et l’hôte l’animait, donc chaque ligne en dessous gigotait pendant que la voiture ne bougeait pas. La correction tient en une comparaison : ne redessiner que si une ligne a changé. La règle est plus grande que la correction. Un écran immobile doit avoir l’air immobile, et c’est vérifié par une rafale de captures d’écran qui doivent être identiques.
C’est ça, le vrai travail quand une IA écrit le code. Elle ne se fatigue pas et ça ne la gêne pas de réécrire, mais elle ne voit pas l’écran de la voiture. Vous, si. Noter ce que vous avez vu comme une règle, avec la date, c’est ce qui l’empêche de revenir trois sessions plus tard.
Ce que le code a raté, et comment ça a été attrapé
Beaucoup de choses. Rien d’exotique, et chaque défaut a été attrapé en faisant tourner le code, pas en le lisant :
| Défaut | Ce qu’il faisait | Comment il a été attrapé |
|---|---|---|
| Itinéraire rattaché au mauvais tronçon | l’itinéraire de Google depuis une voiture garée partait vers le nord, faisait demi-tour à un rond-point et revenait vers le sud sur la même route. Le rattachement collait la voiture au tronçon nord à 10 m, donc chaque radar en direction du sud était « hors route » de plus d’un kilomètre. Rien n’alertait | un trajet scripté sur le banc ; le journal des alertes disait offRoad lateral=1204 pour chaque radar |
| Chien de garde de la voix trop court | il accordait 1,5 s plus 70 ms par caractère. Les nombres prennent plus de temps à dire, donc chaque alerte de deuxième étape était coupée au milieu de la phrase | les enregistrements vocaux d’un passage sur le banc |
| Une limite de fréquence dans le moteur | une fenêtre de trois secondes faisait que deux radars au même carrefour en perdaient un pour de bon | en remontant les alertes restées muettes lors du premier vrai trajet |
| Un cap périmé | l’émulateur donne un relèvement de 0° quoi que vous fassiez, donc sur une route vers le sud chaque radar échouait au contrôle d’orientation | un passage simulé sur l’A61 vers le sud |
| Changements de limite annoncés comme des alertes radars | un changement de limite à venir était mis en file comme une alerte radar de première étape | le journal de la voix sur le banc |
Le deuxième mérite qu’on s’y arrête. Chaque test pris isolément passait. Le code était correct selon ses propres critères. Il avait juste un délai choisi par quelqu’un qui n’avait jamais entendu un téléphone lire une distance à voix haute. Le test qui attrape ça, c’est une vraie voix, chronométrée, sur un vrai passage.
Le premier vrai trajet
Le 12 octobre, j’ai mis une version de production sur mon téléphone et je l’ai sortie dans la XPENG G6 en Android Auto sans fil. Deux choses ont mal tourné. Un itinéraire défini à l’arrêt s’est effacé quelques secondes après le départ. Et certaines alertes étaient annoncées et d’autres non, sans aucune logique que je puisse voir.
Puis le problème plus grave. Il ne restait rien à lire. ColorOS, sur mon téléphone, jette les lignes de journal de l’appli, donc le trajet n’a laissé aucune trace. Était-ce l’appli, le SDK de Google ou Android Auto lui-même ? Impossible à dire.
Donc la correction pour le premier trajet n’a pas été un changement de code. Ça a été des preuves. L’appli écrit maintenant en permanence deux journaux sur le téléphone, un pour le guidage et la carte et un pour chaque décision d’alerte, par lots de 15 secondes, plus un enregistreur de trajet facultatif qui garde chaque position pour qu’un trajet puisse être rejoué sur le banc. Ensuite les suppositions ont été corrigées, chacune réécrite pour en faire moins et noter qu’elle l’a fait. Chaque façon dont le guidage peut se terminer enregistre maintenant qui l’a terminé.
Sur le banc depuis, Android Auto a appelé l’arrêt une fois, 2 minutes 35 secondes après le début d’un trajet guidé. Je cliquais partout sur la head unit à ce moment-là, donc c’était très probablement le X sur sa propre carte. Ça ne s’est pas reproduit quand personne ne touchait l’écran. Le prochain trajet tranchera, parce que cette fois le trajet laisse une trace.
La suite
La liste du banc est encore longue. Les prochains trajets vérifient le bouton d’annulation, les scénarios de virage et de mauvais sens, le passage de relais entre le GPS de la voiture et celui du téléphone, et si l’écran conducteur de la G6 affiche seulement les cartes de direction d’une appli tierce.
Les parties suivantes de cette série entrent vraiment dans les maths du moteur d’alertes, les contournements pour la limitation de vitesse, les formats PocketGPSWorld, et le banc lui-même : comment tester une appli Android Auto sans voiture, avec un GPS scripté et un émulateur qui croit que toutes les routes vont vers le nord.
La machine tape, la norme est la vôtre
J’ai vu passer beaucoup de discours sur l’IA qui écrit du code, la plupart venant de gens qui la vendent ou de gens qu’elle effraie. Ce que j’ai trouvé est plus terne que les deux, et plus utile.
Elle tape vite et elle ne s’ennuie pas. Elle réécrira un écran pour la quatrième fois sans un soupir. Ce qu’elle ne fera pas, c’est remarquer que l’écran Plus tremble, qu’une phrase a été coupée, ou qu’un bouton mort est posé à côté d’un bouton qui marche. Elle ne voit pas la voiture. C’était à moi de voir tout ça, et la seule raison pour laquelle c’est corrigé, c’est que j’ai noté chaque chose comme une règle qu’elle doit lire avant de toucher à quoi que ce soit.
Du coup, la responsabilité ne bouge pas. Le code est à moi parce que c’est moi qui fixe la norme qu’il doit tenir et c’est moi qui suis dans la voiture. Rien de ce qui l’a gardé honnête n’est une méthode d’IA. Écrire la spécification avant le code, noter ce qu’on apprend, et garder des preuves au lieu de deviner, c’est comme ça que l’ingénierie sérieuse s’est toujours faite. L’outil ne change rien à ça. Il permet juste de découvrir plus vite qui s’en dispensait.
Apache License, Version 2.0 — la licence sous laquelle le code d’AutoNavAlerts est publié. ↩︎
Google — Navigation SDK for Android : Android Auto — la Car App Library fournit « a set of visual templates approved for driver safety », et « Android Auto limits screen surface interaction to a series of SurfaceCallback methods ». ↩︎ ↩︎
Google — Navigation SDK for Android : real-time disruptions — « real-time disruptions are not available on Android Auto ». ↩︎
Google — Navigation SDK for Android : speed alerts —
onSpeedingUpdated(float percentageAboveLimit, SpeedAlertSeverity speedAlertSeverity): le pourcentage au-dessus de la limite et un niveau de gravité, pas la limite elle-même. ↩︎googlemaps/flutter-navigation-sdk issue #726 — « Incident reporting on Android Auto & CarPlay », ouvert le 17 juin 2026, toujours ouvert. ↩︎
Google Maps Platform — Get started — « you must create a billing-enabled Cloud project and enable the desired APIs or SDKs ». ↩︎
Google — Navigation SDK for Android : set up your project — « A Google Cloud console project with the Navigation SDK enabled. » ↩︎
PocketGPSWorld — la base de radars britannique depuis laquelle l’appli se synchronise, avec l’abonnement propre à chaque utilisateur. ↩︎
Android Developers — Test using the Desktop Head Unit — l’émulateur de Google pour l’écran de voiture Android Auto. ↩︎