1115 lines
59 KiB
Markdown
1115 lines
59 KiB
Markdown
# GPS2Audio
|
||
|
||
Eine native Android-App (Kotlin + Jetpack Compose), die GPS-Wegpunkte überwacht und beim Betreten des jeweiligen Radius automatisch eine Audiodatei abspielt. Wegpunkte können zusätzlich **manuell** ohne aktives GPS über die integrierte Wiedergabeleiste abgespielt werden.
|
||
|
||
---
|
||
|
||
## Funktionen
|
||
|
||
- **Wegpunkte anlegen, bearbeiten, löschen** mit Name, Koordinaten (Lat/Lng), Radius (Meter) und zugeordneter Audiodatei
|
||
- **Automatische Audioauslösung**, sobald das Gerät in den Radius eines Wegpunkts eintritt
|
||
- **Abspielregeln & Zeitplan** pro Wegpunkt – flexibel steuerbar: bei jedem Betreten, nur einmal, begrenzt oft, mit optionalem Datum/Uhrzeit-Fenster und täglichem Zeitfenster
|
||
- **Hintergrundbetrieb** via Vordergrund-Dienst (`ForegroundService`) mit dauerhafter Benachrichtigung
|
||
- **Lokale Datenspeicherung** via Jetpack DataStore + JSON (kein Backend, kein Internet erforderlich)
|
||
- **Manuelle Wiedergabe** – Waypoints ohne GPS abspielen: Zurück, Play/Pause, Weiter direkt in der Übersicht
|
||
- **Material Design 3** Oberfläche mit professionellem Navy/Teal-Farbschema, Dark-Mode-fähig
|
||
- **JSON/GPX Import & Export** – Wegpunkte als Datei teilen, sichern oder übertragen (inkl. Abspielregel-Felder)
|
||
- **Kartenansicht** – OpenStreetMap/osmdroid mit Markern und Radius-Kreisen
|
||
- **Wegpunkt aus GPS-Position** – aktuellen Standort per Knopfdruck als neuen Wegpunkt übernehmen
|
||
|
||
---
|
||
|
||
## Voraussetzungen
|
||
|
||
| Anforderung | Version |
|
||
|---------------------------|-------------------|
|
||
| Android Studio | Hedgehog 2023.1.1+ |
|
||
| Android SDK | API 26 (Android 8.0) Minimum, API 35 Target |
|
||
| Kotlin | 2.0.21 |
|
||
| Gradle | 8.9 |
|
||
| Google Play Services | Gerät mit GMS (FusedLocationProvider) |
|
||
|
||
---
|
||
|
||
## Build & Run
|
||
|
||
### Android Studio
|
||
|
||
1. **Projekt öffnen**: `File → Open → .../waypoint-audio-guide`
|
||
2. **Gradle synchronisieren**: Android Studio führt dies automatisch beim Öffnen durch (`File → Sync Project with Gradle Files`)
|
||
3. **Gerät/Emulator verbinden**: Physisches Gerät empfohlen für GPS-Tests
|
||
4. **App starten**: Grüner Play-Button oder `Shift+F10`
|
||
|
||
### Kommandozeile (erfordert lokales Android SDK)
|
||
|
||
```bash
|
||
# ANDROID_HOME muss auf das SDK-Verzeichnis zeigen
|
||
export ANDROID_HOME=/path/to/android-sdk
|
||
|
||
cd waypoint-audio-guide
|
||
./gradlew assembleDebug
|
||
|
||
# APK befindet sich unter:
|
||
# app/build/outputs/apk/debug/app-debug.apk
|
||
```
|
||
|
||
### APK auf Gerät installieren
|
||
|
||
```bash
|
||
adb install app/build/outputs/apk/debug/app-debug.apk
|
||
```
|
||
|
||
---
|
||
|
||
## Berechtigungen
|
||
|
||
Die App fordert folgende Berechtigungen an:
|
||
|
||
| Berechtigung | Zweck |
|
||
|---|---|
|
||
| `ACCESS_FINE_LOCATION` | Genaue GPS-Position für Wegpunkt-Erkennung und aktuelle Position |
|
||
| `ACCESS_COARSE_LOCATION` | Grobe Positionsbestimmung (Fallback) |
|
||
| `ACCESS_BACKGROUND_LOCATION` | Wegpunkt-Erkennung bei geschlossener App (Android 10+) |
|
||
| `FOREGROUND_SERVICE` | Vordergrund-Dienst für dauerhaften GPS-Empfang |
|
||
| `FOREGROUND_SERVICE_LOCATION` | Standorttyp für Vordergrund-Dienst (Android 14+) |
|
||
| `POST_NOTIFICATIONS` | Dauerhafte Benachrichtigung während des Dienstbetriebs (Android 13+) |
|
||
| `READ_MEDIA_AUDIO` | Zugriff auf Audiodateien aus dem Medienspeicher (Android 13+) |
|
||
| `READ_EXTERNAL_STORAGE` | Zugriff auf Audiodateien (Android ≤ 12) |
|
||
| `WAKE_LOCK` | CPU aktiv halten während der Audiowiedergabe |
|
||
| `INTERNET` | Kartenkacheln von OpenStreetMap laden (osmdroid) |
|
||
| `ACCESS_NETWORK_STATE` | Netzwerkstatus für Kachel-Cache-Entscheidungen |
|
||
| `RECORD_AUDIO` | Mikrofon für Live/PTT-Funktion |
|
||
| `FOREGROUND_SERVICE_MICROPHONE` | Vordergrund-Dienst mit Mikrofon-Typ (Android 14+) |
|
||
|
||
### Wichtige Hinweise zu Mikrofon-Berechtigung (Live / PTT)
|
||
|
||
Die `RECORD_AUDIO`-Berechtigung wird **erst beim ersten Tippen des PTT-Buttons** angefordert (Laufzeit-Permission). Wenn die Berechtigung verweigert wird, erscheint ein Hinweis in der PTT-Karte; der Rest der App funktioniert uneingeschränkt weiter.
|
||
|
||
Die Berechtigung kann jederzeit in den **App-Einstellungen → Berechtigungen → Mikrofon** nachträglich erteilt werden.
|
||
|
||
### Wichtige Hinweise zu Hintergrundstandort
|
||
|
||
Ab **Android 10 (API 29)** muss `ACCESS_BACKGROUND_LOCATION` **separat** nach der Gewährung von `ACCESS_FINE_LOCATION` angefragt werden. Android leitet den Benutzer dazu automatisch zu den App-Einstellungen. Dort muss „Immer" (nicht nur „Bei Nutzung der App") gewählt werden.
|
||
|
||
Ab **Android 11 (API 30)** wird der Hintergrundstandort **nicht** mehr im Systemdialog genehmigt – der Benutzer muss explizit die App-Einstellungen öffnen.
|
||
|
||
---
|
||
|
||
## Bedienung
|
||
|
||
### Grundfunktionen
|
||
|
||
1. **App starten** → Berechtigungen erlauben
|
||
2. **Wegpunkt anlegen**: Auf `+`-Button tippen → Name, Koordinaten, Radius und Audiodatei eingeben → Speichern
|
||
3. **Koordinaten ermitteln**: Latitude/Longitude in Dezimalgrad eingeben (z. B. `48.137154` / `11.576124` für München Marienplatz)
|
||
4. **Audiodatei wählen**: Auf „Audiodatei auswählen" tippen → Datei-Manager öffnet sich → MP3/WAV/OGG auswählen
|
||
5. **Dienst starten**: Auf ▶-Button in der Titelleiste tippen → grüne Statusleiste unten erscheint
|
||
6. **Hintergrund**: App kann geschlossen werden; der Dienst läuft weiter und zeigt eine Benachrichtigung
|
||
7. **Wegpunkt betreten**: Wenn Gerät in den eingestellten Radius kommt → Ton wird abgespielt, Benachrichtigung aktualisiert
|
||
8. **Dienst stoppen**: Auf ■-Button tippen oder App-Benachrichtigung entfernen
|
||
|
||
### Wegpunkt aus aktuellem GPS-Standort erstellen
|
||
|
||
1. Auf den **📍-Button** (kleiner FAB) neben dem +-Button tippen
|
||
2. Die App ermittelt die aktuelle GPS-Position via FusedLocationProviderClient
|
||
3. Der Bearbeitungsdialog öffnet sich mit vorausgefüllten Koordinaten
|
||
4. Name, Radius und Audiodatei eingeben → Speichern
|
||
|
||
**Hinweis**: Dazu muss `ACCESS_FINE_LOCATION` erteilt sein und GPS aktiviert sein. Ist kein frischer Standort verfügbar, wird auf `lastKnownLocation` zurückgegriffen. Fehlt auch dieser, erscheint eine Fehlermeldung.
|
||
|
||
### JSON Import & Export
|
||
|
||
Import und Export erfolgen über das **Overflow-Menü (⋮)** in der Titelleiste.
|
||
|
||
#### Export (JSON)
|
||
- Menü → „Als JSON exportieren"
|
||
- Systemdateiauswahl öffnet sich → Speicherort und Dateiname wählen
|
||
- Alle Wegpunkte werden als JSON-Array gespeichert, inkl. ID, Name, Koordinaten, Radius und Sound-Name
|
||
|
||
#### Import (JSON)
|
||
- Menü → „JSON importieren"
|
||
- Systemdateiauswahl öffnet sich → JSON-Datei auswählen
|
||
- **Achtung**: Die bestehende Wegpunktliste wird durch die importierten Daten **ersetzt**
|
||
- Audiodatei-URIs werden mitimportiert, sind aber gerätegebunden (content:// URIs)
|
||
|
||
**JSON-Format:**
|
||
```json
|
||
[
|
||
{
|
||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||
"name": "Marienplatz München",
|
||
"latitude": 48.137154,
|
||
"longitude": 11.576124,
|
||
"radiusMeters": 50.0,
|
||
"soundUri": "",
|
||
"soundName": "",
|
||
"isActive": true
|
||
}
|
||
]
|
||
```
|
||
|
||
### GPX Import & Export
|
||
|
||
#### Export (GPX 1.1)
|
||
- Menü → „Als GPX exportieren"
|
||
- Systemdateiauswahl öffnet sich → Speicherort und Dateiname wählen
|
||
- Erzeugt valides GPX 1.1 mit `<wpt lat="..." lon="...">`, `<name>`, `<desc>` und `<extensions>`
|
||
|
||
**GPX-Struktur:**
|
||
```xml
|
||
<wpt lat="48.137154" lon="11.576124">
|
||
<name>Marienplatz München</name>
|
||
<desc>Radius: 50m</desc>
|
||
<extensions>
|
||
<wpa:id>550e8400-...</wpa:id>
|
||
<wpa:radius>50.0</wpa:radius>
|
||
<wpa:isActive>true</wpa:isActive>
|
||
</extensions>
|
||
</wpt>
|
||
```
|
||
|
||
#### Import (GPX)
|
||
- Menü → „GPX importieren"
|
||
- GPX-Dateien anderer Apps werden unterstützt; fehlende Felder erhalten Standardwerte:
|
||
- **Radius**: 50 m (wenn kein `<wpa:radius>` vorhanden)
|
||
- **Sound**: keiner (Audiodatei-URIs sind nicht übertragbar)
|
||
- **Name**: „Wegpunkt N" (wenn kein `<name>` vorhanden)
|
||
- `<wpa:>`-Erweiterungen ermöglichen verlustfreien Round-Trip (Export → Import in dieselbe App)
|
||
- **Achtung**: Die bestehende Wegpunktliste wird **ersetzt**
|
||
|
||
### Kartenansicht
|
||
|
||
1. Auf das **Karten-Symbol** (🗺) in der Titelleiste tippen
|
||
2. OpenStreetMap-Karte lädt mit allen Wegpunkten als Marker
|
||
3. Radius jedes Wegpunkts wird als halbtransparenter Kreis angezeigt
|
||
4. Inaktive Wegpunkte erscheinen transparent
|
||
5. Auf den **Standort-FAB** (MyLocation-Symbol, rechts unten) tippen → Karte zentriert auf den aktuellen GPS-Standort; ein moderner blauer Standort-Puck erscheint
|
||
6. Nach Positionsermittlung erscheint oben ein Koordinatenband und der Button **„Als Wegpunkt übernehmen“** (erweiterter FAB links vom Standort-FAB)
|
||
7. **„Als Wegpunkt übernehmen“** antippen → Wegpunkt-Dialog mit vorausgefüllten Koordinaten → Name, Radius und Audiodatei eingeben → Speichern
|
||
8. Zurück-Pfeil → zurück zur Liste
|
||
|
||
**Kurzanleitung – Wegpunkt aus Kartenposition erstellen:**
|
||
1. Karte öffnen (🗺-Symbol)
|
||
2. Standort-FAB (MyLocation) antippen → Karte zentriert auf aktuelle Position
|
||
3. **„Als Wegpunkt übernehmen“** antippen → Dialog mit Koordinaten öffnet sich
|
||
4. Name, Radius (Meter) und optional eine Audiodatei eingeben → „Speichern“
|
||
|
||
**Hinweis zu Internet und Kacheln**: Die Karte benötigt eine Internetverbindung für das erstmalige Laden der Kartenkacheln. Geladene Kacheln werden im App-Cache gespeichert und sind anschließend offline verfügbar. Attribution: Kartendaten © OpenStreetMap-Mitwirkende (ODbL), Kacheln © OpenStreetMap (CC BY-SA).
|
||
|
||
---
|
||
|
||
## Abhängigkeiten (neue)
|
||
|
||
| Bibliothek | Version | Zweck |
|
||
|---|---|---|
|
||
| osmdroid-android | 6.1.20 | OpenStreetMap-Kartendarstellung |
|
||
| media3-exoplayer | 1.4.1 | Begleitmusik: lokale Playlists und HTTP(S)-Streams |
|
||
| media3-common | 1.4.1 | Media3-Basisklassen (MediaItem, Player) |
|
||
|
||
Die Karte wird über `AndroidView` in Compose eingebettet. osmdroid verwaltet den Kachel-Cache selbstständig unter `context.cacheDir/osmdroid`.
|
||
|
||
---
|
||
|
||
## Projektstruktur
|
||
|
||
```
|
||
waypoint-audio-guide/
|
||
├── app/
|
||
│ ├── src/main/
|
||
│ │ ├── AndroidManifest.xml
|
||
│ │ ├── kotlin/de/waypointaudio/
|
||
│ │ │ ├── MainActivity.kt # Einstiegspunkt, Berechtigungsmanagement, NavHost
|
||
│ │ │ ├── WaypointApp.kt # Application-Klasse, Notification Channel
|
||
│ │ │ ├── data/
|
||
│ │ │ │ ├── Waypoint.kt # Datenmodell
|
||
│ │ │ │ └── WaypointStore.kt # DataStore + JSON-Persistenz
|
||
│ │ │ ├── io/
|
||
│ │ │ │ └── ImportExportManager.kt # JSON & GPX Import/Export [NEU]
|
||
│ │ │ ├── repository/
|
||
│ │ │ │ └── WaypointRepository.kt # Repository-Abstraktion
|
||
│ │ │ ├── viewmodel/
|
||
│ │ │ │ └── WaypointViewModel.kt # UI-State, Dienst-Steuerung, Import/Export, GPS
|
||
│ │ │ ├── service/
|
||
│ │ │ │ ├── WaypointLocationService.kt # Vordergrund-Dienst, GPS-Loop
|
||
│ │ │ │ ├── AudioPlayer.kt # MediaPlayer-Wrapper (GPS-Dienst)
|
||
│ │ │ │ └── ManualAudioPlayer.kt # Separater Player für manuelle Wiedergabe [NEU]
|
||
│ │ │ └── ui/
|
||
│ │ │ ├── theme/Theme.kt # Material 3 Farbpalette
|
||
│ │ │ ├── WaypointListScreen.kt # Hauptbildschirm (Liste + Overflow-Menü)
|
||
│ │ │ ├── WaypointEditDialog.kt # Anlegen/Bearbeiten-Dialog (GPS-Vorausfüllung)
|
||
│ │ │ ├── MapScreen.kt # Kartenansicht (osmdroid) [NEU]
|
||
│ │ │ └── PermissionScreen.kt # Fehlende Berechtigungen
|
||
│ │ └── res/
|
||
│ │ ├── values/strings.xml # Alle UI-Texte (Deutsch, erweitert)
|
||
│ │ ├── values/themes.xml
|
||
│ │ └── xml/file_paths.xml # FileProvider-Konfiguration
|
||
│ └── build.gradle.kts
|
||
├── gradle/
|
||
│ ├── libs.versions.toml # Version Catalog (osmdroid ergänzt)
|
||
│ └── wrapper/gradle-wrapper.properties
|
||
├── build.gradle.kts
|
||
├── settings.gradle.kts
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## Architektur
|
||
|
||
```
|
||
UI (Compose)
|
||
├── WaypointListScreen (Liste, Overflow-Menü, GPS-FAB)
|
||
│ ↕
|
||
│ WaypointEditDialog (Anlegen/Bearbeiten, GPS-Vorausfüllung)
|
||
└── MapScreen (osmdroid MapView via AndroidView)
|
||
↕
|
||
WaypointViewModel (AndroidViewModel, StateFlow)
|
||
├── importJson / exportJson / importGpx / exportGpx → ImportExportManager
|
||
├── fetchCurrentLocation → FusedLocationProviderClient
|
||
└── startService / stopService
|
||
↕
|
||
WaypointRepository
|
||
↕
|
||
WaypointStore (DataStore Preferences + Gson/JSON)
|
||
|
||
WaypointLocationService (ForegroundService)
|
||
├── FusedLocationProviderClient (GPS-Updates alle 5 s)
|
||
├── WaypointRepository (liest Wegpunkte direkt)
|
||
└── AudioPlayer (MediaPlayer – GPS-triggered)
|
||
|
||
ManualAudioPlayer (ViewModel-owned, UI-driven)
|
||
├── play / pause / stop / release
|
||
└── Unterstützt Pause (Position wird gehalten) + Resume
|
||
|
||
ImportExportManager (Singleton object)
|
||
├── toJson / fromJson (Gson)
|
||
└── toGpx / fromGpx (XmlPullParser / XmlSerializer)
|
||
```
|
||
|
||
---
|
||
|
||
## Abspielregeln & Zeitplan
|
||
|
||
Jeder Wegpunkt kann mit individuellen Abspielregeln konfiguriert werden. Die Einstellungen sind vollständig optional – fehlende Felder entsprechen dem bisherigen Standardverhalten (Ton bei jedem Betreten).
|
||
|
||
### Abspiel-Modi
|
||
|
||
| Modus | Beschreibung |
|
||
|---|---|
|
||
| **Bei jedem erneuten Betreten** (Standard) | Ton wird bei jeder neuen Eintrittserkennung abgespielt. Entspricht dem bisherigen Verhalten. |
|
||
| **Nur einmal** | Ton wird höchstens einmal abgespielt (wenn `playCount == 0`). Danach bleibt der Wegpunkt aktiv, aber stumm. |
|
||
| **Begrenzt oft** | Ton wird maximal N-mal abgespielt. Die Anzahl wird im Feld „Maximale Abspielanzahl" eingestellt. |
|
||
|
||
### Zeitplan
|
||
|
||
Zusätzlich zum Modus kann ein optionaler Zeitplan aktiviert werden. Alle Zeitplan-Felder sind unabhängig voneinander kombinierbar:
|
||
|
||
| Feld | Auswahl | Beschreibung |
|
||
|---|---|---|
|
||
| Start-Datum/Zeit | DatePicker + TimePicker | Frühestes Datum/Uhrzeit, ab dem Abspielen erlaubt ist |
|
||
| Ende-Datum/Zeit | DatePicker + TimePicker | Spätestes Datum/Uhrzeit, bis zu dem Abspielen erlaubt ist |
|
||
| Täglicher Beginn | TimePicker | Uhrzeit, ab der das tägliche Zeitfenster beginnt |
|
||
| Tägliches Ende | TimePicker | Uhrzeit, bis zu der das tägliche Zeitfenster endet |
|
||
|
||
Datum und Uhrzeit werden über die nativen Android-Dialoge (DatePickerDialog / TimePickerDialog) gewählt – keine manuelle Texteingabe erforderlich. Gewählte Werte werden im Format `TT.MM.JJJJ HH:mm` bzw. `HH:mm` angezeigt. Jedes Feld kann über die Schaltflächen „Start entfernen", „Ende entfernen" oder „Zeitfenster entfernen" wieder geleert werden.
|
||
|
||
**Logik bei kombinierten Feldern:**
|
||
- Alle gesetzten Bedingungen müssen gleichzeitig erfüllt sein (UND-Verknüpfung).
|
||
- Nicht gesetzte Felder werden ignoriert (keine Einschränkung).
|
||
- Tägliche Zeitfenster, die über Mitternacht gehen (z. B. 22:00–06:00), werden korrekt unterstützt.
|
||
|
||
### Beispiele
|
||
|
||
**Nur einmal abspielen:**
|
||
- Modus: „Nur einmal"
|
||
- Kein Zeitplan nötig
|
||
- Ergebnis: Ton ertönt beim ersten Betreten, danach nie wieder
|
||
|
||
**Während einer Veranstaltung abspielen (Datum-Fenster):**
|
||
- Modus: „Bei jedem erneuten Betreten"
|
||
- Zeitplan aktivieren
|
||
- Start per DatePicker + TimePicker wählen: 01.06.2025 09:00, Ende: 01.06.2025 18:00
|
||
- Ergebnis: Ton ertönt nur am 1. Juni 2025 zwischen 9 und 18 Uhr
|
||
|
||
**Werktags morgens abspielen (tägliches Fenster):**
|
||
- Modus: „Bei jedem erneuten Betreten"
|
||
- Zeitplan aktivieren
|
||
- Täglicher Beginn per TimePicker wählen: 07:00, Tägliches Ende: 09:00
|
||
- Ergebnis: Ton ertönt täglich nur zwischen 7 und 9 Uhr (unabhängig vom Datum)
|
||
|
||
**Begrenzte Anzahl + Nächtliches Zeitfenster:**
|
||
- Modus: „Begrenzt oft", maximale Anzahl: 3
|
||
- Täglicher Beginn per TimePicker: 22:00, Tägliches Ende: 06:00 (Mitternachts-übergreifend)
|
||
- Ergebnis: Ton ertönt nachts bis zu 3-mal insgesamt
|
||
|
||
### Abspielzähler
|
||
|
||
Der „bisher abgespielt"-Zähler (`playCount`) wird nach jeder erfolgreichen Wiedergabe automatisch erhöht und persistent gespeichert. Im Bearbeitungsdialog kann der Zähler per Knopf „Zähler zurücksetzen" auf 0 gesetzt werden. Beim Wechsel des Modus bleibt der Zähler erhalten (wird nicht automatisch zurückgesetzt), damit historische Daten nicht verloren gehen.
|
||
|
||
### Darstellung in der Liste
|
||
|
||
Jede Wegpunktkarte in der Liste zeigt eine kompakte Zusammenfassung der Abspielregel, z. B.:
|
||
- `Abspielen: nur einmal · 0/1 gespielt`
|
||
- `Abspielen: max. 3× · 1/3 gespielt`
|
||
- `Abspielen: bei jedem Betreten · Zeitplan aktiv`
|
||
|
||
### JSON/GPX-Kompatibilität
|
||
|
||
- **JSON-Export/-Import**: Alle neuen Felder werden automatisch serialisiert. Ältere JSON-Dateien ohne diese Felder werden durch Kotlin-Standardwerte korrekt ergänzt (backward-kompatibel).
|
||
- **GPX-Export/-Import**: Alle Abspielregel-Felder werden als `<wpa:...>`-Erweiterungen in `<extensions>` gespeichert (Round-Trip-fähig). Andere GPX-Apps ignorieren diese Erweiterungen. Beim GPX-Import fehlt die `soundUri` immer (content:// URIs sind gerätegebunden); die Audiodatei muss neu zugeordnet werden.
|
||
|
||
### Einschränkungen
|
||
|
||
- Zeitplan-Bedingungen werden nur beim **Eintrittsereignis** geprüft, nicht während des Aufenthalts im Radius.
|
||
- Alle Zeitangaben werden in Geräte-Ortszeit interpretiert (keine Zeitzonenauswahl möglich).
|
||
- Der Zähler `playCount` bleibt beim Löschen und Neuanlegen desselben Wegpunkts (mit identischer UUID) erhalten, da er Bestandteil der JSON-Persistenz ist.
|
||
|
||
---
|
||
|
||
## Einschränkungen
|
||
|
||
- **GMS-Abhängigkeit**: `FusedLocationProviderClient` erfordert Google Play Services. Auf AOSP/GrapheneOS-Geräten ohne GMS müsste `LocationManager` als Fallback implementiert werden.
|
||
- **Karteninternet**: Die osmdroid-Karte benötigt beim ersten Start eine Internetverbindung zum Laden der Kacheln. Danach sind gecachte Kacheln offline verfügbar.
|
||
- **OpenStreetMap-Attribution**: Pflichtgemäß muss die Karte mit „© OpenStreetMap-Mitwirkende" beschriftet sein (ODbL-Lizenz). Die App zeigt dies im `CompassOverlay` und im README.
|
||
- **Audiodatei-URIs beim Import**: `content://`-URIs sind gerätegebunden und können nicht zwischen Geräten übertragen werden. Beim GPX/JSON-Import auf einem anderen Gerät muss die Audiodatei neu zugeordnet werden.
|
||
- **GPX-Sound**: Der GPX-Standard hat kein natives Feld für Audiodateien. Die App nutzt den eigenen Namespace `<wpa:soundName>` in `<extensions>`. Andere GPX-Apps ignorieren dieses Feld.
|
||
- **Einmaliger Auslöser**: Der Ton wird nur einmal pro Eintritt in den Radius abgespielt (nicht wiederholt, solange man im Radius bleibt).
|
||
- **Hintergrundstandort**: Auf Android 11+ muss der Benutzer die Berechtigung manuell in den App-Einstellungen erteilen.
|
||
- **Akku-Optimierung**: Aggressive Akku-Optimierung des Herstellers (Huawei EMUI, Xiaomi MIUI) kann den Dienst trotz Vordergrundstatus beenden.
|
||
- **Audiodateiberechtigungen**: Die App sichert `persistableUriPermission` für ausgewählte Audiodateien. Nach einem Neustart des Geräts kann in seltenen Fällen der Systemdateimanager die URI-Berechtigung widerrufen.
|
||
- **Gradle-Build im CI ohne SDK**: Kann ohne installiertes Android SDK nicht kompiliert werden. Der Quellcode ist vollständig; ein lokales Android Studio Build ist erforderlich.
|
||
- **Kartenradius-Kreis**: Der Radius-Kreis auf der Karte ist eine Polygon-Annäherung (64-Eck), keine exakte geodätische Berechnung. Bei kleinen Radien (< 500 m) ist der Unterschied vernachlässigbar.
|
||
|
||
---
|
||
|
||
## Technologien
|
||
|
||
| Technologie | Verwendung |
|
||
|---|---|
|
||
| Kotlin 2.0 | Primäre Sprache |
|
||
| Jetpack Compose | UI-Framework |
|
||
| Material Design 3 | Design-System |
|
||
| Jetpack DataStore | Lokale Datenpersistenz |
|
||
| Gson | JSON-Serialisierung |
|
||
| FusedLocationProviderClient | GPS-Standortabrufe |
|
||
| Android ForegroundService | Hintergrundbetrieb |
|
||
| MediaPlayer | Wegpunkt-Audiowiedergabe (Service) |
|
||
| ExoPlayer / AndroidX Media3 1.4.1 | Begleitmusik (lokale Playlist + HTTP-Streams) |
|
||
| Kotlin Coroutines + Flow | Reaktive Datenschicht |
|
||
| ViewModel + AndroidViewModel | UI-State-Management |
|
||
| Navigation Compose | In-App-Navigation (Liste ↔ Karte) |
|
||
| osmdroid 6.1.20 | OpenStreetMap-Kartenansicht |
|
||
| XmlPullParser / XmlSerializer | GPX 1.1 Parsing und Erzeugung |
|
||
|
||
---
|
||
|
||
## Entwickler
|
||
|
||
| | |
|
||
|---|---|
|
||
| **App-Name** | GPS2Audio |
|
||
| **Name** | Marcel Mayer |
|
||
| **E-Mail** | marcel.mayer@nesohub.org |
|
||
| **Matrix** | [@neso:nesohub.org](https://matrix.to/#/@neso:nesohub.org) – QR-Code & direkter Link im Info-Dialog |
|
||
|
||
### Matrix-Kontakt
|
||
|
||
Die Info-Seite der App enthält sowohl einen **QR-Code** als auch einen **klickbaren Button „Matrix-Chat öffnen"** für die direkte Kontaktaufnahme über Matrix.
|
||
|
||
- **Matrix-ID:** `@neso:nesohub.org`
|
||
- **Direktlink:** [https://matrix.to/#/@neso:nesohub.org](https://matrix.to/#/@neso:nesohub.org)
|
||
|
||
Den Abschnitt erreicht man über das Overflow-Menü (⋮) → „Über diese App" → Abschnitt „Matrix-Kontakt". Ein Tipp auf den Button öffnet den Matrix-Chat direkt in einer installierten Matrix-App oder im Browser.
|
||
|
||
---
|
||
|
||
## Lizenz
|
||
|
||
Dieses Projekt steht unter der **Apache License 2.0**.
|
||
|
||
Diese App ist Open Source und wird unter der Apache License 2.0 veröffentlicht. Nutzung, Veränderung, Forks und Weitergabe sind unter den Bedingungen dieser Lizenz erlaubt. Copyright- und Lizenzhinweise müssen erhalten bleiben. Die Software wird ohne Gewährleistung bereitgestellt.
|
||
|
||
Vollständiger Lizenztext: [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
|
||
|
||
Siehe auch die Datei [LICENSE](./LICENSE) im Projektverzeichnis.
|
||
|
||
Copyright 2026 Marcel Mayer
|
||
|
||
Kartendaten © [OpenStreetMap](https://www.openstreetmap.org/copyright)-Mitwirkende, verfügbar unter der Open Database Licence (ODbL).
|
||
|
||
---
|
||
|
||
## Fehlerbehebung (Troubleshooting)
|
||
|
||
### GPS-Button funktioniert nicht / „Position kann nicht bestimmt werden"
|
||
|
||
**Symptom:** Der 📍-Button (kleiner FAB) reagiert nicht oder es erscheint eine Fehlermeldung.
|
||
|
||
#### Checkliste
|
||
|
||
1. **Standortberechtigung erteilen**
|
||
- Einstellungen → Apps → GPS2Audio → Berechtigungen → Standort
|
||
- Wählen Sie **„Genauer Standort"** (ACCESS_FINE_LOCATION) oder mindestens **„Ungefährer Standort"**
|
||
- **Nicht** „Verweigern" – ohne Standortberechtigung kann die Position nicht ermittelt werden
|
||
|
||
2. **GPS-Dienst aktivieren**
|
||
- Schnelleinstellungen (von oben wischen) → Standort-Symbol einschalten
|
||
- **oder:** Einstellungen → Standort → Standort aktivieren
|
||
- Modus: **„Hohe Genauigkeit"** (GPS + WLAN + Mobilfunk) empfohlen
|
||
|
||
3. **Im Freien testen**
|
||
- GPS-Signale werden in Gebäuden oft nicht empfangen
|
||
- Beim ersten Start kann es 30–60 Sekunden dauern, bis ein GPS-Fix vorhanden ist
|
||
- Im Freien mit freier Sicht zum Himmel ist die Positionsermittlung am schnellsten
|
||
|
||
4. **Akku-Optimierung deaktivieren** (bei ausbleibender Reaktion)
|
||
- Einstellungen → Apps → GPS2Audio → Akku → **„Nicht optimieren"** oder **„Unbeschränkt"**
|
||
- Hersteller-spezifisch: Huawei (EMUI), Xiaomi (MIUI), Samsung (One UI) schränken GPS im Hintergrund aggressiv ein
|
||
|
||
5. **Android-Standorteinstellungen prüfen**
|
||
- Einstellungen → Standort → App-Berechtigungen → GPS2Audio → **„Bei Nutzung der App"** auswählen
|
||
- Für Hintergrundbetrieb (Dienst): **„Immer"** auswählen (Android 10+)
|
||
|
||
6. **Mock-Standort im Emulator setzen** (für Entwickler/Tests)
|
||
- Android Emulator: Extended Controls (…) → Location → Koordinaten eingeben → „Send"
|
||
- z. B. München: Latitude `48.137154`, Longitude `11.576124`
|
||
- Oder per `adb shell geo fix <Längengrad> <Breitengrad>`
|
||
|
||
#### Fehlermeldungen und Bedeutung
|
||
|
||
| Fehlermeldung | Ursache | Lösung |
|
||
|---|---|---|
|
||
| „Standortberechtigung fehlt" | App hat keine Location-Berechtigung | Berechtigung in App-Einstellungen erteilen |
|
||
| „GPS ist deaktiviert" | Standortdienst im System ausgeschaltet | GPS in Systemeinstellungen aktivieren |
|
||
| „GPS-Position konnte nicht ermittelt werden" | Kein GPS-Empfang (Innenbereich) | Im Freien versuchen, warten bis GPS-Fix |
|
||
| „Standortfehler: …" | Google Play Services nicht verfügbar | Gerät mit Google Play Services verwenden |
|
||
|
||
---
|
||
|
||
### Karte wird angezeigt, aber Position ist unbekannt
|
||
|
||
- Der Karten-FAB (📍 rechts unten) holt den aktuellen Standort und zentriert die Karte
|
||
- Ohne GPS-Berechtigung → Karte zeigt den ersten Wegpunkt (oder Deutschlandmitte)
|
||
- Stellen Sie sicher, dass Standortberechtigung vorhanden und GPS aktiviert ist
|
||
|
||
---
|
||
|
||
### Koordinaten-Dezimaltrennzeichen: Komma statt Punkt
|
||
|
||
**Symptom:** Beim Öffnen des Wegpunkt-Dialogs via GPS-Button oder Kartenansicht erscheinen die vorausgefüllten Koordinaten mit Komma als Dezimaltrennzeichen (z. B. `48,137154`), und das Speichern schlägt fehl.
|
||
|
||
**Ursache:** Auf deutschsprachigen Geräten kann die Standard-Gebietsschema-Formatierung des Android-Systems Kommas anstelle von Punkten als Dezimaltrennzeichen in Gleitkommazahlen verwenden.
|
||
|
||
**Lösung (ab dieser Version behoben):** Die App formatiert GPS-Koordinaten jetzt immer mit `Locale.US` (Punkt als Dezimaltrennzeichen, z. B. `48.1371540`). Außerdem werden beim Speichern Kommas in den Eingabefeldern automatisch durch Punkte ersetzt, sodass manuelle Eingaben im deutschen Format (z. B. `52,123456`) ebenfalls akzeptiert werden.
|
||
|
||
**Koordinaten-Eingabeformat:**
|
||
- Empfohlen: Punkt als Dezimaltrennzeichen, z. B. `48.137154` / `11.576124`
|
||
- Alternativ: Komma wird ebenfalls akzeptiert, z. B. `48,137154` / `11,576124`
|
||
|
||
---
|
||
|
||
### Berechtigungen wurden versehentlich verweigert
|
||
|
||
1. Einstellungen → Apps → GPS2Audio → Berechtigungen
|
||
2. Standort → **„Genauer Standort"** aktivieren
|
||
3. Benachrichtigungen → aktivieren (für Dienst-Benachrichtigung)
|
||
4. Mediendateien/Audio → aktivieren (für Audiodatei-Auswahl)
|
||
5. App neu starten
|
||
|
||
---
|
||
|
||
### Hintergrund-Dienst erkennt keine Wegpunkte
|
||
|
||
- Prüfen Sie, ob der Dienst gestartet ist (▶-Button in der Titelleiste → grüne Statusleiste)
|
||
- Standortberechtigung muss **„Immer"** sein (nicht nur „Bei Nutzung")
|
||
- Akku-Optimierung für die App deaktivieren
|
||
- Gerät nicht in den Flugmodus versetzen
|
||
|
||
---
|
||
|
||
## Touren / Routen
|
||
|
||
### Überblick
|
||
|
||
Wegpunkte können in **Touren** (Routen) organisiert werden. Jede Tour erscheint als **Tab/Reiter** am oberen Rand der Hauptliste. Die Kartenansicht zeigt ebenfalls nur die Wegpunkte der aktuell gewählten Tour.
|
||
|
||
### Neue Tour erstellen
|
||
|
||
1. Overflow-Menü **(⋮)** in der Titelleiste öffnen
|
||
2. **„Neue Tour"** antippen
|
||
3. Namen frei eingeben (z. B. „Stadtführung Nürnberg" oder „Wanderung Zugspitze") → **Speichern**
|
||
4. Die neue Tour erscheint sofort als Tab in der Liste. Leere Touren (ohne Wegpunkte) bleiben erhalten und werden persistent gespeichert.
|
||
|
||
### Wegpunkt einer Tour zuordnen
|
||
|
||
Beim Anlegen oder Bearbeiten eines Wegpunkts befindet sich im Dialog der Abschnitt **„Tour"**:
|
||
|
||
- **Dropdown-Auswahl**: Bereits vorhandene Touren können direkt ausgewählt werden.
|
||
- **Freie Texteingabe**: Ein neuer Tourname kann direkt eingetippt werden. Ist der Name noch nicht vorhanden, wird er beim Speichern automatisch zur Tourliste hinzugefügt.
|
||
- **Leer lassen**: Bleibt das Feld leer, wird der Wegpunkt der **Standardtour** zugeordnet.
|
||
- **Neue Wegpunkte (GPS-FAB)**: Beim Erstellen eines Wegpunkts aus dem aktuellen GPS-Standort oder über die Kartenansicht wird die aktuell gewählte Tour automatisch vorausgefüllt.
|
||
|
||
### Tour wechseln (Tab-Navigation)
|
||
|
||
- Tippe auf einen **Tab** in der Tab-Leiste, um zu einer anderen Tour zu wechseln.
|
||
- Die Wegpunktliste zeigt dann nur die Wegpunkte dieser Tour.
|
||
- Auch die **Kartenansicht** zeigt nur die Wegpunkte der aktuell gewählten Tour (der Tourname ist in der Titelleiste der Karte sichtbar).
|
||
|
||
### Tour umbenennen
|
||
|
||
1. Zur gewünschten Tour wechseln (Tab antippen)
|
||
2. Overflow-Menü **(⋮)** → **„Tour umbenennen"**
|
||
3. Neuen Namen eingeben → **Speichern**
|
||
4. Alle Wegpunkte dieser Tour werden automatisch umbenannt.
|
||
|
||
### Tour löschen
|
||
|
||
1. Zur gewünschten Tour wechseln
|
||
2. Overflow-Menü **(⋮)** → **„Tour löschen“**
|
||
3. Den Sicherheitsdialog bestätigen: Alle Wegpunkte der Tour werden in die **Standardtour** verschoben.
|
||
4. Die UI wechselt sofort zur nächsten verfügbaren Tour – kein App-Neustart nötig.
|
||
5. Der GPS-Track der gelöschten Tour wird ebenfalls entfernt.
|
||
|
||
**Standardtour**: Der Menüpunkt „Tour löschen“ ist deaktiviert (ausgegraut), wenn die Standardtour ausgewählt ist. Die Standardtour kann nicht gelöscht werden.
|
||
|
||
---
|
||
|
||
## Manuelle Wiedergabe
|
||
|
||
Die App bietet zwei Möglichkeiten zur manuellen Audiowiedergabe ohne GPS-Dienst:
|
||
|
||
---
|
||
|
||
### 1. Einzel-Wiedergabe je Wegpunkt (per Karten-Schaltfläche)
|
||
|
||
Jede Wegpunktkarte in der Hauptliste zeigt – sofern eine Audiodatei zugeordnet ist – eine **▶◉ Abspielen**-Schaltfläche direkt auf der Karte.
|
||
|
||
**Verhalten:**
|
||
|
||
- Tippt man auf die Schaltfläche, spielt **nur diese eine Datei** ab und stoppt danach automatisch.
|
||
Die Warteschlange wird **nicht** fortgesetzt – es wird kein weiterer Wegpunkt geladen.
|
||
- Ist derselbe Wegpunkt bereits aktiv, wechselt die Schaltfläche zu **⏸ Pause**; erneutes Tippen pausiert / setzt fort.
|
||
- Tippt man auf einen anderen Wegpunkt während einer Einzel-Wiedergabe läuft, wird die vorherige sofort gestoppt und die neue gestartet.
|
||
- Läuft die globale Wiedergabeleiste (Playlist-Modus), wird diese beim Start einer Einzel-Wiedergabe gestoppt.
|
||
- Hat ein Wegpunkt **keine Audiodatei**, erscheint stattdessen ein deaktiviertes `🔇`-Symbol mit dem Hinweis „Keine Audiodatei zugewiesen“.
|
||
- Die aktive Karte wird farblich hervorgehoben (primäre Hintergrundfarbe + Rahmen), damit sofort erkennbar ist, welcher Wegpunkt spielt.
|
||
|
||
**Begleitmusik (Atmo):**
|
||
Das konfigurierte Atmo-Verhalten (Pause & Resume, Fade, Duck, Parallel) wird auch bei der Einzel-Wiedergabe angewendet. Die Atmo-Rückkehr erfolgt erst nach dem natürlichen Abschluss der Datei.
|
||
|
||
**Einzel-Wiedergabe ist auch über die Karte verfügbar** – beim Antippen eines Markers erscheint (wenn Audiodatei vorhanden) ein `▶◉ Diesen Wegpunkt abspielen`-Knopf im Aktionsdialog.
|
||
|
||
---
|
||
|
||
### 2. Playlist-Modus (globale Wiedergabeleiste)
|
||
|
||
Am unteren Rand der Hauptübersicht befindet sich eine **Wiedergabeleiste** für die manuelle Steuerung ohne aktiven GPS-Dienst.
|
||
|
||
#### Bedienung
|
||
|
||
| Schaltfläche | Funktion |
|
||
|---|---|
|
||
| ⏮ Zurück | Springt zum vorherigen Wegpunkt der aktuellen Tour und startet die Wiedergabe |
|
||
| ▶/⏸ Play/Pause | Startet die Wiedergabe des ausgewählten Wegpunkts oder pausiert die laufende Wiedergabe |
|
||
| ⏭ Weiter | Springt zum nächsten Wegpunkt der aktuellen Tour und startet die Wiedergabe |
|
||
|
||
> **Hinweis:** Während eine Einzel-Wiedergabe (Modus 1) aktiv ist, werden ⏮ Zurück und ⏭ Weiter in der Leiste **deaktiviert** (ausgegraut), da Einzel-Wiedergabe keine Queue-Fortsetzung kennt. Nur der Play/Pause-Knopf bleibt aktiv. Beim Betätigen von Play/Pause in der Leiste während Einzel-Modus: die Einzel-Wiedergabe wird gestoppt und der Playlist-Modus übernimmt.
|
||
|
||
#### Wiedergabeliste
|
||
|
||
Die Wiedergabeliste besteht aus allen **aktiven** Wegpunkten der aktuell gewählten Tour, die eine **Audiodatei** zugeordnet haben (in Listenreihenfolge).
|
||
|
||
- Wenn kein Wegpunkt mit Audiodatei vorhanden ist, sind die Schaltflächen deaktiviert und es wird ein Hinweis angezeigt.
|
||
- Der Name des aktuell geladenen Wegpunkts wird über den Schaltflächen angezeigt: `Manuell: <Name>` (Playlist) bzw. `Einzelwiedergabe: <Name>` (Einzel-Modus).
|
||
- Pause hält die Wiedergabe an der aktuellen Position; Play setzt sie fort.
|
||
- Der manuelle Player ist vom GPS-Hintergrunddienst getrennt und beeinflusst diesen nicht.
|
||
- Beim Wechsel der Tour wird die manuelle Wiedergabe gestoppt.
|
||
|
||
### Hintergrunddienst und Touren
|
||
|
||
Der GPS-Hintergrundddienst überwacht **alle aktiven Wegpunkte aller Touren** gleichzeitig. Die Tour-Auswahl wirkt sich nur auf die Listenansicht und Kartenansicht aus – das Abspielen von Audiodateien beim Betreten eines Radius funktioniert tourunabhängig.
|
||
|
||
### Import / Export mit Touren
|
||
|
||
- **JSON-Export/-Import**: Das Feld `tourName` wird automatisch mit serialisiert. Ältere JSON-Dateien ohne `tourName` erhalten beim Import automatisch den Wert „Standard" (rückwärtskompatibel).
|
||
- **GPX-Export**: `tourName` wird als `<wpa:tourName>` in den `<extensions>` gespeichert.
|
||
- **GPX-Import**: `<wpa:tourName>` wird beim Import übernommen. Fehlt das Feld, wird „Standard" verwendet. Importierte Touren werden automatisch zur Tourliste hinzugefügt.
|
||
|
||
### Kartenansicht und Touren
|
||
|
||
Die Kartenansicht zeigt immer nur die Wegpunkte der aktuell in der Listenansicht gewählten Tour. Der Tourname ist in der Titelleiste der Karte sichtbar, wenn mehr als eine Tour vorhanden ist.
|
||
|
||
**Hinweis**: Neue Wegpunkte, die über den FAB „Als Wegpunkt übernehmen" in der Karte angelegt werden, erhalten automatisch die aktuell gewählte Tour.
|
||
|
||
### MVP-Einschränkungen (Touren)
|
||
|
||
- **Reihenfolge**: Touren werden in der Reihenfolge der Erstellung angezeigt; eine manuelle Umsortierung ist noch nicht möglich.
|
||
- **Löschen der Standardtour**: Die Tour „Standard" kann nicht gelöscht werden.
|
||
- **Dienst**: Der Hintergrunddienst überwacht alle Touren (nicht nur die gewählte). Dies ist gewollt, damit keine aktiven Wegpunkte versehentlich stumm geschaltet werden.
|
||
|
||
---
|
||
|
||
## Begleitmusik (Atmo)
|
||
|
||
GPS2Audio unterstützt optionale **Begleitmusik** (Hintergrundmusik) pro Tour. Die Musik läuft während der Tour im Hintergrund und reagiert automatisch auf Wegpunkt-Audio-Ereignisse.
|
||
|
||
> **Hinweis:** Das Begleitmusik-Panel erscheint auf der Hauptseite unter dem Titel **„Atmo“** – die interne Bezeichnung lautet weiterhin Begleitmusik.
|
||
|
||
### Atmo Mini-Player (Begleitmusik)
|
||
|
||
Die Begleitmusik-Steuerung ist als kompakter **„Atmo“-Mini-Player** direkt in der Hauptübersicht sichtbar – unterhalb des Abschnitts „Wegpunkt-Tracks“ und oberhalb der manuellen Wiedergabeleiste.
|
||
|
||
#### Anzeige-Elemente
|
||
|
||
| Element | Beschreibung |
|
||
|---|---|
|
||
| **Titel** | Name des aktuell abgespielten Tracks (aus displayName der Playlist oder Stream-URL) |
|
||
| **Track-Badge** | Position in der Playlist (z. B. „2 / 5") oder „Stream" für Radio/Internet-Streams |
|
||
| **Fortschrittsbalken** | `LinearProgressIndicator` mit verstrichener / Gesamtdauer (nur lokale Dateien mit bekannter Länge) |
|
||
| **Zeitanzeige** | Verstrichene Zeit / Gesamtdauer (z. B. `1:23 / 4:05`) |
|
||
| **Live-Indikator** | Roter Punkt + „Live" für aktive Stream-Wiedergabe (kein Fortschrittsbalken) |
|
||
| **Nächster Titel** | Zeile „Als nächstes: …" für lokale Playlists mit >1 Track |
|
||
| **Verhalten-Badge** | Aktives Wegpunkt-Verhalten (Pause/Fade/Duck/Weiter) |
|
||
| **Autostart-Badge** | Erscheint, wenn „Autostart nach Waypoint" aktiviert ist |
|
||
| **Fehleranzeige** | Konfigurationsfehler oder fehlende Quellen direkt im Panel |
|
||
|
||
#### Steuerung
|
||
|
||
| Schaltfläche | Funktion | Verfügbarkeit |
|
||
|---|---|---|
|
||
| **⏮ Zurück** | Springt zum vorherigen Titel | Nur lokale Playlist mit >1 Track |
|
||
| **▶/⏸ Play/Pause** | Startet oder pausiert die Wiedergabe | Immer (wenn aktiviert & Quelle konfiguriert) |
|
||
| **⏭ Weiter** | Springt zum nächsten Titel | Nur lokale Playlist mit >1 Track |
|
||
| **⏹ Stop** | Stoppt die Wiedergabe und gibt den Player frei | Wenn ein Track geladen ist |
|
||
| **Konfigurieren** | Öffnet den vollständigen Begleitmusik-Dialog | Immer |
|
||
|
||
> **Streams**: Voriger/Nächster-Schaltflächen werden für Streams automatisch deaktiviert (ausgegraut), da Streams keine Playlist-Navigation unterstützen.
|
||
|
||
Das Overflow-Menü **(⋮)** enthält weiterhin den Eintrag „Begleitmusik" als zusätzlichen Zugangspunkt.
|
||
|
||
### Aktivierung
|
||
|
||
1. Im **Begleitmusik-Panel** auf **„Konfigurieren"** tippen (oder Overflow-Menü **(⋮)** → **„Begleitmusik"**)
|
||
2. **„Begleitmusik aktivieren"** einschalten
|
||
3. Musikquelle wählen und Einstellungen speichern
|
||
4. Play-Button im Panel drücken oder Begleitmusik startet automatisch (wenn Autostart aktiv)
|
||
|
||
### Musikquellen
|
||
|
||
#### Lokale Playlist
|
||
|
||
- Tippe auf **„Dateien hinzufügen"** → Systemdateiauswahl öffnet sich
|
||
- Mehrere Audiodateien gleichzeitig auswählbar (MP3, OGG, FLAC, AAC usw.)
|
||
- Ausgewählte Dateien werden mit ihrem Dateinamen in der Playlist angezeigt
|
||
- URI-Berechtigungen werden dauerhaft gesichert (bleiben nach App-Neustart erhalten)
|
||
- Einzelne Dateien können per ✕-Button entfernt werden
|
||
- **„Playlist leeren"** löscht alle Einträge
|
||
- Option **„Zufällige Reihenfolge"** mischt die Playlist beim Abspielen
|
||
- Wiedergabe läuft in Dauerschleife (Repeat All)
|
||
|
||
#### Stream-URL
|
||
|
||
- Direkte **http:// oder https://**-URL zu einem Audio-Stream eingeben
|
||
- Geeignet für: Internetradio-Streams (ICY/Icecast, Shoutcast), direkte MP3-URLs, öffentliche Audio-Streams
|
||
- **Wichtig**: Es muss eine **direkte, abspielbare Audio-URL** sein – keine Webseiten-URL
|
||
- Playback via ExoPlayer (AndroidX Media3) – unterstützt HLS, DASH und klassische HTTP-Streams
|
||
|
||
> **Hinweis zu YouTube, SoundCloud und radio.de:**
|
||
> Diese Plattformen liefern keine direkt abspielbaren Audio-URLs über ihre öffentlichen Links. Eine Standard-YouTube- oder SoundCloud-URL funktioniert nicht als Stream-URL. Stattdessen:
|
||
> - **Internetradio**: Viele Sender veröffentlichen direkte Stream-URLs (z. B. `.mp3`, `.ogg`, `.m3u8`) auf ihrer Website
|
||
> - **radio.de**: Die App-interne Stream-URL (im HTML-Quellcode o. ä.) funktioniert – die Webseiten-URL nicht
|
||
> - **YouTube / SoundCloud**: Inhalte über die jeweilige App oder den Browser abspielen; direkte Integration ist aus rechtlichen und technischen Gründen nicht vorgesehen
|
||
> - Bei Eingabe einer nicht abspielbaren URL zeigt der Player im Logcat einen Fehler; in der App erscheint die Begleitmusik einfach nicht
|
||
|
||
### Verhalten beim Wegpunkt-Audio
|
||
|
||
Vier Modi steuern, was mit der Begleitmusik passiert, wenn ein Wegpunkt-Ton abgespielt wird:
|
||
|
||
| Modus | Beschreibung |
|
||
|---|---|
|
||
| **Pausieren und fortsetzen** (Standard) | Musik wird pausiert, solange der Wegpunkt-Ton läuft. Danach setzt sie an der gleichen Stelle fort. |
|
||
| **Fade-out / Fade-in** | Musik wird sanft ausgeblendet (Fade-out), Wegpunkt spielt, danach sanft eingeblendet (Fade-in). |
|
||
| **Leise unterlegen (Duck)** | Musik wird auf eine reduzierte Lautstärke abgesenkt (konfigurierbar), Wegpunkt spielt parallel. Nach dem Ton wird die Lautstärke wiederhergestellt. |
|
||
| **Normal unterlegen** | Musik läuft auf normaler Lautstärke weiter, Wegpunkt-Ton wird parallel abgespielt. |
|
||
|
||
### Parameter
|
||
|
||
| Parameter | Standard | Beschreibung |
|
||
|---|---|---|
|
||
| Fade-Dauer | 1500 ms | Dauer des Fade-out/Fade-in-Effekts (300–4000 ms, per Schieberegler) |
|
||
| Duck-Lautstärke | 25 % | Lautstärke der Begleitmusik im Duck-Modus (5–50 %, per Schieberegler) |
|
||
|
||
### Nach Waypoint automatisch Begleitmusik starten (Autostart)
|
||
|
||
Im Begleitmusik-Dialog gibt es die Option **„Nach Waypoint automatisch Begleitmusik starten"**:
|
||
|
||
- **Deaktiviert** (Standard): Begleitmusik wird nach einem Wegpunkt-Ton nur dann wieder aufgenommen, wenn sie *vor* dem Wegpunkt bereits spielte. War die Musik gestoppt, bleibt sie nach dem Wegpunkt gestoppt.
|
||
- **Aktiviert**: Nach dem Ende des Wegpunkt-Tons startet die Begleitmusik *immer* – auch wenn sie vorher nicht spielte. Das gilt für manuelle Wiedergabe (`ManualAudioPlayer`) und GPS-ausgelöste Wegpunkte (`WaypointLocationService`).
|
||
|
||
**Zusammenspiel mit den Verhalten-Modi:**
|
||
|
||
| Modus | Autostart aktiv | Verhalten wenn Musik vorher nicht spielte |
|
||
|---|---|---|
|
||
| Pause/Resume | Ja | Musik startet nach dem Waypoint-Ton neu |
|
||
| Fade-out/Fade-in | Ja | Musik startet und blendet sanft ein |
|
||
| Duck | Ja | Musik startet auf normaler Lautstärke |
|
||
| Normal unterlegen | Ja | Musik startet sofort nach dem Waypoint |
|
||
|
||
Das Autostart-Symbol erscheint als **Badge** im sichtbaren Begleitmusik-Panel der Hauptansicht.
|
||
|
||
### Test / Vorschau
|
||
|
||
Der Dialog enthält Steuerungsschaltflächen zum Testen:
|
||
- **Play/Pause** – Begleitmusik direkt im Dialog testen
|
||
- **Stop** – Musik sofort stoppen
|
||
- **⏮ / ⏭** – In der lokalen Playlist vor- und zurückspringen
|
||
|
||
**Tipp**: Einstellungen vor dem Speichern mit Play testen, um sicherzustellen, dass die Quelle abspielbar ist.
|
||
|
||
### Technische Hinweise (Akku & Datenverbrauch)
|
||
|
||
- **Lokale Playlist**: Kein Datenverbrauch. Akku-Verbrauch vergleichbar mit anderen Musik-Apps (~5–15 % pro Stunde, geräteabhängig).
|
||
- **Stream-URL**: Kontinuierliche Mobilfunk-/WLAN-Verbindung erforderlich. Typischer Verbrauch je nach Stream-Qualität: 32–192 kbps (ca. 15–90 MB/Stunde). Bei schlechter Verbindung kann der Stream pausieren oder abbrechen.
|
||
- **ExoPlayer** (Media3) wird erst beim Starten der Begleitmusik initialisiert. Im deaktivierten Zustand (kein Overhead).
|
||
- **Akku-Hinweis**: WLAN-Streaming ist deutlich energieeffizienter als Mobilfunk-Streaming.
|
||
|
||
### Fehlerbehebung: Begleitmusik startet nicht
|
||
|
||
**Symptom:** Die Begleitmusik spielt nicht, obwohl sie aktiviert ist.
|
||
|
||
#### Checkliste
|
||
|
||
1. **Quelle konfiguriert?**
|
||
- Im Begleitmusik-Panel müssen entweder „Lokale Playlist: N Titel“ oder „Stream: …“ angezeigt werden
|
||
- Ist die Anzeige „Keine Quelle konfiguriert“, zuerst Dateien hinzufügen oder URL eingeben und **Speichern** drücken
|
||
|
||
2. **Aktiviert?**
|
||
- Das Begleitmusik-Panel muss den farbigen sekundären Hintergrund zeigen („Begleitmusik aktivieren“ ist EIN)
|
||
- Grauer Hintergrund = nicht aktiviert
|
||
|
||
3. **Play-Button direkt drücken**
|
||
- Im Begleitmusik-Panel auf ▶ drücken (nicht auf den Wegpunkt-Player warten)
|
||
- Erscheint eine Fehlermeldung im roten Banner? → Hinweis befolgen
|
||
|
||
4. **URI-Berechtigungen für lokale Dateien**
|
||
- Dateien müssen über den **Systemdateimanager** innerhalb der App ausgewählt werden
|
||
- Manuell eingetippte Pfade funktionieren nicht
|
||
- URI-Berechtigung wird beim Auswählen automatisch dauerhaft gesichert
|
||
- Nach einem Factory Reset müssen Dateien neu hinzugefügt werden
|
||
|
||
5. **Stream-URL**
|
||
- URL muss mit `http://` oder `https://` beginnen
|
||
- Es muss eine **direkt abspielbare** Audio-URL sein (kein YouTube, kein SoundCloud, keine radio.de-Webseite)
|
||
- URL in einem Browser öffnen und prüfen, ob Audio direkt gestreamt wird
|
||
- Fehler sichtbar im Begleitmusik-Panel-Banner oder im Logcat (`adb logcat -s BackgroundMusicPlayer`)
|
||
|
||
6. **Einstellungen gespeichert?**
|
||
- Nach Änderungen im Dialog immer **„Speichern“** drücken (nicht nur schließen)
|
||
- Beim Schließen ohne Speichern („Abbrechen“) werden Änderungen verworfen
|
||
|
||
7. **Autostart nach Waypoint aktivieren**
|
||
- Wenn die Begleitmusik nur nach Wegpunkten automatisch starten soll: Option **„Nach Waypoint automatisch Begleitmusik starten“** einschalten
|
||
- Ohne diese Option startet die Musik nur, wenn sie vor dem Wegpunkt bereits spielte
|
||
|
||
#### Logcat-Debugging
|
||
|
||
```bash
|
||
# Alle Begleitmusik-Logs anzeigen
|
||
adb logcat -s BackgroundMusicPlayer BackgroundMusicManager
|
||
|
||
# Typische Fehlermeldungen
|
||
# W BackgroundMusicPlayer: Keine abspielbaren Quellen gefunden → URI ungültig oder Playlist leer
|
||
# W BackgroundMusicPlayer: Stream-URL ist keine gültige http/https-URL → URL-Format prüfen
|
||
# E BackgroundMusicPlayer: ExoPlayer Fehler: ... → Datei nicht lesbar oder Stream nicht verfügbar
|
||
```
|
||
|
||
### MVP-Einschränkungen (Begleitmusik)
|
||
|
||
- **Wiederherstellung im GPS-Dienst**: Der `AudioPlayer` des GPS-Hintergrunddienstes (`WaypointLocationService`) unterstützt jetzt `onCompletion`- und `onError`-Callbacks. Die Begleitmusik wird exakt dann wiederhergestellt (Fade-in, Resume, Duck-Restore), wenn der Wegpunkt-Ton natürlich beendet ist oder ein Fehler aufgetreten ist – nicht mehr sofort nach dem Auslösen. Das Verhalten entspricht damit dem der manuellen Wiedergabe (`ManualAudioPlayer`). Der `playCount`-Zähler wird ebenfalls nur bei natürlicher Completion inkrementiert (nicht bei Wiedergabe-Fehlern).
|
||
- **GPS-Dienst und App-Prozess**: Begleitmusik-Player und GPS-Dienst laufen im selben App-Prozess. Wenn der Prozess vom System beendet wird, stoppt auch die Begleitmusik.
|
||
- **Stream-Fehler**: Bei nicht direkt abspielbaren URLs (z. B. YouTube-Links) erscheint ein Fehler-Banner im Begleitmusik-Panel. Im Logcat ist der ExoPlayer-Fehler zusätzlich ersichtlich.
|
||
- **Kein Crossfade**: Beim Wechsel von Playlist-Titeln gibt es kein Überblenden.
|
||
- **Einzel-Instanz**: Nur eine Begleitmusik-Quelle gleichzeitig. Beim Tourwechsel in der App wird die Musik der vorherigen Tour gestoppt und die Einstellungen der neuen Tour geladen.
|
||
|
||
---
|
||
|
||
## Tour-Zähler (Zähler je Tour)
|
||
|
||
GPS2Audio ermöglicht es, den **Abspiel-Zähler und Abspiel-Modus für alle Wegpunkte einer Tour in einem Schritt** zu steuern. Die Funktion erscheint als kompakte **Tour-Zähler-Karte** direkt unterhalb der Tour-Tabs und zeigt auf einen Blick, wie oft Wegpunkte der Tour abgespielt wurden.
|
||
|
||
> **Hinweis:** Die Tour-Zähler-Karte erscheint nur, wenn die aktuelle Tour mindestens einen Wegpunkt enthält.
|
||
|
||
### Tour-Zähler-Karte (Hauptansicht)
|
||
|
||
Zwischen der Tab-Leiste und der Wegpunktliste wird eine kompakte Karte mit Zählerinformationen angezeigt:
|
||
|
||
| Element | Beschreibung |
|
||
|---|---|
|
||
| **Titel** | „Tour-Zähler" |
|
||
| **Zusammenfassung** | Gesamtzahl aller Abspielungen (alle Wegpunkte der Tour) sowie die Anzahl an Wegpunkten mit begrenzen oder einmaligen Abspielregeln |
|
||
| **Schaltfläche „Einstellen"** | Öffnet den Zähler-Dialog für diese Tour |
|
||
|
||
**Beispielausgaben:**
|
||
- `5× abgespielt · 2 begrenzt · 1 einmalig`
|
||
- `Alle Wegpunkte: bei jedem Betreten` (wenn alle Wegpunkte im Standard-Modus sind und noch nicht abgespielt wurden)
|
||
|
||
### Tour-Zähler-Dialog
|
||
|
||
Ein Tipp auf „Einstellen" öffnet den **Zähler-Dialog** mit zwei unabhängigen Aktionsbereichen:
|
||
|
||
#### 1. Zähler zurücksetzen
|
||
|
||
- Schaltfläche: **„Alle Zähler dieser Tour zurücksetzen"**
|
||
- Setzt den `playCount` aller Wegpunkte der aktuellen Tour auf **0**
|
||
- Gilt nur für die aktuelle Tour, andere Touren bleiben unberührt
|
||
- Der Abspiel-Modus (`EVERY_ENTRY`, `ONCE`, `LIMITED_COUNT`) und `maxPlayCount` werden nicht verändert
|
||
|
||
> Nach dem Zurücksetzen können zuvor stumme Wegpunkte (weil Limit erreicht) erneut abgespielt werden.
|
||
|
||
#### 2. Abspiel-Modus für alle Wegpunkte setzen
|
||
|
||
Erlaubt es, den Abspiel-Modus aller Wegpunkte der aktuellen Tour gleichzeitig zu ändern:
|
||
|
||
| Feld | Beschreibung |
|
||
|---|---|
|
||
| **Abspiel-Modus** | Dropdown: „Bei jedem erneuten Betreten" / „Nur einmal" / „Begrenzt oft" |
|
||
| **Maximale Abspielanzahl** | Nur sichtbar bei Modus „Begrenzt oft" – Eingabefeld für eine Zahl ≥ 1 |
|
||
| **Zähler beim Anwenden zurücksetzen** | Checkbox: Setzt `playCount` beim Anwenden auf 0 |
|
||
|
||
Ein Tipp auf **„Auf alle Wegpunkte anwenden"** aktualisiert alle Wegpunkte der Tour:
|
||
- `playbackMode` wird auf den gewählten Modus gesetzt
|
||
- `maxPlayCount` wird gesetzt (bei `LIMITED_COUNT`) oder auf `null` zurückgesetzt
|
||
- `playCount` wird zurückgesetzt, wenn die Checkbox aktiviert war
|
||
|
||
**Modi im Überblick:**
|
||
|
||
| Modus | Wirkung |
|
||
|---|---|
|
||
| **Bei jedem erneuten Betreten** | Alle Wegpunkte spielen bei jedem Betreten – kein Limit |
|
||
| **Nur einmal** | Alle Wegpunkte spielen maximal einmal; `playCount = 0` ist Voraussetzung |
|
||
| **Begrenzt oft** | Alle Wegpunkte spielen maximal N-mal (N wird in der Eingabe festgelegt) |
|
||
|
||
### Welche Wegpunkte sind betroffen?
|
||
|
||
- Die Tour-Zähler-Aktionen betreffen immer **alle Wegpunkte der aktuell gewählten Tour**
|
||
- Die Aktionen gelten für aktive und inaktive Wegpunkte gleichermaßen
|
||
- Wegpunkte anderer Touren werden nicht berührt
|
||
- **Neue Wegpunkte**, die nach der Massen-Aktion angelegt werden, erben den gesetzten Modus **nicht automatisch** – sie erhalten den Standard-Modus (bei jedem Betreten). Für neue Wegpunkte muss der Modus einzeln im Bearbeitungsdialog oder durch erneute Massen-Aktion gesetzt werden.
|
||
|
||
### Typische Anwendungsfälle
|
||
|
||
**Saisonale Tour neu starten:**
|
||
1. Tour-Tab antippen
|
||
2. Tour-Zähler-Karte → „Einstellen"
|
||
3. „Alle Zähler dieser Tour zurücksetzen" → alle Wegpunkte können erneut abgespielt werden
|
||
|
||
**Alle Wegpunkte auf einmaliges Abspielen umstellen (Messeführung):**
|
||
1. Tour-Tab antippen
|
||
2. Tour-Zähler-Dialog öffnen
|
||
3. Modus „Nur einmal" wählen + Checkbox „Zähler beim Anwenden zurücksetzen" aktivieren
|
||
4. „Auf alle Wegpunkte anwenden"
|
||
|
||
**Begrenzte Anzahl für alle setzen (z. B. max. 3×):**
|
||
1. Tour-Tab antippen
|
||
2. Tour-Zähler-Dialog öffnen
|
||
3. Modus „Begrenzt oft", Anzahl `3`, Checkbox „Zähler zurücksetzen" aktivieren
|
||
4. „Auf alle Wegpunkte anwenden"
|
||
|
||
### Verhältnis zu einzelnen Wegpunkt-Einstellungen
|
||
|
||
Die Tour-Zähler-Massen-Aktion **überschreibt** die individuellen Modus-Einstellungen aller Wegpunkte der Tour. Danach können einzelne Wegpunkte über den Bearbeitungsdialog (Bleistift-Symbol) individuell angepasst werden – der per Massen-Aktion gesetzte Modus gilt dann als Ausgangspunkt.
|
||
|
||
### GPX/JSON-Kompatibilität
|
||
|
||
- Die Tour-Zähler-Funktion arbeitet ausschließlich auf den vorhandenen Wegpunkt-Feldern (`playbackMode`, `maxPlayCount`, `playCount`).
|
||
- GPX- und JSON-Import werden durch die Tour-Zähler-Funktion **nicht beeinflusst**.
|
||
- Ein nach dem Import durchgeführtes „Zurücksetzen" oder „Modus anwenden" wirkt auf die soeben importierten Wegpunkte.
|
||
|
||
---
|
||
|
||
## Tour-Abspiel-Vorgaben (Vorgaben für neue Wegpunkte)
|
||
|
||
GPS2Audio merkt sich die zuletzt im Tour-Zähler-Dialog gesetzten Abspielregeln als **Tour-Vorgabe** und wendet sie automatisch auf neu angelegte Wegpunkte an.
|
||
|
||
### So funktioniert es
|
||
|
||
1. **Tour-Zähler-Dialog öffnen**: Tour-Zähler-Karte → „Einstellen"
|
||
2. Gewünschten Abspiel-Modus wählen (z. B. „Nur einmal" oder „Begrenzt oft, max. 3×")
|
||
3. **„Auf alle Wegpunkte anwenden"** tippen
|
||
|
||
Ab diesem Moment gilt die Einstellung als **Tour-Vorgabe**: Alle neu erstellten Wegpunkte dieser Tour (über den +FAB, den Standort-FAB oder die Kartenansicht) erben automatisch diesen Abspiel-Modus und die maximale Abspielanzahl.
|
||
|
||
### Hinweis im Wegpunkt-Dialog
|
||
|
||
Wenn eine abweichende Tour-Vorgabe aktiv ist (also nicht der Standardmodus „Bei jedem Betreten"), erscheint im Wegpunkt-Erstellungsdialog ein farbiger Hinweis:
|
||
|
||
> „Abspielregel aus Tour-Vorgabe übernommen. Kann hier überschrieben werden."
|
||
|
||
Der Modus kann im Dialog jederzeit für den einzelnen Wegpunkt überschrieben werden.
|
||
|
||
### Wo wird gespeichert?
|
||
|
||
Die Tour-Vorgaben werden separat (im DataStore unter `tour_playback_defaults_json`) pro Tour gespeichert und überleben App-Neustarts.
|
||
|
||
### Einschränkungen
|
||
|
||
- Tour-Vorgaben werden nur beim **Anwenden im Tour-Zähler-Dialog** gesetzt, nicht durch Bearbeitung einzelner Wegpunkte.
|
||
- Die Vorgabe gilt nur für **neu erstellte** Wegpunkte; bereits vorhandene Wegpunkte werden nicht berührt (es sei denn, „Auf alle Wegpunkte anwenden" wird erneut verwendet).
|
||
|
||
---
|
||
|
||
## Karten-Editor
|
||
|
||
Die Kartenansicht ist nun ein vollwertiger **Wegpunkt-Editor** für die gewählte Tour.
|
||
|
||
### Wegpunkte auf der Karte
|
||
|
||
- Alle Wegpunkte der gewählten Tour werden als **Marker** mit Radius-Kreis angezeigt.
|
||
- Inaktive Wegpunkte erscheinen halbtransparent.
|
||
- Die Tour ist in der Titelleiste sichtbar.
|
||
|
||
### Wegpunkt antippen → Aktionsmenü
|
||
|
||
Ein Tipp auf einen Wegpunkt-Marker öffnet ein Dialog-Menü mit:
|
||
|
||
| Aktion | Beschreibung |
|
||
|---|---|
|
||
| **Bearbeiten** | Öffnet den Wegpunkt-Dialog mit allen vorhandenen Daten |
|
||
| **Löschen** | Öffnet Bestätigungsdialog „Wegpunkt löschen?" → erst nach Bestätigung wird gelöscht |
|
||
|
||
### Langer Druck → Neuer Wegpunkt
|
||
|
||
Ein **langer Druck** auf eine beliebige Kartenposition öffnet den Wegpunkt-Erstellungsdialog mit den Koordinaten der gedrückten Position vorausgefüllt.
|
||
|
||
- Tour-Vorgaben (Abspielregel) werden automatisch übernommen.
|
||
- Tour wird automatisch auf die aktuell gewählte Tour gesetzt.
|
||
|
||
### FAB: Wegpunkt aus aktuellem Standort
|
||
|
||
Wie bisher: GPS-Position ermitteln → „Als Wegpunkt übernehmen" (erweiterter FAB).
|
||
|
||
### FAB: Wegpunkt am Track-Ende
|
||
|
||
Ist ein GPS-Track aufgezeichnet oder gespeichert, erscheint ein zusätzlicher FAB **„Wegpunkt am Track-Ende"**: Er öffnet den Wegpunkt-Dialog mit dem letzten aufgezeichneten Track-Punkt als Koordinaten.
|
||
|
||
### Editor-Hinweis
|
||
|
||
Am unteren Rand der Karte erscheint dauerhaft der Hinweis: **„Marker antippen · Karte lange drücken"**, solange kein Track-Panel sichtbar ist.
|
||
|
||
---
|
||
|
||
## GPS-Track-Aufzeichnung
|
||
|
||
GPS2Audio kann GPS-Routen (Tracks) **auch im Hintergrund** aufzeichnen, als Polyline auf der Karte darstellen und pro Tour persistent speichern.
|
||
|
||
Die Aufzeichnung läuft als **Foreground Service** (`TrackRecordingService`) – auch wenn die App in den Hintergrund wechselt, bleibt der Track aktiv. Eine permanente Benachrichtigung „GPS2Audio – Track-Aufzeichnung" zeigt den laufenden Service an.
|
||
|
||
### Track aufzeichnen
|
||
|
||
1. Kartenansicht öffnen (🗺-Symbol in der Titelleiste)
|
||
2. Auf den roten **Aufnahme-FAB** (Kreis-Symbol, unterer Bereich) tippen → Aufzeichnung startet
|
||
3. Während der Aufzeichnung:
|
||
- Alle **5 Sekunden** (mind. 5 m Abstand) wird ein Punkt aufgezeichnet
|
||
- Eine rote **Polyline** erscheint auf der Karte und wächst mit jedem neuen Punkt
|
||
- Das **Track-Statistik-Panel** (links unten) zeigt: Punktanzahl, Distanz, Aufnahmedauer
|
||
- **Die App kann in den Hintergrund wechseln** – die Aufzeichnung läuft weiter
|
||
4. Auf den **Stopp-FAB** (rotes „Stopp"-Symbol) tippen → Aufzeichnung endet, Track wird gespeichert
|
||
|
||
### Track-Statistik-Panel
|
||
|
||
| Anzeige | Beschreibung |
|
||
|---|---|
|
||
| „Aufzeichnung läuft" / roter Punkt | Zeigt an, dass gerade aufgezeichnet wird |
|
||
| Punktanzahl | Anzahl der aufgezeichneten GPS-Punkte |
|
||
| Distanz | Gesamtlänge des Tracks in Metern oder Kilometern (Haversine-Berechnung) |
|
||
| Aufnahmedauer | Vergangene Zeit seit Start (MM:SS oder HH:MM:SS) |
|
||
| „Track gespeichert" | Track ist gespeichert (nicht gerade aktiv aufzeichnend) |
|
||
| „Track löschen" | Entfernt Track aus Speicher und Karte |
|
||
|
||
### Persistenz
|
||
|
||
Der aufgezeichnete Track wird **nach dem Stoppen automatisch** im DataStore unter `gps_tracks_json` pro Tour gespeichert. Beim erneuten Öffnen der Karte mit derselben Tour wird der gespeicherte Track wiederhergestellt und angezeigt.
|
||
|
||
### Wegpunkt am Track-Ende erstellen
|
||
|
||
Ist ein Track vorhanden, erscheint der FAB **„Wegpunkt am Track-Ende"** (türkis/tertiäre Farbe, Timeline-Symbol). Ein Tipp öffnet den Wegpunkt-Dialog mit dem letzten Track-Punkt als Koordinaten.
|
||
|
||
### Langer Druck entlang des Tracks
|
||
|
||
Über **langen Druck** auf die Karte (auch auf den Track) kann an jeder beliebigen Stelle ein Wegpunkt erstellt werden – auch entlang des aufgezeichneten Tracks.
|
||
|
||
### Einschränkungen (GPS-Track)
|
||
|
||
- **Hintergrundaufzeichnung**: Die Track-Aufzeichnung läuft als Foreground Service auch wenn die App minimiert oder die Karte verlassen wird. Eine dauerhafte Systembenachrichtigung „GPS2Audio – Track-Aufzeichnung" ist während der Aufzeichnung sichtbar.
|
||
- **Berechtigung**: Für die Aufzeichnung wird `ACCESS_FINE_LOCATION` (oder `ACCESS_COARSE_LOCATION`) benötigt. Ein Foreground Service des Typs `location` kann mit der normalen Vordergrund-Berechtigung im Hintergrund laufen – **keine** `ACCESS_BACKGROUND_LOCATION`-Berechtigung erforderlich.
|
||
- **Hersteller-Einschränkungen**: Einige Android-Hersteller (Huawei EMUI, Xiaomi MIUI, Samsung One UI) können Foreground Services aggressiv stoppen. Falls der Track im Hintergrund abbricht, bitte unter Einstellungen → Apps → GPS2Audio → Akku → „Nicht optimieren" / „Keine Einschränkungen" setzen.
|
||
- **Kein Konflikt mit dem GPS-Dienst**: Track-Aufzeichnung (`TrackRecordingService`) und GPS-Wegpunkt-Dienst (`WaypointLocationService`) laufen unabhängig voneinander mit eigenen Notification-IDs (2001 vs. 1001).
|
||
- **Ein Track pro Tour**: Jede Tour kann genau einen gespeicherten Track haben. Ein neuer Track überschreibt den vorherigen nach dem Stoppen.
|
||
- **Genauigkeit**: Mindestens Android API 26, FusedLocationProviderClient mit HIGH_ACCURACY (wenn Berechtigung vorhanden), Mindestabstand 5 m.
|
||
- **Akku**: Aktive GPS-Aufzeichnung erhöht den Akku-Verbrauch spürbar. Für Langzeitaufnahmen: Akku-Optimierung der App deaktivieren (s. o.).
|
||
|
||
### Berechtigungen für Hintergrund-Track-Aufzeichnung
|
||
|
||
| Berechtigung | Erforderlich | Hinweis |
|
||
|---|---|---|
|
||
| `ACCESS_FINE_LOCATION` | Empfohlen | Für genaue GPS-Daten |
|
||
| `ACCESS_COARSE_LOCATION` | Mindestanforderung | Weniger genaue Tracks |
|
||
| `FOREGROUND_SERVICE` | Ja | Automatisch erteilt |
|
||
| `FOREGROUND_SERVICE_LOCATION` | Ja | Für Foreground Service Typ Location |
|
||
| `ACCESS_BACKGROUND_LOCATION` | Nein | Nicht erforderlich – Foreground Service Typ Location reicht |
|
||
|
||
> **Hinweis Android 12+**: Beim ersten Start des Track-Aufzeichnungs-Service erscheint die Systemmeldung „GPS2Audio greift auf deinen Standort zu". Das ist erwartetes Verhalten.
|
||
|
||
---
|
||
|
||
## Live / PTT – Mikrofon-Übertragung
|
||
|
||
### Übersicht
|
||
|
||
Die **Live/PTT-Funktion** (Push-to-Talk) ermöglicht es, das Mikrofon in Echtzeit an den Lautsprecher oder ein angeschlossenes Ausgabegerät weiterzuleiten. Die Karte „Live / PTT" befindet sich auf der Hauptseite zwischen dem Atmo-Bereich und den Wegpunkt-Tracks.
|
||
|
||
### Audio-Routing (Gerätewahl)
|
||
|
||
Über den **Zahnrad-Button** in der PTT-Karte oder den Button „Audiogeräte" öffnet sich der Gerätedialog:
|
||
|
||
- **Eingabegerät**: Welches Mikrofon soll für PTT verwendet werden?
|
||
- Intern, Bluetooth-Headset, USB-Headset, ...
|
||
- **Ausgabegerät**: Wohin soll das PTT-Audio geleitet werden?
|
||
- Lautsprecher, Bluetooth-Kopfhörer, ...
|
||
- Wahl „Systemstandard" nutzt das vom Betriebssystem gewählte Standardgerät.
|
||
- Die gewählten Geräte werden **global gespeichert** (DataStore) und beim nächsten Start wiederhergestellt.
|
||
|
||
Die Gerätewahl gilt nur für PTT; reguläre Atmo- und Wegpunkt-Wiedergabe verwenden die system-eigene Audiorouting-Logik.
|
||
|
||
### Berechtigungen
|
||
|
||
Beim ersten Tippen auf „PTT starten" wird die Laufzeit-Berechtigung `RECORD_AUDIO` angefordert. Ohne diese Berechtigung kann kein Mikrofonsignal erfasst werden. Die App funktioniert in allen anderen Bereichen ohne diese Berechtigung normal weiter.
|
||
|
||
### Audio-Priorität
|
||
|
||
| Situation | Verhalten |
|
||
|---|---|
|
||
| PTT aktiv | Atmo (Begleitmusik) wird pausiert |
|
||
| GPS-Wegpunkt während PTT | Wiedergabe wird aufgeschoben und nach PTT-Ende nachgeholt |
|
||
| Manuelle Wegpunkt-Wiedergabe während PTT | Blockiert mit Hinweis; nach PTT-Ende möglich |
|
||
| PTT endet | Atmo-Wiedergabe wird wiederhergestellt |
|
||
|
||
### Bekannte Einschränkungen
|
||
|
||
| Einschränkung | Erklärung |
|
||
|---|---|
|
||
| **Echo / Feedback** | Ohne Headset hört das Mikrofon den Lautsprecher – Echo ist zu erwarten. Das App-UI zeigt eine Warnung. Für Echo-freien Betrieb ein Headset verwenden. |
|
||
| **Bluetooth-Latenz** | Bluetooth SCO/A2DP hat systembedingte Verzögerungen von 50–200 ms. Für Echtzeit-Sprache empfehlen sich kabelgebundene oder USB-Headsets. |
|
||
| **Geräte-ID-Änderungen** | Android vergibt Geräte-IDs (`AudioDeviceInfo.id`) sitzungsspezifisch. Nach einem Neustart oder Trennen/Verbinden eines Geräts kann eine gespeicherte ID ungültig werden. Die App fällt dann automatisch auf den Systemstandard zurück und zeigt ggf. einen Hinweis im Log. |
|
||
| **setPreferredDevice()-Support** | Nicht alle Android-Geräte oder Hersteller-ROMs respektieren `AudioRecord.setPreferredDevice()` vollständig. Auf nicht kompatiblen Geräten wird der Systemstandard verwendet; ein Log-Eintrag dokumentiert den Fallback. |
|
||
| **Hintergrundmikrofon-Benachrichtigung** | Android 9+ zeigt eine Systembenachrichtigung wenn eine App das Mikrofon im Vorderground-Service nutzt. Diese Benachrichtigung ist vom System vorgegeben und kann nicht unterdrückt werden. |
|
||
| **Keine Echo-Unterdrückung (AEC)** | Der MVP implementiert keine Software-AEC. Für Echo-Unterdrückung kann `AcousticEchoCanceler.create()` nachgerüstet werden, sofern die Hardware es unterstützt. |
|
||
| **Kein Hintergrund-PTT nach App-Kill** | Der LivePttService stoppt wenn der App-Prozess vom System beendet wird. PTT ist primär für Vordergrundnutzung ausgelegt. |
|
||
|
||
### Technische Details
|
||
|
||
- **Implementierung**: `LivePttService` (Foreground Service, Typ `microphone`) mit `AudioRecord` (Eingang) und `AudioTrack` (Ausgang)
|
||
- **Audio-Format**: PCM 16-Bit, Mono, 16 kHz Abtastrate
|
||
- **Routing-Einstellungen**: Persistiert in `audio_routing_settings` (Jetpack DataStore)
|
||
- **Geräteinformationen**: `AudioDeviceManager` kapselt `AudioManager.getDevices()` mit deutschen Gerätenamen
|