Eigenes Produkt

Contrail

Wie zeigt eine Reise-App Unsicherheit, ohne Reisende mit Rohdaten allein zu lassen?

Contrail zeigt einen dunklen Globus mit der Großkreisroute von London nach Singapur und sichtbarer Tag-Nacht-Grenze.
Dokumentierter Android-Gerätezustand. Route, Sonnenstand und Bordkartenansicht werden gemeinsam gezeigt; kein neu erzeugtes Mockup.

Contrail verbindet Flugdaten, Reisezeit und native Android-Benachrichtigungen. Messung, Schätzung und veralteter Stand bleiben dabei unterscheidbar.

Bereich
Flug- und Reisebegleitung
Zeitraum
2026
Status
In Entwicklung · v1.5
Plattformen
Android
Leistungen
Flutter-App, Native Android-Integration, Backend-Scheduling, Release-Vorbereitung

Ausgangslage

Airline- und ADS-B-Daten beantworten nicht direkt, wann jemand losfahren muss, ob ein Anschluss realistisch ist oder ob eine Position noch gemessen wurde. Gleichzeitig darf Hintergrundbetrieb nicht vom Flutter-Lifecycle abhängen.

Verantwortung

Produktkonzeption, Flutter-Anwendung, Reise- und Frischemodell, Globusdarstellung, native Android-Services, Benachrichtigungen, Backend-Polling und Play-Release-Vorbereitung.

Ergebnis

Eine Android-App im Entwicklungsstand 1.5 mit dokumentierten Gerätezuständen, nativer Live-Benachrichtigung und einem Scheduler für begrenzte Datenabfragen.

Contrail zeigt einen Live-Flug mit eindeutig bezeichneten Ortszeiten für Zakynthos und London.
Echte Prüfaufnahme des Zeitmodells. Flughafenzeiten werden mit Ortskürzel angezeigt; die Statusleiste ist in dieser Aufnahme stellenweise kontrastarm.
Android-Lockscreen-Live-Update für einen Flug mit der Meldung Landung in 26 Minuten.
Native Android-16-Ausgabe. Das kleine Lockscreen-Format ist Teil desselben Reise-Watch-Zustands wie die geöffnete App.

Eine Schätzung darf nie wie eine Beobachtung aussehen

Contrail kennt im aktuellen Code fünf Datenzustände: live, geschätzt, geplant, veraltet und offline. Jeder Zustand trägt Alter, letzten Fehler und Zeitpunkt der letzten erfolgreichen Abfrage. Nur ein tatsächlich frischer Live-Wert darf pulsieren. Nach zwei Minuten wechselt eine Messung aus dem Live-Zustand; das weitere Frischefenster hängt davon ab, wie nah die Reise am Abflug liegt.

Diese Unterscheidung verhindert zwei Arten falscher Sicherheit. Ein weit entfernter Flug muss nicht minütlich abgefragt werden, um gesund zu wirken. Ein Flug kurz vor dem Gate darf dagegen nicht stundenlang denselben Stand zeigen. Die Oberfläche bildet die fachliche Dringlichkeit ab, statt lediglich den Zeitpunkt des letzten Requests auszudrucken.

Fehlt ein neuer ADS-B-Fix, schätzt Contrail nicht blind auf der theoretischen Direktverbindung weiter. Die Engine nimmt zunächst die letzte reale Position und führt sie mit gemessener Geschwindigkeit in Richtung Ziel fort. Nur ohne verwertbare letzte Position wird aus Abflug, Ziel und vergangener Flugzeit interpoliert. Dadurch springt ein Flugzeug beim Signalverlust nicht vom Ende seiner tatsächlichen Spur zurück auf eine ideale Linie.

Auch diese Fortrechnung ist begrenzt. Sie läuft höchstens zwei Stunden in Zielrichtung. Weicht der gemessene Kurs mehr als 90 Grad ab, wird er maximal 20 Minuten fortgeführt und danach eingefroren. Ein Bodenfix bleibt stehen. Geschwindigkeiten über 700 Knoten gelten nicht als plausible Basis. Ein Fix ohne Zeitstempel bleibt an der gemessenen Position. Die Schätzung trägt ihre Basis und einen eingefrorenen Zustand bis in die Darstellung. Selbst rechnerisch null Reststrecke erfindet keine Landung.

Zeit ist ein Ort und ein Zeitpunkt

Eine Reise verbindet Gerätezeit, Abflugort, Zielort und manchmal weitere Flughäfen. Contrail führt Zeit deshalb als UTC-Instant mit IANA-Zeitzone und Ortscode. Dauerberechnungen arbeiten auf UTC; die Ausgabe benennt den Ort. Ein Datumssprung wird gesondert berechnet.

Das wirkt auf den ersten Blick wie Formatierung, verhindert aber konkrete Fehler. Ein früherer Pfad konnte eine Bibliothekszeitzone mit Gerätezeit verwechseln. Die Normalisierung auf einen gewöhnlichen UTC-Zeitpunkt trennt die Berechnung nun von der Darstellung. Vorhandene Tests decken beide Richtungen der Datumsgrenze, Sommerzeitwechsel, nicht ganzzahlige Stundenoffsets sowie fehlende oder falsche Zonen ab.

Das Modell ist bewusst nicht als mathematischer Beweis über alle UI-Texte beschrieben. Es existiert weiterhin eine kurze Formatfunktion, die bei fehlender Zone auf Gerätezeit zurückfallen kann. Der belastbare Anspruch lautet: Reisezeiten werden zentral modelliert und können ihren Ort sichtbar mitführen.

Die Benachrichtigung überlebt die Flutter-Oberfläche

Die sichtbare Live-Benachrichtigung ist kein Abbild eines laufenden Widgets. Die Flutter-Seite berechnet aus Reise, Segmenten und einer expliziten Uhr den aktuellen Fokus: aktives Leg, relevanten Moment, Überschrift, Anschlussbewertung und Tür-bis-Gate-Plan. Beim Wechsel in den Hintergrund übergibt sie einen flachen Datenvertrag an Android. Die eigene Pollschleife in Dart endet dann absichtlich.

Kotlin persistiert die Kennungen der beobachteten Flüge, rekonstruiert sie beim Start des Foreground-Service und kann nach einem vom System ausgelösten Neustart mit leerem Intent weiterarbeiten. Der native Poller verwendet bevorzugt den von Flutter gelieferten Ankunftsanker. Erst wenn dieser nicht mehr brauchbar ist, berechnet er eine einfache Restzeit aus Entfernung und Geschwindigkeit. Dadurch erzählen App und Benachrichtigung nicht gleichzeitig zwei unterschiedlich aufwendige Modelle.

Tests sichern unter anderem genau eine Benachrichtigung pro Reise, das Weiterlaufen beim Entfernen eines einzelnen Segments und das Aufräumen nach dem letzten Segment. Ein zusätzlicher Vertragstest liest die aufgerufenen Flutter-Methoden und vergleicht sie mit den nativen Handlern. Er prüft eine Grenze, die weder Dart- noch Kotlin-Compiler für sich allein sehen.

Die vorhandene Evidence-Sammlung enthält Statuschip, Lockscreen und mehrere Minuten auseinanderliegende Zustände sowie ein Video bei geschlossener App. Das ist stärker als ein nachgebauter Website-Effekt: Es zeigt die native Ausgabe auf einem Android-16-Gerät.

Ein knappes Datenbudget ist ein Scheduling-Problem

Die bei der Implementierung dokumentierte Anbietergrenze entsprach ungefähr 300 Requests pro Schlüssel und Monat. Diese Zahl beschreibt eine damalige Projektkonfiguration, keinen aktuellen Tarif. Die Architekturfrage bleibt dennoch relevant: Eine konstante Pollrate würde das Kontingent auf wenige Flüge konzentrieren und weniger dringliche Reisen unnötig oft abfragen.

Der Scheduler ordnet beobachtete Flüge deshalb Dringlichkeitsklassen zu. Überfällige, ankommende, gelandete, aktive oder bald startende Flüge erhalten unterschiedliche Intervalle. Nutzerpräsenz, Zahl der Beobachter, Störung und Alter der letzten erfolgreichen Abfrage fließen in die Auswahl ein. Ein Backend-Tick begrenzt die Kandidatenmenge, verteilt Requests mit Mindestabstand und protokolliert Entscheidung und tatsächlich versandten Push getrennt.

Die Fehlerbehandlung unterscheidet erschöpftes Kontingent, Rate Limit, fehlenden Datensatz, fehlerhafte Antwort und Timeout. Nur eine tatsächlich erkannte Kontingenterschöpfung wechselt innerhalb desselben Versuchs zu einem weiteren Schlüssel. Ein Timeout würde am Reserveweg wahrscheinlich denselben kostenpflichtigen Nichtbefund erzeugen.

Was diese Arbeit für ähnliche Aufträge zeigt

Contrail belegt drei Leistungsfelder gemeinsam: ein verständliches Produktmodell für unsichere Daten, native Hintergrundausführung jenseits des Cross-Platform-Lifecycles und ein Backend, das technische Grenzen als fachliche Priorisierung behandelt.

Für ein Unternehmensprojekt kann dieselbe Denkweise auf Lieferstatus, Sensordaten, Außendienst oder andere zeitkritische Systeme übertragen werden. Die konkrete Lösung wird nicht kopiert. Entscheidend ist, Messung, Annahme, Alter und Ausfall als unterschiedliche Produktzustände zu modellieren und bis in UI, Service und Betrieb konsistent zu halten.

Technik und wofür sie da ist

Flutter
Oberfläche und Reisemodell
Kotlin
Native Android-Dienste
Android Foreground Service
Überlebt das Prozessende
Android 16 Live Updates
Lockscreen-Status
Cloud Functions
Abfrageplanung im Backend
ADS-B
Positionsdaten
Zeitzonenmodell
Ortszeit an jedem Flughafen