De kaart van Google, mijn flitsers, één app

Ik wilde één ding op het autoscherm. De kaart van Google, het verkeer van Google en de turn-by-turn van Google, met mijn eigen flitsergegevens erbovenop, en een melding alleen voor flitsers die echt op mijn kant van de weg gericht staan.

Ik kon op Android Auto niets vinden dat dat deed. Google Maps heeft de kaart en de routes, maar je kunt er op geen enkele manier je eigen flitserdatabase in laden. Dus bouw ik het zelf.

Het heet AutoNavAlerts. Het is een navigatie-app voor Android Auto, gebouwd op de Navigation SDK van Google, met daarbovenop een meldsysteem voor flitsers en andere interessante punten. De eerste bron voor flitsers is PocketGPSWorld, met mijn eigen betaalde abonnement. De code is openbaar onder de Apache License 2.01 op github.com/damo2929/AutoNavAlerts.

Dit is deel één van een serie. Het gaat over wat de app doet, wat Google een app van derden op een autoscherm wel en niet laat doen, en hoe hij gebouwd is, want bijna elke regel ervan is geschreven door Claude, het AI-model van Anthropic, terwijl ik de regels stelde, testte en eigenaar ben van het resultaat. Dat laatste is een verhaal op zich.

Het is versie 0.1.0. Hij is gesideloaded, staat niet in de Play Store en heeft één echte rit gehad. Lees het als een bouwlogboek, niet als een productlancering.

Wat het vandaag doet

Dit zit er in de testbuild, en hier is waar elk onderdeel voor is:

OnderdeelWat het doet
NavigatieKaart van Google met verkeer, plaatsen zoeken, routevoorbeeld met de aankomsttijd, turn-by-turn op het autoscherm, de zijbalk en het bestuurdersdisplay
Naar een contact rijdenZeg of typ een naam en de opgeslagen adressen van het contact verschijnen boven de resultaten van Places. Alleen het adres dat je kiest gaat naar Google
Samen met je muziekAlleen navigatiesjablonen, zodat de muziek haar kaart houdt in gesplitst scherm. Gesproken meldingen zetten de muziek zachter, nooit op pauze
FlitsermeldingenDrie fasen per flitser, alleen voor flitsers die naar je rijrichting kijken, op de weg waar je rijdt
TrajectcontrolesEen traject begint alleen als er een volgende flitser met dezelfde limiet voor je ligt, en eindigt bij de laatste flitser
SnelheidspaneelJe snelheid en de limiet van de weg, altijd naast elkaar, rechtsonder
Snelheidslimieten offlineEén download van OpenStreetMap-limieten voor het VK: 1.326.619 wegen in 29 MB op de telefoon. Tijdens het rijden wordt niets opgezocht
Routes voor elektrische auto’sDe snelste route en de energiezuinige route van Google naast elkaar, en jij kiest
FlitsergegevensJe eigen PocketGPSWorld-abonnement, dagelijks gecontroleerd, nooit gewisseld terwijl je navigeert. Of importeer iGO-, KML-, GPX-, OV2- of CSV-bestanden
Een flitser meldenEén tik in de auto bewaart positie, richting en limiet, met optioneel gesproken commentaar. Nakijken en versturen gebeurt op de telefoon, nooit tijdens het rijden

De flitsermeldingen zijn de reden dat de app bestaat, dus die krijgen het volgende hoofdstuk.

Een flitser telt alleen als hij naar jou kijkt

Een flitsermelding die afgaat voor de andere rijbaan is erger dan geen melding. Ze leert je het ding te negeren. Dus de eerste harde regel in het ontwerp is dat een flitser alleen meldt als hij naar je rijrichting kijkt, en die regel wordt nooit versoepeld, nooit met een standaardwaarde omzeild en nooit losgelaten als de gegevens lastig zijn.

Hoe een positiebepaling een flitsermelding wordtInvoerVier controles, elke positieUitvoersnelheid en GPS van de autoals de auto ze deeltGPS van de telefoon10 posities per secondeje eigen flitsersetsop de telefoon1. dichtbij genoeg2. voor je3. kijkt jouw kant op4. op jouw wegbanner op deautokaartgesproken melding,muziek zachterflitser gemarkeerdop de kaartéén controle mislukt: geen melding; afgewend wordt gedimd getekend met pijl
Hoe een positiebepaling een melding wordt. Tot tien posities per seconde gaan door vier controles; alleen een flitser die alle vier doorstaat wordt uitgesproken en als melding gegeven.

De engine draait bij elke positiebepaling, tot tien per seconde. Voor elke flitser in de buurt stelt hij vier vragen, op volgorde:

ControleGeslaagd alsWaarom die er is
Dichtbij genoegbinnen de meldafstand plus 200 m, met een maximum van 3 kmgeen werk aan flitsers die kilometers ver weg staan
Voor jekoers naar de flitser binnen 45° van je rijrichtingeen flitser achter je is geschiedenis
Kijkt jouw kant opde richting van de flitser binnen 45° van je rijrichting, of van de koers naar de flitser in een bochtde andere rijbaan blijft stil
Op jouw wegbinnen 50 m van de route voor je, of een corridor van 40 m die met de afstand breder wordt bij vrij rijdende parallelle weg blijft stil

Die 45° is niet ruim. De TomTom-bestanden van PocketGPSWorld geven de richting van een flitser in acht windrichtingen, dus 22,5° ervan gaat al op aan de gegevens voordat er iets anders gebeurt. Een GPS-koers kost nog een paar graden, en de kromming van de weg nog een paar. Daarom mag niets anders er iets van afsnoepen.

Een flitser die de richtingcontrole niet haalt, wordt nog steeds op de kaart getekend, gedimd, met een pijl die laat zien welke kant hij op kijkt. Je kunt hem zien. Hij praat alleen niet tegen je.

Drie meldfasen bij 70 mphStandaard voorsprong: 15 seconden bij je snelheid, hier 70 mphjij, 70 mphflitserkijkt naar jouandere rijbaan, afgewend: gedimd, stil1e melding469 m vooraf, 15 s2e melding235 m vooraf, 7,5 spasseren100 yd (91 m)niet op schaal; ondergrenzen van 242 m en 142 m houden de eerste twee uit elkaar bij lage snelheid
De drie fasen bij 70 mph met de standaard voorsprong van 15 seconden. De eerste twee worden getimed op je snelheid; de passeermelding ligt vast op 100 yards en kan niet uit zolang het geluid aan staat.

De fasen zijn getimed, geen vaste afstanden. De eerste melding komt 15 seconden van tevoren bij je huidige snelheid en de tweede op de helft daarvan, allebei met een ondergrens zodat ze de derde nooit verdringen. De derde ligt vast op 100 yards, en die is verplicht zolang het geluid aan staat. De meldafstand kan tijdens een nadering alleen groeien, dus hard remmen maakt de waarschuwing waar je al recht op had niet korter.

Wat Google een app op het autoscherm laat doen

Hier wordt het interessant, want een app van derden op Android Auto is geen Google Maps. Hij draait binnen de regels van de Car App Library van Android Auto, die apps “a set of visual templates approved for driver safety”2 geeft, en binnen wat de Navigation SDK besluit open te stellen.

Drie gaten hebben de app meer gevormd dan alles wat ik zelf koos te bouwen:

WatGoogle Maps in de autoEen app op de Navigation SDK
Een ongeluk, politie of wegwerkzaamheden meldeningebouwdniet aangeboden. De eigen documentatie van Google: “real-time disruptions are not available on Android Auto”3
De snelheidslimiet van de weggetoondalleen het percentage dat je erboven zit, en alleen zolang je te hard rijdt4
Aanraken van de eigen kaartknoppen van de SDKn.v.t.niets. Android Auto “limits screen surface interaction to a series of SurfaceCallback methods”2

Neem de snelheidslimiet. Google weet hem. Google vertelt een app hoeveel je erboven zit, als percentage en een ernst, en helemaal niets zolang je eronder zit. Mag ik vragen waarom een bestuurder de limiet pas mag weten als hij hem al overtreedt? Daar ga ik geen antwoord op krijgen, dus de app werkt eromheen. Zolang je te hard rijdt, rekent hij de limiet terug uit je snelheid en het percentage. Daaronder gebruikt hij de flitser die je nadert, daarna de OpenStreetMap-download, en hij toont een streepje in plaats van niets als hij helemaal geen limiet heeft.

Incidenten melden heeft dezelfde vorm. De meld-API’s bestaan in de navigatieweergave op de telefoon en niet in die van de auto. Iemand heeft Google er al om gevraagd5, en dat verzoek staat nog open. De app controleert tijdens het draaien of de API’s er zijn, dus als een latere SDK ze toevoegt, verschijnt de meldknop van Google zonder enige wijziging in mijn code. Een GitHub Actions-job controleert het elk kwartaal en opent een issue op de dag dat het gebeurt.

De aanraakregel had me goed te pakken. De autokaart van de SDK tekent zijn eigen aankomstkaart, kop, centreerknop, snelheidsmeter en ritbalk. Geen ervan reageert op een tik, want geen aanraking bereikt de weergave van de SDK. Ze zien eruit als knoppen en doen helemaal niks. Dus staan ze allemaal uit, en de app tekent zijn eigen knoppen op de plek waar een tik echt aankomt.

Breng je eigen sleutel mee, breng je eigen gegevens mee

Twee beslissingen houden deze app eerlijk over geld en licenties, en allebei zijn ze bewust.

Er zit geen ingebouwde Maps-sleutel in. Google Maps Platform vereist “a billing-enabled Cloud project”6, en de Navigation SDK een project waarin hij is ingeschakeld7. Als ik een sleutel meeleverde, zou ieders rijden op mijn rekening komen, of de sleutel zou uitlekken en alsnog op mijn rekening komen. Dus brengt elke gebruiker zijn eigen sleutel mee, in zijn eigen Google Cloud-account. De telefoonapp kan er een aanmaken met je eigen Google-account, of je plakt er een in. Hij wordt versleuteld op de telefoon bewaard. Er is geen enkele terugvaloptie, en de app doet geen enkele SDK-aanroep voordat jouw sleutel erin zit.

Er zitten geen flitsergegevens in de app. PocketGPSWorld geeft zijn database in licentie voor individueel gebruik, voorziet elke download van een watermerk voor het lid, en verbiedt hem ergens neer te zetten waar iemand anders dan de koper erbij kan. Dus de app levert hem nooit mee, host hem nooit en synchroniseert hem nooit tussen telefoons. Je logt in met je eigen abonnement, en de telefoon downloadt je eigen kopie met watermerk naar privéopslag die buiten de back-ups valt. Op de testopstelling waren dat 19.826 flitsers in 33 sets, één set per bestand, nooit samengevoegd.

De automatische synchronisatie is daar beleefd in. Hij leest één keer per dag de openbare RSS-feed van PocketGPSWorld8 en logt alleen in als er een nieuwe uitgave is. Hij wisselt de flitsers nooit terwijl je navigeert.

Eén clausule in hun licentie is hiermee niet helemaal geregeld, die over het opnemen van de gegevens in een applicatie. Voor mijn eigen gebruik accepteer ik dat. Voordat de app naar iemand anders gaat, krijgt PocketGPSWorld een e-mail met de vraag.

Twee dagen, 87 commits, en eerst een ontwerpdocument

Nu het deel waar mensen over gaan discussiëren. Ik heb deze code niet getypt. Claude wel, via Claude Code, met twee modellen, Claude Fable en Claude Opus. Ik schreef de eisen, nam elke beslissing, draaide de testopstelling, reed de auto en beoordeelde wat terugkwam. Elke commit met door AI geschreven wijzigingen erin draagt een trailer die dat zegt, en de README ook.

Dit zijn de cijfers, afgelezen uit de repository:

MetingWaarde
Commits87, van 22:10 op 11 oktober tot 12:44 op 13 oktober 2026
Commits met een Claude co-author-regel83 (56 Fable, 27 Opus)
Kotlin in de app en zijn kernbibliotheek15.334 regels
Unittests211, in 3.464 regels
DESIGN.md, de specificatie1.763 regels, geschreven voordat er code was

Het ontwerpdocument kwam eerst, en dat is het nuttigste dat ik iemand kan vertellen die dit doet. De openingsregel zegt dat er geen code wordt geschreven voordat het is goedgekeurd, en dat elke latere wijziging daar eerst wordt gemaakt. Elke klasse heeft een taak die ernaast staat opgeschreven. Elke drempel heeft een reden. Elke regel die ik stelde, staat als de mijne gemarkeerd, met de datum.

Dat doet ertoe omdat een model vergeet. Een lange sessie wordt samengevat, en de samenvatting houdt de grote lijn en laat de details vallen, en in de details zitten de bugs. De eigen AGENTS.md van de repository zegt het ronduit: vertrouw niet op een samenvatting van deze bestanden uit je geheugen of uit een eerdere sessie. De agent gaat terug naar het document. Elke keer.

In de tweede fase werkten ook twee agents tegelijk, de een aan begeleiding, de kaart en schermen, de ander aan locatie, meldingen, spraak en kaartmarkeringen. Elk had een opgeschreven lijst bestanden, en de interfaces ertussen lagen vooraf vast: toevoegen, niet hernoemen. Ze voegden schoon samen omdat de grens besloten was voordat een van beide begon, niet achteraf ontdekt.

Elke harde regel kwam van iets wat ik zag

Het ontwerp heeft een lijst harde regels, en niet één ervan kwam van een whiteboard. Elke regel kwam van kijken hoe het ding draaide op de Desktop Head Unit9, de emulator van Google voor het autoscherm op de pc, of in de auto, en zien dat het iets verkeerd deed.

Harde regelWat ik zag waardoor het een regel werd
Een flitser meldt alleen als hij jouw kant op kijktmeldingen voor de andere rijbaan zijn ruis die je leert meldingen te negeren
Niets op het autoscherm dat niet werkttwee stopknoppen op het scherm, waarvan één dood
Geen functie twee keer getoonddatzelfde paar, plus twee centreerknoppen, twee snelheidsweergaven
Eén annuleerknop, die van Googlede kaart in de hoek met de X is van Android Auto zelf, getekend uit de rit die de app publiceert, dus de eigen stopknop van de app verdween
Geen getril op het autoschermhet scherm Meer trilde terwijl de auto geparkeerd stond, omdat het elke seconde een identiek scherm opnieuw stuurde en Android Auto elke verversing animeert
Elke knop aan de rechterkantde kaartknoppen stonden linksboven tot het autoscherm zijn afmetingen doorgaf; nu vanaf het begin één kolom langs de rechterrand, niets van ons links
Geen ingebouwde Maps-sleutel, nooitniemands rijden komt op de rekening van een ander

Het getril is mijn favoriet, omdat het zo klein is en het mee zou zijn gegaan. Een live GPS-regel tikte één keer per seconde. Elke tik stuurde het hele scherm opnieuw, ongewijzigd, en de host animeerde het, zodat elke regel eronder wiebelde terwijl de auto stilstond. De oplossing is één vergelijking: alleen opnieuw tekenen als een regel veranderd is. De regel is groter dan de oplossing. Een scherm dat stilstaat moet er stil uitzien, en dat wordt gecontroleerd met een reeks schermafbeeldingen die identiek moeten zijn.

Dat is het echte werk als een AI de code schrijft. Hij wordt niet moe en hij vindt herschrijven niet erg, maar hij kan het autoscherm niet zien. Jij wel. Wat je zag opschrijven als een regel, met de datum, is wat voorkomt dat het drie sessies later terugkomt.

Wat de code fout deed, en hoe het werd gevonden

Genoeg. Niets ervan was exotisch, en elk ervan werd gevonden door het te draaien, niet door het te lezen:

FoutWat het deedHoe het werd gevonden
Route aan het verkeerde deel gekoppeldDe route van Google vanaf een geparkeerde auto ging naar het noorden, keerde op een rotonde en kwam over dezelfde weg terug naar het zuiden. De matcher zette de auto vast op het noordelijke deel 10 m verderop, dus elke flitser richting zuiden lag meer dan een kilometer “naast de weg”. Er kwam geen enkele meldingeen gescripte rit op de testopstelling; het meldlogboek gaf offRoad lateral=1204 voor elke flitser
Spraakwaakhond te kortdie gaf 1,5 s plus 70 ms per teken. Getallen uitspreken duurt langer dan dat, dus elke melding in de tweede fase werd midden in de zin afgekaptde spraakregistraties van een testrun
Een snelheidsbegrenzing in de engineeen venster van drie seconden betekende dat van twee flitsers op één kruising er één voorgoed verdweenhet nalopen van de meldingen die stil bleven tijdens de eerste echte rit
Een verouderde koersde emulator meldt een koers van 0°, wat je ook doet, dus op een weg naar het zuiden haalde elke flitser de richtingcontrole nieteen gesimuleerde rit over de A61
Limietwijzigingen uitgesproken als flitsermeldingeneen limietwijziging verderop werd in de wachtrij gezet als flitsermelding in de eerste fasehet spraaklogboek op de testopstelling

De tweede is het waard om even bij stil te staan. Elke afzonderlijke test slaagde. De code was correct naar zijn eigen maatstaf. Hij had alleen een time-out, gekozen door iemand die nog nooit een telefoon een afstand hardop had horen voorlezen. De test die dat vangt is een echte stem, getimed, op een echte rit.

De eerste echte rit

Op 12 oktober zette ik een releasebuild op mijn telefoon en nam hem mee in de XPENG G6 via draadloos Android Auto. Twee dingen gingen mis. Een route die ik geparkeerd had ingesteld, wiste zichzelf binnen een paar seconden nadat ik wegreed. En sommige meldingen werden uitgesproken en andere niet, zonder patroon dat ik kon zien.

Toen het ergere probleem. Er viel niets na te lezen. ColorOS op mijn telefoon gooit de logregels van de app weg, dus de rit liet helemaal geen bewijs achter. Was het de app, de SDK van Google of Android Auto zelf? Ik kon het niet zeggen.

Dus de oplossing voor de eerste rit was geen codewijziging. Het was bewijs. De app schrijft nu de hele tijd twee logboeken op de telefoon, een voor routes en de kaart en een voor elke meldbeslissing, in batches van 15 seconden, plus een optionele ritrecorder die elke positie bewaart zodat een rit op de testopstelling opnieuw kan worden afgespeeld. Daarna werden de gissingen gerepareerd, elk zo geschreven dat hij minder doet en logt dat hij het deed. Elke manier waarop de begeleiding kan eindigen, legt nu vast wie haar beëindigde.

Op de testopstelling heeft Android Auto sindsdien één keer stop aangeroepen, 2 minuten 35 seconden in een begeleide rit. Ik zat op dat moment door de head unit te klikken, dus het was waarschijnlijk de X op zijn eigen kaart. Het is niet gebeurd zonder dat iemand het scherm aanraakte. De volgende rit beslist het, want deze keer laat de rit een spoor achter.

Wat er hierna komt

De lijst voor de testopstelling is nog lang. De volgende ritten controleren de annuleerknop, de scenario’s met een bocht en met de verkeerde richting, de overdracht tussen de GPS van de auto en die van de telefoon, en of het bestuurdersdisplay in de G6 überhaupt afslagkaarten van een app van derden toont.

Latere delen van deze serie gaan behoorlijk in op de wiskunde van de meldengine, de omwegen voor de snelheidslimiet, de formaten van PocketGPSWorld, en de testopstelling zelf: hoe je een Android Auto-app test zonder auto, met een gescripte GPS en een emulator die denkt dat elke weg naar het noorden loopt.

De machine typt, de standaard is van jou

Ik heb veel gepraat over AI die code schrijft voorbij zien komen, het meeste van mensen die het verkopen of mensen die er bang voor zijn. Wat ik vond is saaier dan allebei, en nuttiger.

Hij typt snel en hij verveelt zich niet. Hij herschrijft een scherm voor de vierde keer zonder te zuchten. Wat hij niet doet, is merken dat het scherm Meer trilt, of dat een zin werd afgekapt, of dat er een dode knop naast een levende zit. Hij kan de auto niet zien. Dat was aan mij om te zien, en de enige reden dat het gerepareerd is, is dat ik elk ervan heb opgeschreven als een regel die hij moet lezen voordat hij iets aanraakt.

Als zodanig verschuift de verantwoordelijkheid niet. De code is van mij omdat ik de standaard stel waaraan hij wordt gehouden en omdat ik degene in de auto ben. Niets van wat het eerlijk hield is een AI-methode. Eerst de specificatie schrijven en dan de code, opschrijven wat je leert, en bewijs bewaren in plaats van gissen: zo is degelijke techniek altijd gedaan. Het gereedschap verandert dat niet. Het maakt het alleen sneller om te zien wie het oversloeg.


  1. Apache License, Version 2.0 — de licentie waaronder de code van AutoNavAlerts is gepubliceerd. ↩︎

  2. Google — Navigation SDK for Android: Android Auto — de Car App Library biedt “a set of visual templates approved for driver safety”, en “Android Auto limits screen surface interaction to a series of SurfaceCallback methods”. ↩︎ ↩︎

  3. Google — Navigation SDK for Android: real-time disruptions — “real-time disruptions are not available on Android Auto”. ↩︎

  4. Google — Navigation SDK for Android: speed alerts — onSpeedingUpdated(float percentageAboveLimit, SpeedAlertSeverity speedAlertSeverity): het percentage boven de limiet en een ernst, niet de limiet zelf. ↩︎

  5. googlemaps/flutter-navigation-sdk issue #726 — “Incident reporting on Android Auto & CarPlay”, geopend op 17 juni 2026, staat nog open. ↩︎

  6. Google Maps Platform — Get started — “you must create a billing-enabled Cloud project and enable the desired APIs or SDKs”. ↩︎

  7. Google — Navigation SDK for Android: set up your project — “A Google Cloud console project with the Navigation SDK enabled.” ↩︎

  8. PocketGPSWorld — de Britse flitserdatabase waaruit de app synchroniseert, met het eigen abonnement van elke gebruiker. ↩︎

  9. Android Developers — Test using the Desktop Head Unit — de emulator van Google voor het autoscherm van Android Auto. ↩︎