-
released this
2026-05-15 14:32:24 +02:00 | 7 commits to main since this releaseGPS2Audio v2.0.8 – Stream-Playlist (Atmo/Begleitmusik)
Version: 2.0.8 · versionCode: 36 · Build type: Release (signed) · Baseline: v2.0.7 (
GPS2Audio_v2_0_7_atmo_service_player_source.zip)Artefakte
Pfad Inhalt /home/user/workspace/GPS2Audio_v2_0_8_stream_playlist_signed.apkSigniertes Release-APK (v2 APK Signing) /home/user/workspace/GPS2Audio_v2_0_8_stream_playlist_source.zipVollständiger Quellbaum ohne build/, ohne Keystore, ohnekeystore.properties/home/user/workspace/GPS2Audio_v2_0_8_stream_playlist_handoff.mdDieses Dokument APK-Eckdaten (
aapt dump badging):package: name='de.waypointaudio' versionCode='36' versionName='2.0.8'- compileSdk 35, minSdk 26, targetSdk 35
- Signer 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 mit Release-Keystore ausGPS2Audio_release_keystore_credentials.txt) - APK-SHA-256:
2b9a1f25f54fbf7b93eb4dd24c824dc429fe293e62774cd777c5902d14a13053 - Größe: ~14.5 MB
apksigner verify: ✅Verifies(APK Signature Scheme v2)
Was ist neu in 2.0.8
Die einzige Stream-URL pro Tour wird durch eine Stream-Playlist ersetzt. User können beliebig viele
Internet-Stream-Einträge (URL + optionaler Name) pro Tour anlegen, umsortieren und nacheinander abspielen.
Der service-eigene ExoPlayer aus v2.0.7 wurde unverändert übernommen – die Stream-Playlist wird einfach als
mehrteiligeMediaItem-Liste an die bestehende Player-Pipeline übergeben.Alle anderen v2.0.7-Funktionen bleiben unverändert: service-eigener ExoPlayer (Foreground Service
mediaPlayback), PTT pausiert Wegpunkt + Atmo, Drag-Reorder, Wake Lock, Map-Provider, Track-Editor +
Drafts, Backup-Export/Import, Map-Suche, Audio-Bibliothek, OSM-Attribution, TabRow-Fix, About-Dialog
mit PayPal-Link/Versions-Notiz.Datenmodell + Migration
Neu in
TourAudioSettings
(app/src/main/kotlin/de/waypointaudio/data/TourAudioSettings.kt):data class StreamEntry(val url: String, val name: String = "") data class TourAudioSettings( … val streamPlaylist: List<StreamEntry> = emptyList(), val streamUrl: String? = null, // Legacy-Feld – nur für Backward-Compat … ) { val effectiveStreamPlaylist: List<StreamEntry> get() = when { streamPlaylist.isNotEmpty() -> streamPlaylist !streamUrl.isNullOrBlank() -> listOf(StreamEntry(url = streamUrl, name = "")) else -> emptyList() } fun migrated(): TourAudioSettings = … // streamUrl → streamPlaylist }Persistenz (
TourMusicStore):streamPlaylistwird als JSON-Array[{url, name}, …]neben dem
bestehendenstreamUrl-Feld gespeichert. Beim Laden:- Wenn
streamPlaylistbefüllt ist → wird direkt benutzt. - Wenn
streamPlaylistleer ist undstreamUrlbefüllt ist → einmalige Migration in einen einzigen
StreamEntry(url=streamUrl, name=""),streamUrlwird aufnullgesetzt. - Sobald der User die Einstellungen das nächste Mal speichert, ist die Migration auf Disk persistiert.
Backward-Compatibility:
- Beim Lesen alter Datastore-Inhalte (v2.0.7 oder älter):
streamPlaylist-Feld fehlt im JSON → wird als
leere Liste interpretiert (Gson-Default). Anschließendmigrated()aufrufen → Legacy-streamUrlwird in
eine ein-Element-Playlist überführt. Der User sieht in v2.0.8 sofort die alte URL als ersten Eintrag der
Stream-Playlist. - Beim Schreiben neuer Settings aus dem Dialog wird
streamUrl=nullgespeichert; die kanonische
Quelle ist diestreamPlaylist. Ältere App-Versionen können die JSON-Repräsentation immer noch lesen
(Gson ignoriert das unbekanntestreamPlaylist-Feld bei v2.0.7), zeigen aber dann keine Stream-URL,
weil das Legacy-Feld leer ist – das wäre also ein Downgrade-Pfad und kein normaler Use-Case.
Keine DB-Migration nötig –
TourMusicStorebenutzt JSON in DataStore und ist tolerant gegenüber
fehlenden Feldern (Gson-Defaults).UI-Flow (Begleitmusik-Dialog)
Datei: app/src/main/kotlin/de/waypointaudio/ui/BegleitmusikDialog.kt
Quelle „Stream-URL" wählen → die alte einzelne URL-Eingabe ist ersetzt durch:
- Stream-Playlist-Liste (oben): pro Eintrag eine Zeile mit Radio-Icon, Name (falls vergeben) bzw. URL,
Buttons:↑/↓(Reorder, sequentiell – kein Drag, da im Dialog overkill)✏️ Bearbeiten→ lädt den Eintrag in die Eingabefelder unten✕ Entfernen(rot)
- Eingabesektion „Stream hinzufügen" / „Stream bearbeiten":
Name (optional)– Klartext, z. B. „Deutschlandfunk Kultur"Stream-URL– Pflicht, validiert aufhttp://oderhttps://, Fehleranzeige unter dem Feld- Buttons:
Hinzufügen/Übernehmen(Edit) /Abbrechen(nur im Edit-Modus) /Playlist leeren(rot)
- Shuffle-Switch erscheint zusätzlich nur wenn
streamPlaylist.size > 1. - Der bestehende Plattform-Hinweis zu YouTube/SoundCloud/radio.de bleibt erhalten.
- Bei „Speichern" mit leerer Stream-Playlist und Quelle=Stream → Fehlermeldung
music_stream_playlist_empty_error(„Bitte mindestens einen Stream zur Playlist hinzufügen.")
Alle Labels sind auf Deutsch lokalisiert (neue Strings in
res/values/strings.xmlZeilen ~280–298,
Prefixmusic_stream_*).Playback-Verhalten
Datei: app/src/main/kotlin/de/waypointaudio/service/AtmoPlaybackService.kt
- Neue Intent-Extras:
EXTRA_STREAM_URLS(String[]),EXTRA_STREAM_NAMES(String[]). - Legacy
EXTRA_STREAM_URLwird weiterhin gesetzt (= erstes Element der Playlist) für Re-Delivery-Fälle. applySettingsFromIntentbaut beiisStream=trueausEXTRA_STREAM_URLSeine Liste vonMediaItems
und übergibt sie unverändert über die bestehende ExoPlayer-Initialisierung – derselbe Code-Pfad wie für
lokale Playlists. ExoPlayer behandelt Next/Previous, Auto-Advance und Fehler nativ über
Player.REPEAT_MODE_ALLund diePlayer.Listener-Callbacks, die wir bereits hatten.- Wenn ein Stream-Item fehlerhaft ist (Netzwerk, falsche URL), gehört das zum Standard-ExoPlayer-Verhalten
→ der Player loggt den Fehler und überträgt den nächstenMediaItem(Repeat-All). Es gibt keinen Crash. MusicPlaybackState:isStream = truebleibt für alle Stream-Modi.playlistIndex/playlistTotalwerden bei Stream-Playlists mit > 1 Eintrag korrekt befüllt – die
UI kann darüber „1/3" anzeigen wie für lokale Playlists.supportsSkip = total > 1gilt jetzt auch für Stream-Playlists, sodass die Next/Previous-Buttons
funktionieren.currentTitlezeigt den Stream-Namen, wenn vergeben, sonst den URL-Host.sourceLabelzeigt „ Streams" bei Playlists mit > 1 Eintrag, sonst den Host.
Background-Wiedergabe (v2.0.7-Verhalten unverändert): Der Foreground-Service
AtmoPlaybackService
besitzt den ExoPlayer. PTT/Wegpunkt-Audio pausiert die Wiedergabe wie zuvor (VerhaltenPAUSE_RESUME,
FADE_OUT_IN,DUCK_UNDERLAY,CONTINUE_UNDERLAYgreifen auf Stream-Playlists wie auf lokale Playlists).
Drag-Reorder im Wegpunkt-Listenscreen ist nicht betroffen.Backup-Export/Import
Export (io/BackupExportManager.kt):
data/music_settings.jsonenthält jetzt zusätzlichstreamPlaylist: [{url, name}, …]pro Tour
(effectiveStreamPlaylist– auch bei Tourdaten, die noch das Legacy-streamUrlhaben). Das alte Feld
streamUrlbleibt im Export-JSON aus Kompat-Gründen enthalten (nun typischerweisenull).Import (io/BackupImportManager.kt):
parseMusicSettings()lieststreamPlaylist(neu); falls fehlend undstreamUrlgesetzt → Migration
in eine ein-Element-Stream-Playlist. Damit funktionieren v2.0.7-Backups uneingeschränkt – die alte
Stream-URL erscheint nach dem Import als erster Eintrag der Stream-Playlist.Manuelle Tests
Erstinstallation (Geräte-Daten vorher leer):
- Stream-Playlist anlegen – Tour erstellen → Begleitmusik → Quelle „Stream-URL" → zwei Streams
eintragen (z. B.https://liveradio.swr.de/sw282p3/swr3/play.mp3und
https://st01.dlf.de/dlf/01/104/ogg/stream.ogg) → speichern → Play-Button → erster Stream startet im
Foreground. - Next/Previous – Skip-Vor/Zurück-Buttons springen zwischen den beiden Streams.
- Background – App in den Hintergrund schicken, Bildschirm aus → Musik läuft weiter (Notification
bleibt sichtbar). App schließen (Recents wischen) → Wiedergabe läuft weiter; Stop-Action in der
Notification beendet sie. - PTT-Pause – PTT aktivieren → Atmo-Stream pausiert; PTT loslassen → Wiedergabe setzt fort, abhängig
vom Verhalten (PAUSE_RESUME / FADE_OUT_IN / DUCK / CONTINUE). - Wegpunkt-Pause – an einem Wegpunkt vorbeigehen oder „Test" → Wegpunkt-Ton spielt, Atmo verhält sich
gemäß Behavior-Modus. - Reorder – Streams in der Liste per
↑/↓umsortieren → Save → Reihenfolge bleibt nach App-Restart
erhalten. - Edit & Delete – Eintrag bearbeiten (Name + URL ändern) und entfernen → Liste reagiert sofort.
- Shuffle – Switch erscheint bei > 1 Stream-Eintrag, aktivieren → Reihenfolge wird zufällig.
- Lokale Playlist – Quelle auf „Lokale Playlist" wechseln → bestehende lokale Playlist + Audio-
Bibliothek funktionieren unverändert. Audio-Bibliothek-Picker für lokale Files wurde nicht angefasst. - Validation – Stream-URL ohne
http(s)://eintragen → Fehlermeldung. Stream-Playlist leer + Quelle
Stream + Save → Fehlermeldung.
Migration / Backward-Compatibility:
11. v2.0.7-Backup importieren – Backup-ZIP aus v2.0.7 öffnen → Touren mit einzelner Stream-URL
erscheinen nach Import unter „Stream-Playlist" mit genau einem Eintrag (URL-Feld gefüllt, Name leer).
12. In-Place-Upgrade – v2.0.7-APK deinstallieren nicht notwendig (gleiche Signatur, gleiche
applicationId). Nach Upgrade auf 2.0.8 zeigen vorhandene Touren ihre alte Stream-URL automatisch in der
neuen Stream-Playlist.
13. Backup-Export – Backup in v2.0.8 erstellen → ZIP enthältstreamPlaylist-Feld (kann mitunzip -p backup.zip data/music_settings.jsoninspiziert werden).Regressions-Checkliste (v2.0.7-Features)
- Service-owned ExoPlayer –
AtmoPlaybackServicebesitzt weiterhin den Player; Wiedergabe läuft
durch App-Hintergrund, Bildschirm aus, App-Kill (Recents). - PTT pausiert Wegpunkt + Atmo –
LivePttManagerundAtmoResumeManagerunverändert. Stream-
Playlist verhält sich identisch zu lokalen Playlists. - Drag-Reorder Wegpunkte –
WaypointListScreenund Drag-Logic unverändert. - Wake Lock – ExoPlayer-Wake-Mode (
WAKE_MODE_NETWORKfür Streams,WAKE_MODE_LOCALfür lokale)
bleibt erhalten. - Map-Provider – Map-Screen + Provider-Auswahl nicht angefasst.
- Track-Editor + Drafts – Code in
editor/TrackDraftListScreennicht modifiziert. - Backup-Export/Import – Music-Settings-JSON erweitert (kompatibel mit alten Backups), alle
anderen Sektionen unverändert. - Map-Suche – Code in
MapScreennur Compiler-Warnung (deprecatedfillColor– schon in v2.0.7),
keine Verhaltensänderung. - Audio-Bibliothek –
LibraryPickerDialogundaudioLibrary-Flow unverändert. - OSM-Attribution – nicht modifiziert.
- TabRow-Fix – nicht modifiziert.
- About-Dialog (PayPal-Link, Versions-Notiz) – nicht modifiziert; Version wird automatisch aus
BuildConfig gelesen (2.0.8).
Geänderte Dateien
app/build.gradle.kts versionCode 35→36, versionName "2.0.7"→"2.0.8" app/src/main/kotlin/de/waypointaudio/data/TourAudioSettings.kt + StreamEntry, streamPlaylist, effectiveStreamPlaylist, migrated() app/src/main/kotlin/de/waypointaudio/data/TourMusicStore.kt + StreamEntryJson, streamPlaylist-Persistenz, Migration im Read-Pfad app/src/main/kotlin/de/waypointaudio/service/AtmoPlaybackService.kt + EXTRA_STREAM_URLS/NAMES, buildStreamItems(List<StreamEntry>), state für mehrere Streams app/src/main/kotlin/de/waypointaudio/service/BackgroundMusicPlayer.kt srcOk-Check auf effectiveStreamPlaylist app/src/main/kotlin/de/waypointaudio/ui/BegleitmusikDialog.kt komplettes Stream-Playlist-UI (Liste, Add/Edit/Delete, Reorder, Validate, Shuffle) app/src/main/kotlin/de/waypointaudio/ui/WaypointListScreen.kt hasSource-Check auf effectiveStreamPlaylist app/src/main/kotlin/de/waypointaudio/viewmodel/WaypointViewModel.kt sourceOk-Check auf effectiveStreamPlaylist app/src/main/kotlin/de/waypointaudio/io/BackupExportManager.kt + streamPlaylist im JSON-Export app/src/main/kotlin/de/waypointaudio/io/BackupImportManager.kt parseMusicSettings liest streamPlaylist mit Legacy-Migration app/src/main/res/values/strings.xml + 14 neue Strings music_stream_*Build-Reproduktion
unzip GPS2Audio_v2_0_8_stream_playlist_source.zip -d gps2audio cd gps2audio cat > keystore.properties <<EOF storeFile=/path/to/GPS2Audio_release_keystore.jks storePassword=<store password> keyAlias=gps2audio_release keyPassword=<key password> EOF export ANDROID_HOME=/path/to/android-sdk # platforms/android-35, build-tools/35.0.0 gradle :app:assembleRelease # Output: app/build/outputs/apk/release/app-release.apkVerifiziert:
apksigner verify --verbose app-release.apk→Verifies(v2-Scheme), Signer-CN
CN=GPS2Audio, OU=NesoHub, O=GPS2Audio, L=Germany, C=DE.Downloads