- Kotlin 57.9%
- JavaScript 24.7%
- CSS 7.3%
- HTML 5%
- Python 2.6%
- Other 2.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
APK bauen & Release / build-and-release (push) Successful in 1m53s
Ergebnis des ausfuehrlichen Geschwindigkeits- und Sicherheits-Reviews (versionCode 12 / 2.2.1). Keine kritischen oder hohen Sicherheitsfunde; die Performance-Funde wurden behoben: Performance: - Routenlinie: Screen-Path-Cache in LkwMapView. OSRM liefert bis zu 20.000 Punkte, die vorher in JEDEM Pan-/Pinch-Frame neu projiziert und ein neuer Path allokiert wurden (5-15 ms CPU + GC-Druck pro Frame). Jetzt wird der Path nur bei Zoom-/Groessen-/Routenwechsel neu gebaut, dezimiert Punkte < 1,5 px und beim Pan reicht eine reine canvas.translate()-Verschiebung. - HTTP-Keep-Alive: httpGet und Kachel-Loader rufen disconnect() nur noch im Fehlerfall auf. Bei Erfolg bleibt die Verbindung im Keep- Alive-Pool der VM - jeder der bis zu 9 Requests pro Routenberechnung und jeder Kachel-Download spart den TCP+TLS-Handshake (~150-400 ms). - Autocomplete: alle Parser-/Normalisierungs-Regexes einmalig kompiliert (vorher > 100 Regex-Kompilierungen pro Tastendruck auf dem UI-Thread); normalisierte Graph-Knoten-Schluessel einmalig vorberechnet statt pro KeyEvent je Knoten. Sicherheit/Datenschutz: - Nominatim-Throttle: get()/set()-Race durch compareAndSet-Schleifen ersetzt (Geocoding und Autocomplete laufen auf parallelen Threads). - Routen-IDs als SHA-256-Hash statt Klartext-GPS-Koordinaten in persistenten SharedPreferences-Keys (mastered_*). Hinweis: fuer zuvor gemeisterte FREIE Routen (nicht Presets) beginnt dadurch die Meisterschafts-Verfolgung neu - XP und Level bleiben unberuehrt. - Datenschutzhinweis in den Einstellungen (Transparenz ueber Online-Suche via OpenStreetMap-Server) plus README-Abschnitt. Bewusst NICHT geaendert (bewertet und verworfen): - Dijkstra (83 Knoten / 117 Kanten, < 1 ms) - unproblematisch - Keystore im privaten Repo und CI-Token-Exposure auf dem eigenen Single-User-Runner - dokumentierte bewusste Entscheidungen versionCode 12 -> 13, versionName 2.2.1 -> 2.3.0 Co-Authored-By: Claude Code <noreply@anthropic.com> |
||
| .forgejo/workflows | ||
| _legacy_webview_frontend/frontend | ||
| android_tools | ||
| res | ||
| src/main/kotlin/de/openstreet/lkwplaner | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| AndroidManifest.xml | ||
| build_apk.bat | ||
| build_apk.py | ||
| LKW-Streckenplaner.apk | ||
| lkw_release.keystore | ||
| README.md | ||
AndroidLKWAPP – LKW-Streckenplaner & Fahrer-Akademie (Native Kotlin)
Dieses Verzeichnis (Desktop/coding/AndroidLKWAPP/) enthält das vollständige, eigenständige Android-Projekt des LKW-Streckenplaners mit Fahrer-Akademie, Level-System und XP-Sammelfortschritt.
📱 Highlights & Features
- Material-3-Dark-UI (Eigenbau, ohne M3-Bibliothek):
- M3-Dark-Surfaces
#1e1f22/#2b2d30/#141517, 16 dp-Radien, Ripple-Feedback, Elevation-Schatten. - M3-Bottom-Navigation mit 5 Tabs:
🗺️ Route(Übersicht, KPIs, Abbiegeliste & Spickzettel),🧭 Tour(Schritt-für-Schritt-Navigator mit Auto-Play & Karten-Autofokus),❓ Quiz,🌫️ Blindflug,🎓 Akademie. - Road-Sign-Design: START/Ziel-Pins in Smaragdgrün
#059669/ Signalrot#dc2626mit 2 px weißer Kontur, Nadelspitze pixelgenau auf Routenanfang/-ende gesnappt, Zielscheiben-Kern; Autobahn-BadgesA 7in Autobahnblau#005aa9, BundesstraßenB 27in Gelb#f59e0bmit schwarzer Kontur; Fährabschnitte als nautische gestrichelte Linie#06b6d4. - Keine überbreiten Textboxen: Ortsnamen und Tankstellen-Details erscheinen nur als Tooltip beim Antippen des Markers.
- M3-Dark-Surfaces
- Fahrer-Akademie mit 6 Leveln & striktem Gating:
- 🔰 Regional-Einsteiger (0 XP) → 🚚 Verteiler-Profi (300) → 🚛 Fernverkehr-Magistralen (800) → ⛰️ Schwerlast & Steigungen (1.500) → 🏔️ Alpentransit-Experte (2.400) → 👑 Maritime Seewege & Fähren (3.500).
- Jede Route wird automatisch klassifiziert (
classifyRouteLevel): Fähre → L6, Alpen/über 800 km → L5, Gebirgsautobahnen/Tunnel/Gefälle → L4, über 350 km/≥2 Autobahnwechsel → L3, über 120 km/Bundesstraßen → L2, sonst L1. - Nur erreichte Level sind sichtbar — höhere Level sind komplett ausgeblendet (kein Teaser, kein Schummel-Dropdown).
- XP-System: Quiz +25 XP je richtiger Antwort, +50 ab 75 %, +50 bei 100 %, +30 für neue Bestleistung; Tour-Abschluss +100/+40; Blindflug +150/+60; +250 Meisterschaftsbonus, wenn Tour + Quiz + Blindflug einer Route gemeistert sind. Level-Aufstieg mit Fanfare und Toast „🎉 LEVEL-AUFSTIEG!", goldenes XP-Banner auf dem Quiz-Ergebnis.
- 100 % Natives Kotlin (kein WebView):
- Eigener nativer Canvas-Kartenrenderer (
LkwMapView.kt) auf Basis der offiziellen OpenStreetMap-Kacheln – keyless, kein API-Schlüssel, kein CartoDB. - OSM-Dark-Karte: dreistufiger lokaler
ColorMatrixColorFilter(Entsättigung → Dim-Tint → Kontrast) über die Standard-OSM-Kacheln — Land in M3-Card-Ton#292c35, Straßen#31353e, Wasser in Nachtblau, Autobahn-Markierungen in Rost. Kein externer Dark-Tile-Provider. - Routenlinie mit Cyan-Kern + blauem Glow-Halo.
- Flüssiges Pan & stufenloser Pinch-to-Zoom (
ScaleGestureDetector).
- Eigener nativer Canvas-Kartenrenderer (
- Universelle Zieleingabe (100 % offline erkannt):
- Live-Autocomplete wie bei Google Maps: Während der Eingabe öffnet sich unter dem Start-/Zielfeld eine Vorschlagsliste zum Antippen — sofortige Offline-Treffer aus dem eingebetteten Europa-Graph (Hamburg, Kopenhagen, Milano …), ergänzt nach kurzer debounce um Nominatim-Suchergebnisse mit Region/Land als Unterzeile (max. 1 Anfrage/s gemäß OSM-Policy). Sind Start und Ziel gefüllt, startet die Auswahl die Routenberechnung direkt.
- Dezimalgrad („53.5511, 9.9937"), Grad/Dezimalminuten, Grad/Minuten/Sekunden („50°44'30"N 7°05'40"E") mit N/S/O/E/W-Himmelsrichtungen.
- Plus Codes / Open Location Code (z. B. „9F2X7W8C+XX") – Decoder gegen Googles offizielle Testvektoren verifiziert.
- UTM („32U 555555 5599441", inverse Snyder-Projektion) und Geohash („u1x0c6f").
- Europaweite Ziele per Nominatim-Geocoding (keyless) oder direkt über den eingebetteten Graph.
- LKW-Routing europaweit inkl. Fährlinien:
- OSRM-Autobahn-Routing online (80 km/h Richtgeschwindigkeit).
- Eingebetteter europäischer Autobahngraph als Offline-Fallback: ~80 Knoten von Skandinavien bis Griechenland (Hamburg, Kolding, Kopenhagen, Malmö, Oslo, London, Paris, Barcelona, Milano, Roma, Messina, Patras …), Bundesautobahnen, Europastraßen und Dijkstra-Kürzeste-Route.
- Fährlinien für Inselziele: Rømø–Sylt, Vogelfluglinie (Puttgarden–Rødby), Rostock/Travemünde–Trelleborg, Kiel–Göteborg/Oslo, Frederikshavn–Göteborg, Hirtshals–Kristiansand, Ystad–Świnoujście, Calais–Dover, Rotterdam–Hull, Holyhead–Dublin, Messina, Livorno–Olbia/Bastia (Sardinien/Korsika), Ancona–Patras, Brindisi–Igoumenitsa – mit fester Überfahrtsdauer, Teal-Fähren-Badge in der Etappen-Tour und eigener Quiz-Frage (Art.-9-Fährruhezeitklausel).
- EU-VO 561/2006: automatische 45-Min-Pausen nach jeweils 4,5 h Lenkzeit.
- Fähr-Konsistenz: Liegen die Fährhäfen einer Graph-Fährtreppe nicht auf der tatsächlich gelieferten Route (z. B. landgebundene OSRM-Alternative), wird die Fährtreppe aus KPI, Etappen und Quiz herausgefiltert — Diesel, Maut und Fahrzeit beschreiben dann immer die wirklich gefahrene Tour.
- Deutsche LKW-Maut 0,244 €/km (40-Tonner) nur für den deutschen Streckenanteil (Point-in-Polygon über Grenzpolygon); Fährstrecken sind mautfrei.
- Diesel 30,5 L/100 km ausschließlich Straßen-km – auf Fähren wird kein Diesel kalkuliert.
- Live MTS-K Dieselpreise (100 % keyless, keine Registrierung):
- Korridor-Abtastung bei Start / 25 % / 50 % / 75 % / Ziel.
- Primärquelle: echte MTS-K-Echtzeitpreise über die keyless InfraNode-API (Quelle: Tankerkönig/MTS-K, CC BY 4.0) – je Streckenknoten die günstigsten Tankstellen inkl. Marke, Adresse, Live-Preis und Koordinaten für die Karten-Marker.
- Fallback: bundesweiter Echtzeit-Durchschnittspreis von benzinpreis-aktuell.de (Update alle 5 Minuten) – nur wenn die Route Deutschland berührt.
- Reine Auslandstouren: klar gekennzeichnete europäische Durchschnittsschätzung (keine keylose EU-Live-Quelle verfügbar).
- Zuletzt Offline-Schätzung, wenn gar keine Verbindung besteht.
- Inkl. Ersparnis-Berechnung und grünem Empfehlungsbanner für die günstigste Tankstelle der Tour.
- Tour-Navigator: Schritt-für-Schritt-Etappen mit Auto-Play (3 s pro Etappe) und Kamera-Autofokus auf den jeweiligen Etappenknoten; Warn-Notizen (Steigung/Gefälle/Retarder) in Amber.
- Interaktives Strecken-Quiz zu Lenkzeitpausen, Maut/Dieselkosten, Autobahnnummern, Tempolimit und Gefällestrecken der aktuellen Tour — plus Level-Fachfragen je nach klassifiziertem Routen-Level (60 km/h Landstraße, 4,5-h-Lenkzeitpause, Tunnelsicherheit/Retarder, Blockabfertigung Kufstein, Art.-9-Fährruhezeit).
- Blindflug-Modus: Karte wird abgeschaltet, Radar-Sweep mit pulsierenden Ringen und Etappen-Ticker (Autobahn, Abschnitt, km, Minuten) für mentales Streckentraining — mit XP nach jedem vollständigen Durchlauf.
- Einstellungen (⚙ oben rechts): Relay-Server-Abschnitt als Platzhalter für eine spätere Funktion — URL und Auto-Connect-Option werden bereits dauerhaft gespeichert (SharedPreferences
lkw_settings), die eigentliche Verbindung folgt in einer künftigen Version.
📂 Projektstruktur
AndroidLKWAPP/
├── AndroidManifest.xml # Manifest (Rechte, Activity, Version 2.3.0)
├── LKW-Streckenplaner.apk # Fertig kompilierte & signierte APK (~0,8 MB)
├── lkw_release.keystore # Release-Signaturschlüssel
├── build_apk.py # Standalone-Build-Skript (aapt2, kotlinc, D8, Signierung)
├── build_apk.bat # 1-Klick-Build für Windows
├── android_tools/ # Compiler-Toolchain (kotlinc, D8, aapt2, uber-apk-signer)
├── res/ # Android-Ressourcen (Strings, Launcher-Icons)
└── src/
└── main/
└── kotlin/
└── de/openstreet/lkwplaner/
├── MainActivity.kt # M3-Dark-UI, 5-Tab-Bottom-Nav, Akademie-/Quiz-Flow
├── LkwMapView.kt # Nativer Canvas-Kartenrenderer, Präzisions-Pins,
│ # Tooltips, gestrichelte Fähr-Linie, Blindflug-Radar
├── LkwRoutingEngine.kt # OSRM-Routing, Offline-Autobahngraph (Dijkstra),
│ # MTS-K Dieselpreise, Maut & Pausen, Quiz-Generator
├── DriverAcademy.kt # 6-Level-Akademie, XP-System, Routen-Klassifizierung
└── Models.kt # Typsichere Kotlin-Datenmodelle
Der Offline-Fallback (Autobahngraph) ist direkt in LkwRoutingEngine.kt eingebettet – die App benötigt keine externen Datenbankdateien.
🛠 APK neu bauen
Doppelklick auf build_apk.bat oder im Terminal:
python build_apk.py
Das Skript kompiliert die Ressourcen mit aapt2, übersetzt den Kotlin-Code mit kotlinc, erzeugt Dalvik-Bytecode mit Google D8 und signiert die APK mit uber-apk-signer (v1, v2 und v3).
🤖 Forgejo CI (automatischer Release-Build)
.forgejo/workflows/build-apk.yml baut nach jedem Push — nativ auf dem Windows-Host-Runner (act_runner.exe, Label windows-latest:host) — die signierte APK und veröffentlicht sie als Release-Anhang:
- Branch-Push → Rolling-Release unter dem Tag
latest(alte APK wird ersetzt). - Tag-Push
v*→ Release unter genau diesem Tag.
Das Build-Skript nutzt auf dem Windows-Host android_tools/aapt2.exe und den fest eingebauten Adoptium-JDK-Pfad. Pillow/pyaxmlparser sind optional. Voraussetzung: android_tools/ (kotlinc-Distribution inkl. bin/kotlinc.bat, r8.jar, android.jar, uber-apk-signer.jar) und lkw_release.keystore liegen im Repository; auf dem Host müssen python, git und curl.exe im PATH liegen.
📲 Installation auf Android-Smartphone / Tablet
LKW-Streckenplaner.apkauf das Smartphone kopieren (USB, Mail, Drive o. Ä.).- APK antippen und installieren („Unbekannte Quellen" einmalig erlauben).
- Fertig – die App läuft vollständig nativ ohne WebView.
🗺 Datenquellen
- Kartenkacheln: © OpenStreetMap-Mitwirkende (tile.openstreetmap.org, ODbL).
- Routing: OSRM (router.project-osrm.org).
- Geocoding: Nominatim (nominatim.openstreetmap.org).
- Dieselpreise: MTS-K-Echtzeitdaten, keyless via InfraNode (infranode.dev, Quelle Tankerkönig, CC BY 4.0); Fallback bundesweiter Ø via benzinpreis-aktuell.de.
🔒 Datenschutz
Die App arbeitet ohne Konto, ohne Tracker, ohne Werbung. Suchbegriffe und Ziele werden bei der Online-Suche an OpenStreetMap-Server (Nominatim/OSRM) übertragen, der Kartenabruf geht an tile.openstreetmap.org. Alle Fortschritte (XP, Level, Meisterschaften, Einstellungen) bleiben ausschließlich lokal auf dem Gerät (SharedPreferences, allowBackup=false); Routen werden zur Meisterschafts-Verfolgung nur als Hash-ID gespeichert, nicht als Klartext-Koordinaten. Ein Transparenz-Hinweis steht auch in den App-Einstellungen (⚙).