Release GPS2Audio v2.5.44 POI category fix

This commit is contained in:
Perplexity Computer
2026-05-30 05:42:44 +00:00
parent 18ea77b21d
commit 014e6c1bf1
100 changed files with 28584 additions and 1083 deletions
@@ -23,6 +23,7 @@ import de.waypointaudio.data.PlaybackMode
import de.waypointaudio.data.TourAudioSettings
import de.waypointaudio.data.TourMusicStore
import de.waypointaudio.data.Waypoint
import de.waypointaudio.data.activeClips
import de.waypointaudio.repository.WaypointRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -157,6 +158,9 @@ class WaypointLocationService : Service() {
private fun stopTracking() {
fusedLocationClient.removeLocationUpdates(locationCallback)
audioPlayer.stop()
WaypointAudioInterruptionCoordinator.unregister(
WaypointAudioInterruptionCoordinator.Source.GPS
)
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
Log.i(TAG, "GPS-Tracking gestoppt")
@@ -206,9 +210,10 @@ class WaypointLocationService : Service() {
val msg = getString(R.string.notification_waypoint_reached, waypoint.name)
updateNotification(msg)
// Ton nur abspielen wenn Audiodatei vorhanden und Abspielregeln erfuellt
if (waypoint.soundUri.isBlank()) {
Log.d(TAG, "Kein Ton fuer Wegpunkt '${waypoint.name}' - keine Audiodatei")
// v2.5.12 — Effektive Clipliste prüfen. activeClips() berücksichtigt
// sowohl das neue audioClips-Modell als auch Legacy-soundUri.
if (waypoint.activeClips().isEmpty()) {
Log.d(TAG, "Kein Ton fuer Wegpunkt '${waypoint.name}' - keine aktiven Audioclips")
return
}
@@ -246,21 +251,28 @@ class WaypointLocationService : Service() {
/**
* Spielt den Wegpunkt-Ton ab (Begleitmusik-Sequenz).
* Kann direkt oder nach PTT-Ende aufgerufen werden.
*
* v2.5.12 — Multi-Clip:
* - Es werden ALLE aktiven Clips des Wegpunkts der Reihe nach abgespielt.
* - Inaktive Clips werden übersprungen (siehe [Waypoint.activeClips]).
* - Begleitmusik wird einmalig vor dem ersten Clip pausiert/geduckt
* und einmalig nach dem letzten Clip wiederhergestellt — nicht zwischen
* den Clips, damit die Sequenz nahtlos wirkt.
* - playCount wird genau einmal pro Eintrittsereignis erhöht, nachdem
* der letzte Clip natürlich endete (keine Erhöhung bei Fehler).
* - Bei einem Fehler eines Clips wird abgebrochen, Begleitmusik wieder
* hergestellt; playCount bleibt unverändert.
*/
private fun playWaypointAudio(waypoint: Waypoint) {
// Begleitmusik-Sequenz:
// 1. beforeWaypointAudio() - Begleitmusik pausieren/ducken/faden
// 2. audioPlayer.play() - Wegpunkt-Ton starten
// 3a. onCompletion - nach naturalem Ende: afterWaypointAudio() + playCount++
// 3b. onError - bei Fehler: afterWaypointAudio() (kein playCount++)
//
// Alles laeuft im Main-Dispatcher, da ExoPlayer (Begleitmusik) Main erfordert.
// Die Callbacks von AudioPlayer kommen auf dem MediaPlayer-Thread und werden
// per serviceScope.launch(Dispatchers.Main) weitergeleitet.
serviceScope.launch(Dispatchers.Main) {
val mgr = musicManager
val clipUris = waypoint.activeClips().map { it.uri }
if (clipUris.isEmpty()) {
Log.d(TAG, "playWaypointAudio: keine aktiven Clips für '${waypoint.name}'")
return@launch
}
// Tour-Einstellungen laden
val settings: TourAudioSettings? = if (mgr != null) {
runCatching {
@@ -269,7 +281,7 @@ class WaypointLocationService : Service() {
}.getOrNull()
} else null
// 1. Begleitmusik vor Wegpunkt-Audio anpassen
// 1. Begleitmusik einmalig vor erstem Clip anpassen
if (mgr != null && settings != null && settings.enabled) {
runCatching {
mgr.currentSettings = settings
@@ -279,35 +291,85 @@ class WaypointLocationService : Service() {
}
}
// 2. Wegpunkt-Ton abspielen
// onCompletion und onError werden auf dem MediaPlayer-Thread aufgerufen;
// wir leiten sie zurueck in den Main-Dispatcher fuer ExoPlayer-Zugriffe.
audioPlayer.play(
context = applicationContext,
soundUri = waypoint.soundUri,
onCompletion = {
// Natuerliches Ende: Begleitmusik wiederherstellen + Zaehler erhoehen
serviceScope.launch(Dispatchers.Main) {
Log.d(TAG, "Wegpunkt-Ton beendet (natural completion): ${waypoint.name}")
restoreBackgroundMusic(mgr, settings)
}
// playCount auf IO-Thread inkrementieren (Repository-Zugriff)
serviceScope.launch(Dispatchers.IO) {
runCatching {
repository.incrementPlayCount(waypoint.id)
}.onFailure { e ->
Log.e(TAG, "Fehler beim Inkrementieren von playCount fuer ${waypoint.name}", e)
}
}
},
onError = { e ->
// Fehler: Begleitmusik trotzdem wiederherstellen; kein playCount++
serviceScope.launch(Dispatchers.Main) {
Log.w(TAG, "Wegpunkt-Ton Fehler (${waypoint.name}): ${e?.message}")
restoreBackgroundMusic(mgr, settings)
}
}
// 2. Beim PTT-Coordinator registrieren über die gesamte
// Multi-Clip-Sequenz hinweg. Pause/Resume betreffen immer
// den aktuell aktiven MediaPlayer im AudioPlayer-Wrapper.
WaypointAudioInterruptionCoordinator.register(
source = WaypointAudioInterruptionCoordinator.Source.GPS,
isCurrentlyPlaying = { audioPlayer.isPlaying },
pause = { audioPlayer.pause() },
resume = { audioPlayer.resume() }
)
// 3. Clips sequenziell abspielen.
playClipSequence(
waypoint = waypoint,
clipUris = clipUris,
index = 0,
mgr = mgr,
settings = settings
)
}
}
/**
* v2.5.12 — Spielt den Clip mit Index [index] und ruft sich selbst nach
* natürlichem Ende für den nächsten Clip auf. Bei Fehler oder am Ende
* der Liste wird die Begleitmusik wiederhergestellt; der Coordinator
* abgemeldet; und bei natürlichem Ende der gesamten Sequenz wird
* playCount inkrementiert.
*/
private fun playClipSequence(
waypoint: Waypoint,
clipUris: List<String>,
index: Int,
mgr: BackgroundMusicManager?,
settings: TourAudioSettings?
) {
if (index !in clipUris.indices) {
// Sequenz erfolgreich durchlaufen
finishSequence(waypoint, mgr, settings, incrementPlayCount = true)
return
}
val uri = clipUris[index]
audioPlayer.play(
context = applicationContext,
soundUri = uri,
onCompletion = {
serviceScope.launch(Dispatchers.Main) {
Log.d(TAG, "Clip ${index + 1}/${clipUris.size} beendet (${waypoint.name})")
playClipSequence(waypoint, clipUris, index + 1, mgr, settings)
}
},
onError = { e ->
Log.w(TAG, "Clip ${index + 1}/${clipUris.size} Fehler (${waypoint.name}): ${e?.message}")
// Bei Fehler abbrechen, Begleitmusik wiederherstellen, KEIN playCount++
serviceScope.launch(Dispatchers.Main) {
finishSequence(waypoint, mgr, settings, incrementPlayCount = false)
}
}
)
}
private fun finishSequence(
waypoint: Waypoint,
mgr: BackgroundMusicManager?,
settings: TourAudioSettings?,
incrementPlayCount: Boolean
) {
WaypointAudioInterruptionCoordinator.unregister(
WaypointAudioInterruptionCoordinator.Source.GPS
)
restoreBackgroundMusic(mgr, settings)
if (incrementPlayCount) {
serviceScope.launch(Dispatchers.IO) {
runCatching {
repository.incrementPlayCount(waypoint.id)
}.onFailure { e ->
Log.e(TAG, "Fehler beim Inkrementieren von playCount fuer ${waypoint.name}", e)
}
}
}
}