• v2.1.1 b2aa1c167c

    marcel released this 2026-05-15 14:32:48 +02:00 | 7 commits to main since this release

    GPS2Audio v2.1.1 – PTT-Aufnahmen anhören & sinnvoll zuweisen

    Build: 2.1.1 · versionCode: 38
    Basis: stabile Code-Basis aus GPS2Audio_v2_1_0_ptt_recorder_source.zip
    Build-Host: Linux, JDK 21, Android SDK 35, Gradle 8.9 (AGP 8.5.2)


    1. Ursache der gemeldeten Probleme

    In v2.1.0 war der PTT-Recorder zwar funktional (Aufnahme, Speicherung,
    Bibliothek, Datenmodell), aber die UI hatte zwei Lücken, die ihn aus
    Nutzersicht teilweise nutzlos machten:

    1. Keine Anhörmöglichkeit in der Bibliothek
      Der Dialog PttRecordingsLibraryDialog zeigte zwar Aufnahmen mit
      Metadaten an (Datum, Dauer, optional GPS), bot aber pro Eintrag nur
      die Buttons „Als Waypoint-Audio zuweisen" und „Löschen". Es gab
      keinerlei Möglichkeit, eine Aufnahme im Dialog vorzuhören. (Screenshot
      1000014484.jpg.)

    2. „Wegpunkt auswählen" war in leeren Touren eine Sackgasse
      WaypointChooserDialog listete ausschließlich die Wegpunkte der
      aktuell ausgewählten Tour. War diese Tour leer – z.B. „Standard"
      direkt nach App-Installation – zeigte der Dialog lediglich den Text
      „Keine Wegpunkte in dieser Tour." an, ohne Möglichkeit, eine andere
      Tour zu wählen oder einen Wegpunkt aus der Aufnahme zu erzeugen.
      (Screenshots 1000014485.jpg, 1000014486.jpg.)


    2. Umsetzung (UI + Logik)

    2.1 Vorhörfunktion in der PTT-Bibliothek

    • Neuer Button „Anhören" / „Pause" pro Aufnahme im Dialog.
    • Ein dedizierter, lokaler Preview-Player (MediaPlayer-basiert)
      innerhalb des Dialogs, der bewusst nicht beim
      WaypointAudioInterruptionCoordinator registriert wird. Dadurch
      bleibt der bestehende Audiopfad (Atmo-Service, manueller
      Wegpunkt-Player, PTT-Interruption) vollständig unverändert.
    • Genau eine Vorschau gleichzeitig: beim Wechsel auf eine andere
      Aufnahme wird die vorherige automatisch gestoppt und freigegeben.
    • Cleanup garantiert über:
      • DisposableEffect(Unit) { onDispose { previewPlayer.release() } }
      • explizites Stoppen bei: Schließen-Icon, onDismissRequest,
        Klick auf „Zuweisen" (vor Wechsel in WaypointChooserDialog),
        Klick auf „Löschen" (falls gerade gespielt), natürlichem
        Wiedergabe-Ende.
    • Wiedergabe nutzt die file://-URI der Aufnahme (wie bisher von
      PttRecorder erzeugt). Kein neuer Permission-Bedarf.

    2.2 Wegpunkt-Auswahl/-Erstellung im Chooser

    • Tour-Dropdown im Dialogkopf: Nutzer kann während der Zuweisung
      zu einer anderen Tour wechseln. Initialwert = aktuell aktive Tour.
    • Liste zeigt Wegpunkte der gewählten Tour mit dem bestehenden
      Pfad: Klick auf einen Wegpunkt setzt soundUri und soundName der
      Aufnahme über viewModel.upsert(...). Erfolgsmeldung auf Deutsch via
      viewModel.postInfo(...) → bestehender Info-Snackbar-Mechanismus.
    • Neuer Wegpunkt aus Aufnahme (Button):
      • Sichtbar auch in leeren Touren (prominent) und zusätzlich
        in nicht-leeren Touren
        (sekundär, OutlinedButton).
      • Erzeugt einen neuen Waypoint mit:
        • name = displayName der Aufnahme (Fallback „PTT-Aufnahme"),
        • soundUri/soundName aus der Aufnahme,
        • radiusMeters = 50f, isActive = true,
        • tourName = Dropdown-Auswahl (ggf. Waypoint.DEFAULT_TOUR_NAME).
      • Position mit Prioritätskette:
        1. Aktuelle GPS-Position (viewModel.currentLocation, falls
          gesetzt – nutzt die bestehende fetchCurrentLocation-Logik).
        2. GPS-Metadaten aus der Aufnahme (recording.latitude/longitude,
          die PttRecorder.stop() beim Speichern bereits anlegt).
        3. Sicherer Default 0.0 / 0.0 (entspricht dem Default des
          Waypoint-Datenmodells – Nutzer kann den Wegpunkt anschließend
          jederzeit per Karten-Editor oder Bearbeiten-Dialog korrigieren).
      • Persistiert via viewModel.upsert(...); das bestehende
        WaypointRepository legt den Wegpunkt an. Tour-Auswahl wird auf
        die Zieltour gewechselt, damit der neu erzeugte Wegpunkt in der
        Liste sichtbar wird.
    • Feedback auf Deutsch: Neue String-Ressourcen
      ptt_waypoint_chooser_created und
      ptt_waypoint_chooser_empty_hint; bestehende
      ptt_waypoint_chooser_assigned bleibt für reine Zuweisungen.

    2.3 ViewModel-Erweiterung (minimal)

    Zwei kleine öffentliche Setter in WaypointViewModel:

    • fun postInfo(message: String) setzt _infoMessage (für Erfolgs-Banner).
    • fun postError(message: String) setzt _errorMessage (für Fehler-Banner).

    Beide nutzen die existierenden, bereits in der UI gehosteten
    StateFlows (infoMessage/errorMessage) und führen keine eigenen
    Side-Effects ein.


    3. Geänderte Dateien

    Datei Änderung
    app/build.gradle.kts versionCode 37 → 38, versionName 2.1.0 → 2.1.1
    app/src/main/res/values/strings.xml Neue Strings: ptt_waypoint_chooser_empty_hint, ptt_waypoint_chooser_tour_label, ptt_waypoint_chooser_create_new, ptt_waypoint_chooser_created, ptt_recording_preview_play, ptt_recording_preview_pause
    app/src/main/kotlin/de/waypointaudio/ui/PttRecordingDialogs.kt Preview-Player + Play/Pause in der Bibliothek; Tour-Dropdown + „Neuen Wegpunkt erstellen" im Chooser; deutsche Erfolgs-/Hinweistexte
    app/src/main/kotlin/de/waypointaudio/viewmodel/WaypointViewModel.kt Öffentliche postInfo / postError Setter (additive Änderung)
    .gitignore Schutz vor versehentlichem Einchecken von keystore.properties und *.jks

    Es wurden keine anderen Klassen / Services / Player / Stores
    verändert.


    4. Build- und Signaturstatus

    • Toolchain: JDK 21, Android SDK 35, Build-Tools 35.0.0,
      Gradle 8.9, AGP 8.5.2, Kotlin 2.0.21.
    • Build-Befehl: gradle :app:assembleRelease (kein Daemon).
    • Signatur: v2 APK Signature Scheme – verifiziert mit apksigner.
      Signiert mit dem produktiven Release-Keystore gps2audio_release
      (PKCS12, RSA 4096, SHA384withRSA). Der signierte Build ist damit
      updatefähig zu früheren v2.x-Installationen.
    • Apk-Pfad: /home/user/workspace/GPS2Audio_v2_1_1_ptt_recorder_play_assign_signed.apk
    • Größe / Metadaten:
      • package: name='de.waypointaudio' versionCode='38' versionName='2.1.1'
      • targetSdkVersion='35', sdkVersion:'26'
    • Gradle-Ausgabe: BUILD SUCCESSFUL in 1m 22s. Nur Compiler-
      Warnungen (deprecation hints aus bestehenden Modulen, kein Bezug
      zu den neuen Änderungen außer Icons.Filled.Assignment – bewusst
      beibehalten zur visuellen Konsistenz mit v2.1.0).

    5. Manuelle Tests (Schritt für Schritt)

    PTT-Aufnahmen anhören

    1. App öffnen → Tour „Standard" auswählen.
    2. PTT-Einstellungen → „Aufnahme speichern" aktivieren.
    3. Mehrere kurze PTT-Aufnahmen erzeugen (PTT-Toggle aus/an).
    4. Menü → „Aufnahmen…" öffnen → Dialog „PTT-Aufnahmen" erscheint.
    5. Auf „Anhören" einer Aufnahme tippen → Wiedergabe startet, Button
      wechselt zu „Pause".
    6. Auf „Pause" tippen → Wiedergabe pausiert; erneutes Tippen auf
      „Anhören" derselben Aufnahme → resumed.
    7. Auf „Anhören" einer anderen Aufnahme tippen → erste Vorschau
      stoppt automatisch, zweite startet.
    8. Dialog schließen (X / Außerhalb) → Wiedergabe stoppt sofort.
    9. Aufnahme während laufender Vorschau löschen → Vorschau stoppt
      sicher, Datei + Eintrag entfernt.

    Zuweisung an Wegpunkte

    1. In leerer Tour „Standard": Eine Aufnahme „Zuweisen" wählen →
      Dialog „Wegpunkt auswählen" zeigt Dropdown „Tour: Standard" und
      Hinweistext + Button „Neuen Wegpunkt aus Aufnahme erstellen".
    2. Button drücken → Wegpunkt wird angelegt; Snackbar/Banner
      bestätigt: „Wegpunkt … in Tour … angelegt." Liste enthält den
      neuen Wegpunkt; Audio ist gesetzt.
    3. Mehrere Touren anlegen, eine davon mit Wegpunkten füllen.
    4. Aufnahme zuweisen → Tour-Dropdown öffnen → Tour mit Wegpunkten
      wählen → Liste erscheint → Wegpunkt antippen → Audio wird der
      Wegpunkt zugewiesen; Bestätigung erscheint.
    5. „Neuen Wegpunkt aus Aufnahme erstellen" auch in nicht-leerer
      Tour → erzeugt zusätzlichen Wegpunkt (sekundärer Button).

    Position

    1. Ohne GPS-Position (kein vorheriges fetchCurrentLocation):
      neuer Wegpunkt nutzt – sofern in der Aufnahme vorhanden – die
      GPS-Metadaten der Aufnahme; sonst 0.0/0.0 (vom Nutzer
      nachträglich editierbar).
    2. Mit aktiver GPS-Position (z.B. nach „Neuen Wegpunkt"-Klick im
      Hauptscreen): wird bevorzugt.

    6. Regression-Checkliste (v2.1.0 → v2.1.1)

    Bereich Erwartetes Verhalten Status
    Stream-Playlist (Service-owned Atmo-Player, Hintergrundwiedergabe) Unverändert; Atmo läuft im Foreground-Service weiter, Sperrbildschirm-Steuerung verfügbar keine Änderung am Service / AtmoPlaybackService / BackgroundMusicManager
    PTT pausiert Waypoint und Atmo WaypointAudioInterruptionCoordinator Pfad unverändert; Preview-Player ist außerhalb dieses Pfads (rein UI-lokale Vorschau)
    Drag-and-drop Waypoint-Sortierung Unverändert kein Eingriff in WaypointListScreen-Sortierlogik
    Karteneditor / Drafts / Map Search Unverändert keine Änderung an MapScreen, TrackDraftEditorScreen, PlaceSearchDialog, NominatimClient
    Backup Export / Import Unverändert keine Änderung an BackupExportManager/BackupImportManager
    About / PayPal / Versions-Dialog Unverändert. Versions-Dialog erscheint automatisch wieder bei versionCode 38, weil dismissedVersionCode < 38.
    Audio-Bibliothek (manuelle Auswahl von Sound-Dateien) Unverändert
    OSM Attribution Unverändert
    ScrollableTabRow Fix Unverändert
    Touren ordnen / umbenennen / löschen Unverändert moveTour, renameTour, deleteTour nicht angefasst
    Post-Aufnahme-Dialog Identisches Verhalten zu v2.1.0
    PTT-Aufnahme-Pfad (Recorder, Speicherung, Bibliothek-Persistenz) Identisch zu v2.1.0 PttRecorder und LivePttManager unverändert
    Manueller Waypoint-Player Identisch zu v2.1.0 ManualAudioPlayer unverändert

    Risikoanalyse: Sämtliche Änderungen sind additiv und auf zwei UI-
    Dialoge sowie zwei neue, idempotente Setter im ViewModel
    beschränkt. Der Preview-Player ist räumlich auf den Dialog
    beschränkt und benutzt eine eigene MediaPlayer-Instanz, die durch
    DisposableEffect und mehrfache explizite release()-Aufrufe sicher
    freigegeben wird. Es gibt keinen geteilten Zustand mit den
    bestehenden Playern.


    7. Sicherheit / Auslieferung

    • Keystore-Datei (GPS2Audio_release_keystore.jks) und
      keystore.properties mit Passwörtern sind nicht im
      GPS2Audio_v2_1_1_ptt_recorder_play_assign_source.zip enthalten.
      Geprüft per unzip -l; im ZIP befindet sich ausschließlich die
      Vorlage keystore.properties.example.
    • .gitignore zusätzlich abgesichert (keystore.properties, *.jks).
    • Der Build erwartet beim erneuten Erstellen entweder
      keystore.properties im Projekt-Root oder die ENV-Variablen
      GPS2AUDIO_RELEASE_STORE_FILE/…_STORE_PASSWORD/…_KEY_ALIAS/
      …_KEY_PASSWORD (Details: keystore.properties.example).

    8. Ergebnisartefakte

    • GPS2Audio_v2_1_1_ptt_recorder_play_assign_signed.apk – signierte
      Release-APK, updatefähig (15,2 MB).
    • GPS2Audio_v2_1_1_ptt_recorder_play_assign_source.zip – komplette
      Quellen ohne Build-Artefakte, ohne Keystore, ohne Passwort-Datei.
    • GPS2Audio_v2_1_1_ptt_recorder_play_assign_handoff.md – dieses
      Dokument.
    Downloads