android-buschauffeurswekker/README.md

116 lines
No EOL
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Buschauffeurswekker
Android-app die de functie van de normale wekker-app vervult, maar de wekkers
automatisch zet op basis van de Nextcloud CalDAV-agenda **EBS-Diensten**.
## Werking
- Elke dag om **12:00** leest de app de agenda van de **volgende dag**.
- De dienstbegintijd wordt **naar beneden afgerond op een heel kwartier**:
- 05:00–05:14 → 05:00
- 05:15–05:29 → 05:15
- 05:30–05:44 → 05:30
- 05:45–05:59 → 05:45
- Er worden drie wekkers gezet, alle drie vóór de afgeronde aanvangstijd:
- **Opstaan** — 2 uur vóór aanvang
- **Wally** — 1,5 uur vóór aanvang
- **Vertrek** — 0,5 uur vóór aanvang
- Staat er **geen dienst** in de agenda voor morgen, dan worden **geen wekkers** gezet.
- De wekker gaat volwaardig af (geluid + trillen, volledig scherm) **ook bij een
vergrendeld scherm**, met snooze (10 min) en "wekker uit".
- Het toestel mag daarvoor **mobiele data** verbruiken en taken op de
**achtergrond** uitvoeren.
## Installatie
1. Bouw de APK: `./gradlew :app:assembleDebug`
→ `app/build/outputs/apk/debug/app-debug.apk`
2. Zet de APK op de telefoon en installeer (sideload).
3. Open de app en vul bij **Instellingen** in:
- Agenda-URL: `https://nextcloud.eddydevink.nl/remote.php/dav/calendars/eddy/ebs_diensten-1/`
- Gebruikersnaam: `eddy`
- App-wachtwoord: een Nextcloud-app-wachtwoord
(Nextcloud → Beveiliging → App-wachtwoorden; zie de Obsidian-vault voor
de bestaande app-wachtwoorden — niet in de app hardcoden)
4. Druk op **Opslaan** en daarna op **Nu controleren** om te testen.
5. Verleen de gevraagde machtigingen via de knoppen onder **Machtigingen**:
meldingen, exacte alarmen, batterijoptimalisatie uitzonderen en (Android 14+)
volledig scherm.
## Machtigingen
| Machtiging | Doel |
|---|---|
| Internet / netwerk | Agenda ophalen over wifi én mobiele data |
| Meldingen (POST_NOTIFICATIONS) | Afgaande wekker tonen |
| Exacte alarmen (USE_EXACT_ALARM / SCHEDULE_EXACT_ALARM) | Wekker óp tijd, ook in Doze |
| Volledig scherm (USE_FULL_SCREEN_INTENT) | Wekker bovenop het vergrendelscherm |
| Wakelock + trillen | Scherm aanhouden en trillen tijdens afgaan |
| Boot (RECEIVE_BOOT_COMPLETED) | Wekkers na herstart opnieuw inplannen |
| Batterijoptimalisatie uitzonderen | Achtergrondtaken betrouwbaar |
## Architectuur
```
MainActivity status + instellingen, knop "Nu controleren"
AlarmActivity volledig-scherm wekker (geluid, trillen, snooze/dismiss)
App kanalen + dagelijkse 12:00-controle bij opstart
daily check:
AlarmScheduler.scheduleNoonCheck → DailyCheckReceiver (12:00, exact, allowWhileIdle)
→ ShiftCheck.run agenda morgen ophalen → afronden → wekkers plannen
→ CalDavClient REPORT calendar-query (time-range, basic auth)
→ Ical iCal-parse: DTSTART (TZID/UTC), vroegste aanvang
→ ShiftPlanner afronding op kwartier + Opstaan/Wally/Vertrek
ring:
AlarmScheduler.scheduleAlarm → AlarmRingReceiver (exact, allowWhileIdle)
→ full-screen intent + directe start → AlarmActivity
→ Ringer wekkergeluid (loop) + vibratiepatroon
BootReceiver na reboot: 12:00-controle + geplande wekkers herstellen
Prefs instellingen/status, versleuteld (EncryptedSharedPreferences)
```
Details per bestand:
- `core/ShiftPlanner.kt` — pure logica: kwartier-afronding en wekkerplanning
(JVM-unit-tests, geen Android-afhankelijkheden).
- `caldav/Ical.kt` — minimale RFC 5545-parser (VEVENT, DTSTART met TZID/UTC,
all-day en geannuleerde events worden overgeslagen).
- `caldav/CalDavClient.kt` — REPORT calendar-query volgens het recept van de
scrapedienst (zie vault-notitie `Homelab/Software ontwikkeling/scrapedienst.md`).
- `core/ShiftCheck.kt` — orchestrator: ophalen → filteren op morgen → vroegste
aanvang → plannen of annuleren; gedeeld door receiver en knop.
- `core/AlarmScheduler.kt` — exacte alarmen + 12:00-controle + snooze + testwekker.
- `receivers/DailyCheckReceiver.kt` — 12:00; plant zichzelf via AlarmScheduler
steeds opnieuw.
- `receivers/AlarmRingReceiver.kt` — afgaande wekker: wakelock, full-screen
intent (ook vergrendeld scherm), directe activity-start.
- `receivers/BootReceiver.kt` — herstart-herstel (BOOT_COMPLETED, TIME_SET,
TIMEZONE_CHANGED, MY_PACKAGE_REPLACED).
- `core/Notifier.kt`, `core/Ringer.kt` — meldingen (kanalen "wekkers"/"status")
en geluid/trillen.
## Keuzes
- **12:00-controle via exact AlarmManager-alarm**, niet WorkManager: precies om
12:00 (WorkManager periodiek is minimaal 15 min en onnauwkeurig).
- Bij **meerdere events** op één dag geldt de **vroegste aanvang** als
dienstbegintijd.
- **All-day-events** (bijv. "vrij") worden genegeerd; alleen getimede diensten
tellen.
- Na een fout (bv. offline) blijven eerder geplande wekkers staan en verschijnt
een statusmelding.
- Wachtwoord staat **versleuteld** op het toestel
(EncryptedSharedPreferences, AES256-GCM; bij falen plain fallback in de
app-sandbox).
## Build
- Gradle wrapper 8.13, AGP 8.7.3, Kotlin 2.0.21
- compileSdk/targetSdk 34, minSdk 27 (Android 8.1+)
- Tests: `./gradlew :app:testDebugUnitTest`
## Gerelateerd
- Scrapedienst die de EBS-Diensten-agenda vult:
`~/src/scrapedienst` + vault-notitie `scrapedienst.md`
- CalDAV-referentieclient: `~/src/caldav-mcp`