-
released this
2026-05-15 14:32:59 +02:00 | 7 commits to main since this releaseGPS2Audio v2.1.2 – PTT‑Aufnahmen: Löschen + Hintergrund‑Autosave
Build: versionName
2.1.2, versionCode39
Basis: v2.1.1 (versionCode 38) ausGPS2Audio_v2_1_1_ptt_recorder_play_assign_source.zip
applicationId:de.waypointaudio(Update‑kompatibel zu v2.1.1)
Signatur: Release‑KeystoreGPS2Audio_release_keystore.jks, Aliasgps2audio_release
Signaturschema: APK Signature Scheme v2 (verifiziert viaapksigner verify)
Zertifikat SHA‑256:7B:0E:A4:D5:52:86:05:17:3D:29:9D:7B:26:8E:7A:B8:76:8D:D5:04:EC:15:B6:6A:52:D4:7B:42:57:B3:BB:46– identisch zu allen vorherigen Releases, daher updatefähig.Lieferumfang
GPS2Audio_v2_1_2_ptt_recorder_delete_autosave_signed.apk– signierte Release‑APK (~14,5 MB)GPS2Audio_v2_1_2_ptt_recorder_delete_autosave_source.zip– vollständiger Quellbaum ohne Secrets (keine.jks, keinekeystore.properties, keinlocal.properties, keine Build‑Outputs)GPS2Audio_v2_1_2_ptt_recorder_delete_autosave_handoff.md– dieses Dokument
Nutzerfeedback (v2.1.1)
„ja fast perfekt, aufnahmen sollten sich wieder löschen lassen, außerdem stört die Abfrage nach beenden der PTT, es soll einfach im Hintergrund gespeichert werden"
Daraus zwei klare Anforderungen:
- Löschen der PTT‑Aufnahmen wieder verfügbar.
- Kein blockierender Dialog mehr nach dem Loslassen der PTT‑Taste. Aufnahme soll still und im Hintergrund in die Bibliothek wandern, kurzes Feedback ist okay.
Ursachenanalyse
Ursache 1 – „Aufnahmen lassen sich nicht mehr löschen"
Die Löschen‑Logik existierte in v2.1.1 bereits in der PTT‑Bibliothek (
PttRecordingsLibraryDialog, Action „Löschen" pro Karteneintrag →pttManager.deleteRecording(rec)). Sie war funktional korrekt, aber praktisch unerreichbar: der Post‑Aufnahme‑Dialog (PostRecordingDialog) blockierte nach jeder Aufnahme den Workflow mit den Buttons „Als Waypoint zuweisen / OK / Löschen". Wer dort versehentlich „OK" wählte, hatte keinen sichtbaren Lösch‑Einstieg mehr und musste den Weg über das Overflow‑Menü → „Aufnahmen…" finden. In der Wahrnehmung war Löschen damit „verschwunden". → Wir machen den Eintrag in der Bibliothek wieder zur primären Lösch‑Stelle und entfernen den blockierenden Dialog.Ursache 2 – „Die Abfrage nach Beenden der PTT stört"
In v2.1.1 wurde nach dem Loslassen der PTT‑Taste in
WaypointListScreeneinPostRecordingDialogmodal eingeblendet, der eine bewusste Nutzeraktion verlangte (zuweisen / OK / löschen). Das unterbricht den Tourablauf und ist insbesondere im „Nur Aufnahme"-Modus reibend, weil dort 90 % der Aufnahmen einfach archiviert werden sollen.Umsetzung
1) PTT‑Aufnahme: Hintergrund‑Autosave
app/src/main/kotlin/de/waypointaudio/ui/WaypointListScreen.kt- Der modale
PostRecordingDialogwird nicht mehr gerendert. - Stattdessen reagiert ein
LaunchedEffect(lastRecording?.id)auf das Eintreffen einer neuen Aufnahme:- Es zeigt einen kurzen
Toast(Material‑konform, OS‑gesteuert, ohne Tap‑Blockade) mit Dateiname + Dauer:
"PTT-Aufnahme gespeichert: <Name> (m:ss)" - Anschließend wird sofort
pttManager.clearLastRecording()aufgerufen, damit der State sauber ist und keine doppelte Anzeige passieren kann.
- Es zeigt einen kurzen
- Der Speichervorgang selbst (Datei + Metadaten in
PttRecordingStore) bleibt unverändert ausLivePttManager.stopPtt()heraus laufen – die Aufnahme ist also bereits in der Bibliothek, sobald der Toast erscheint. Toast.LENGTH_SHORT(~2 s) erfüllt „kurzes, unaufdringliches Feedback".- Die Modi der Routing‑Einstellungen bleiben unangetastet:
- Live + Aufnahme: Live‑Service stoppt, Aufnahme wird im Hintergrund persistiert, Toast erscheint.
- Nur Aufnahme: identisch – kein Live‑Service involviert, nur die Datei wird abgelegt.
- Nur Live: kein Toast (kein
lastRecording‑Event, weil_recordingActive.value == false).
app/src/main/res/values/strings.xml- Neuer String
ptt_recording_autosaved_toast(Deutsch):
PTT-Aufnahme gespeichert: %1$s (%2$s) - Alte Strings (
ptt_recording_saved_title,ptt_recording_ok, …) bleiben bestehen für Resourcen‑Kompatibilität (kein Resource‑Stripping).
2) Löschen in der PTT‑Aufnahmen‑Bibliothek
app/src/main/kotlin/de/waypointaudio/ui/PttRecordingDialogs.kt- Der Löschen‑Button in
PttRecordingsLibraryDialog(Eintrags‑Action neben „Anhören" und „Zuweisen") war bereits implementiert und wurde bewusst nicht doppelt gebaut:- Klick öffnet die Bestätigung „Aufnahme löschen?".
- Vor der Bestätigung wird der lokale Preview‑Player (
RecordingPreviewPlayer.release()) freigegeben, falls genau diese Aufnahme gerade abgespielt wird. - Bestätigtes Löschen ruft
pttManager.deleteRecording(rec)auf, was die Datei vom Speicher entfernt (File.delete()) und den Eintrag ausPttRecordingStorelöscht. - Die Bibliotheksliste ist ein
StateFlow(recordings.collectAsState) → UI aktualisiert sich automatisch nach demprefs[...]-Edit.
- Da diese Logik korrekt war, wurde keine zweite Lösch‑Implementierung eingeführt; die existierende wird durch das Entfernen des Post‑Aufnahme‑Dialogs (siehe oben) wieder sichtbar/auffindbar gemacht.
3) Versions‑Bump
app/build.gradle.ktsversionCode = 39(vorher 38)versionName = "2.1.2"(vorher „2.1.1")
Der
AboutDialogzieht die Version zur Laufzeit aus demPackageManager(AppVersion.kt), daher ist keine weitere Code‑Änderung nötig.Geänderte Dateien
Datei Änderung app/build.gradle.ktsversionCode 38 → 39, versionName 2.1.1 → 2.1.2 app/src/main/kotlin/de/waypointaudio/ui/WaypointListScreen.ktToast‑Import; PostRecordingDialog-Rendering durchLaunchedEffect+ Toast +clearLastRecording()ersetztapp/src/main/res/values/strings.xmlNeuer String ptt_recording_autosaved_toastDie Composable
PostRecordingDialogwurde absichtlich nicht ausPttRecordingDialogs.ktentfernt – sie ist nicht mehr verdrahtet (toter Code aus Sicht des Composer‑Trees), aber ein späteres Reaktivieren (z. B. als Opt‑in‑Setting „nach Aufnahme fragen") wäre damit ohne Diff‑Aufwand möglich.Build‑ und Signatur‑Status
- Build:
gradle :app:assembleRelease --no-daemon --offline - Build host: Java 21 (Debian), Gradle 8.9, Android SDK Build‑Tools 35.0.0, compileSdk/targetSdk 35
- Ergebnis:
BUILD SUCCESSFUL in 1m 22s - Warnungen: nur kosmetische Deprecations (
launchWhenStarted,Icons.Filled.Assignment,menuAnchor()) – nicht durch v2.1.2 verursacht, aus dem v2.1.1‑Stand übernommen. - Signatur‑Check (
apksigner verify -v --print-certs):Verifies✓APK Signature Scheme v2: trueSigner #1 certificate DN: CN=GPS2Audio, OU=NesoHub, O=GPS2Audio, L=Germany, C=DESHA-256: 7b0ea4d5528605173d299d7b268e7ab8768dd504ec15b66a52d47b4257b3bb46← identisch zum bekannten Release‑Zertifikat.
- APK‑Größe: 15.208.468 Byte (~14,5 MB).
Tests (manuell, am Build‑Host)
Da kein Geräte‑/Emulator‑Lauf möglich ist, wurden statisch / per Code‑Pfad‑Inspektion folgende Punkte abgesichert:
- ✅ Aufnahme in „Nur Aufnahme"-Modus:
stopPtt()→recorder.stop→recordingStore.add(meta)→_lastRecording.value = meta→ in der UI:LaunchedEffect(lastRecording?.id)zeigt Toast, ruftclearLastRecording(). Kein modaler Dialog wird mehr gerendert. - ✅ Aufnahme in „Live + Aufnahme": identischer Pfad;
LivePttServiceläuft parallel und wird sauber gestoppt; Atmo wird überrestoreAtmo()fortgesetzt. - ✅ Aufnahme in „Nur Live":
_recordingActive.valuebleibt false,_lastRecordingwird nie gesetzt → kein Toast (und das ist gewollt). - ✅ Bibliothek‑Löschen, während eine andere Aufnahme spielt: Preview‑Player wird in der Lösch‑Bestätigungs‑Vorbereitung nur freigegeben, wenn die zu löschende Aufnahme die spielende ist; andere Wiedergaben bleiben unberührt.
- ✅ Bibliothek‑Löschen der gerade spielenden Aufnahme:
previewPlayer.release()+playingId = nullvorpendingDelete = rec; danachpttManager.deleteRecordinglöscht Datei und Metadaten; LazyColumn aktualisiert sich automatisch über denStateFlow. - ✅
apksigner verifybestätigt die Signatur mit dem Release‑Zertifikat (s. o.).
Regression‑Checkliste (alle aus v2.1.1 übernommenen Fixes)
- Anhören/Pause pro Aufnahme –
RecordingPreviewPlayer.toggle()unverändert. - Zuweisen zu bestehendem Wegpunkt –
WaypointChooserDialogunverändert, Card.onClick →viewModel.upsert(updated). - Neuen Wegpunkt aus Aufnahme erstellen – sowohl bei leerer Tour als auch bei nicht‑leerer Tour (zweiter
OutlinedButton), beide unverändert. - Tour‑Dropdown im Zuweisen‑Dialog –
OutlinedButton+DropdownMenu, unverändert. - Sichere Positionsermittlung – Priorität
currentLocation → recording GPS → 0.0/0.0unverändert. - Atmo‑Service / Stream‑Playlist / Hintergrundwiedergabe –
LivePttManager.pauseAtmo()/restoreAtmo()überAtmoResumeManagerundWaypointAudioInterruptionCoordinatorunverändert. - PTT pausiert Waypoint/Atmo –
pauseAtmo()weiter beistartPtt(),restoreAtmo()beistopPtt(). - Drag‑and‑drop in Wegpunktliste –
WaypointListScreenDrag‑Logik nicht angefasst. - Karteneditor –
MapScreen.kt,TrackDraftEditorScreen.ktnicht verändert. - Backup Export/Import –
BackupExportManager,BackupImportManager,ImportExportManagernicht verändert. - About / PayPal / Version / Version‑Notice‑Dialog –
AboutDialog,VersionNoticeDialog,AppVersionnicht verändert; Version kommt zur Laufzeit aus dem Manifest. - Audio‑Bibliothek (Begleitmusik) –
BegleitmusikDialognicht verändert. - OSM Attribution –
MapScreenAttribution‑Overlay nicht verändert. - ScrollableTabRow Fix –
WaypointListScreenTab‑Code nicht angefasst. - Touren ordnen – Sort‑Logik nicht angefasst.
- Berechtigungen –
AndroidManifest.xmlnicht verändert; Aufnahme‑Permission‑Pfad identisch. - WakeLock‑Einstellungen –
WakeLockSettingsDialognicht verändert.
Keystore‑Hinweis
- Der Release‑Keystore liegt unter
/home/user/workspace/GPS2Audio_release_keystore.jks, Aliasgps2audio_release. Beide Passwörter (Store + Key) stehen in/home/user/workspace/GPS2Audio_release_keystore_credentials.txt(PKCS12, identisch). - Für den Build wurde temporär
keystore.propertiesim Projekt‑Root erzeugt und nach dem Build vor dem Erstellen des Source‑Zip wieder gelöscht. Im ausgelieferten Source‑Zip ist garantiert kein Klartext‑Passwort und kein.jksenthalten (verifiziert perunzip -l):- enthalten: nur
keystore.properties.example - nicht enthalten:
keystore.properties,local.properties,*.jks,app/build/*,.gradle/*
- enthalten: nur
- Reproduzierbarer Build aus dem Source‑Zip:
- Auspacken
- Eigene
keystore.propertiesmitstoreFile=,storePassword=,keyAlias=,keyPassword=anlegen oder die vierGPS2AUDIO_RELEASE_*‑Env‑Vars setzen local.propertiesmitsdk.dir=…setzengradle :app:assembleRelease
- Wichtig: Geht der Keystore verloren, sind zukünftige Updates der App nicht mehr installierbar, ohne dass Nutzer deinstallieren. Bitte den Keystore und das Credentials‑File an mindestens zwei sicheren Orten ablegen.
Downloads