Production cleanup: enable R8, add ProGuard rules, validate API input

- Enable R8 minification and resource shrinking for release builds
- Add ProGuard keep rules for Ktor, kotlinx.serialization, Room
- Validate hour/minute range in POST /set endpoint
- Guard wake lock release on server start failure
- Remove unused template colors from colors.xml
- Rewrite README with curl examples, security note, troubleshooting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Moritz 2026-02-15 17:10:41 +01:00
parent 5ad7c6cee8
commit 6032e9fd07
5 changed files with 103 additions and 55 deletions

View file

@ -1,64 +1,80 @@
# Helios Alarm Clock
An Android alarm clock app with a built-in HTTP server, designed to be controlled remotely from a Raspberry Pi or any device on the local network.
An Android alarm clock with an embedded HTTP server for remote control from a Raspberry Pi or any device on the local network.
## Features
- **HTTP API** — Embedded Ktor server (port 8080) for remote alarm management
- **In-app UI** — Set and remove alarms with a Material 3 time picker
- **Reliable alarms** — Uses `AlarmManager.setExactAndAllowWhileIdle()` to fire through Doze mode
- **Full-screen alarm** — Wakes the screen, plays the system alarm sound, and vibrates
- **DND bypass** — Alarm audio uses `USAGE_ALARM` to ring even in Do Not Disturb mode
- **Persistent server** — Foreground service with wake lock keeps the HTTP server alive
- **Boot survival** — Server and alarms reschedule automatically after reboot
- **Auto-cleanup** — Fired alarms are automatically deleted from the database
- **HTTP API** on port 8080 for remote alarm management
- **Material 3 UI** with time picker and alarm list
- **Reliable alarms** via `AlarmManager.setExactAndAllowWhileIdle()` (survives Doze)
- **Full-screen alarm** with system alarm sound and DND bypass
- **Persistent server** as a foreground service with wake lock
- **Boot survival** — server and alarms reschedule after reboot
- **Auto-cleanup** — fired alarms are deleted automatically
## HTTP API
All endpoints are served on port `8080`.
All endpoints listen on port `8080`. Replace `PHONE_IP` with the IP shown in the app.
### Set an alarm
```
POST /set
Content-Type: application/json
{"hour": 7, "minute": 30, "label": "Wake up"}
```bash
curl -X POST http://PHONE_IP:8080/set \
-H "Content-Type: application/json" \
-d '{"hour": 7, "minute": 30, "label": "Wake up"}'
```
Returns `201 Created` with `{"id": "<uuid>"}`.
Response: `201 Created`
```json
{"id": "550e8400-e29b-41d4-a716-446655440000"}
```
`hour` must be 0-23, `minute` must be 0-59. `label` is optional (defaults to empty).
### Remove an alarm
```
POST /rm
Content-Type: application/json
{"id": "<uuid>"}
```bash
curl -X POST http://PHONE_IP:8080/rm \
-H "Content-Type: application/json" \
-d '{"id": "550e8400-e29b-41d4-a716-446655440000"}'
```
### List alarms
```
GET /list
```bash
curl http://PHONE_IP:8080/list
```
Returns a JSON array of all scheduled alarms.
## Security
The HTTP server has **no authentication**. Anyone on the same network can set or remove alarms. Only run this on a trusted local network.
## Tech Stack
- Kotlin, Jetpack Compose, Material 3
- MVVM architecture with Hilt dependency injection
- Room database for alarm persistence
- MVVM with Hilt dependency injection
- Room database for persistence
- Ktor CIO embedded HTTP server
- AlarmManager with exact alarms
- Foreground service (connectedDevice type) for the HTTP server
- Foreground service (`connectedDevice` type)
## Requirements
- Android 8.0+ (API 26)
- Target SDK 36 (Android 16)
- Permissions: exact alarms, notifications, foreground service, wake lock, internet
## Permissions
| Permission | Purpose |
|---|---|
| `INTERNET` / `ACCESS_NETWORK_STATE` | HTTP server |
| `FOREGROUND_SERVICE_CONNECTED_DEVICE` | Keep server alive |
| `SCHEDULE_EXACT_ALARM` / `USE_EXACT_ALARM` | Precise alarm timing |
| `USE_FULL_SCREEN_INTENT` | Wake screen on alarm |
| `WAKE_LOCK` | Prevent CPU sleep |
| `RECEIVE_BOOT_COMPLETED` | Restart after reboot |
| `POST_NOTIFICATIONS` | Service + alarm notifications |
## Building
@ -66,4 +82,21 @@ Returns a JSON array of all scheduled alarms.
./gradlew assembleRelease
```
The APK will be at `app/build/outputs/apk/release/app-release.apk`.
The APK is at `app/build/outputs/apk/release/app-release.apk`.
## Installing via ADB
```bash
adb install app/build/outputs/apk/release/app-release.apk
```
## Troubleshooting
- **Server not reachable**: Ensure the phone and client are on the same Wi-Fi network. Check that battery optimization is disabled for the app.
- **Alarm doesn't fire**: Grant exact alarm permission in system settings. Disable battery optimization for the app.
- **Notification not showing**: Grant notification permission (Android 13+).
- **Server dies in background**: Some OEMs aggressively kill background services. Disable battery optimization and lock the app in recents.
## License
MIT