5.8 KiB
5.8 KiB
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.
- Per wekker is een aan/uit-schakelaar op het hoofdscherm: uitgezet blijft uit (ook de dagelijkse 12:00-controle plant hem niet opnieuw) tot je hem weer aanzet.
- In Instellingen → Wekkergeluiden kun je per wekker een eigen geluid kiezen via de systeem-ringtone-kiezer; standaard is het systeem-alarmgeluid.
- 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
- Bouw de APK:
./gradlew :app:assembleDebug→app/build/outputs/apk/debug/app-debug.apk - Zet de APK op de telefoon en installeer (sideload).
- Open de app → Instellingen → vul 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)
- Agenda-URL:
- Opslaan, terug op het hoofdscherm Nu controleren om te testen.
- Verleen de meldingenmachtiging bij de eerste start (systeemdialoog).
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 hoofdscherm: klok + geplande wekkers + "Nu controleren" + link naar instellingen
SettingsActivity instellingen: CalDAV-url, gebruiker, app-wachtwoord (+ uitleg)
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)
Hoofdscherm en instellingen zijn bewust gescheiden; installatiehulp via
launch-intent-extra's (--es url/user/pass) slaat de config op en draait
direct een controle, zonder UI-interactie.
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-notitieHomelab/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-notitiescrapedienst.md - CalDAV-referentieclient:
~/src/caldav-mcp