Files
kfj001 d7ce314c22 migrate timer to ForegroundService for background survival
Move CountDownTimer logic from a Dialog into a ForegroundService so
the timer survives when the user tabs away or the activity is
destroyed. The activity becomes a thin UI projection bound to the
service via TimerStateListener callbacks.

- Create CountdownService with notification, state persistence,
  and ToneGenerator/Vibrator ownership
- Persist timer state to SharedPreferences for process death recovery
- Add notification with progress bar and Stop/Restart actions
- Embed countdown UI in activity_main.xml alongside picker UI
- Delete CountdownDialog and dialog_countdown.xml
- Update AndroidManifest with foreground service permissions
2026-06-23 01:49:11 +00:00

36 lines
2.3 KiB
Markdown

# CLAUDE.md - Countdown Timer
## Build & Test Commands
- **Build Debug APK**: `./gradlew assembleDebug`
- **Build Release APK**: `./gradlew assembleRelease`
- **Clean Project**: `./gradlew clean`
- **Run Unit Tests**: `./gradlew test` (if applicable)
## Code Style Guidelines
- **Language**: Kotlin 1.9.0
- **UI Framework**: Traditional Android View system (XML layouts), **not** Jetpack Compose.
- **Naming Conventions**:
- Classes: `PascalCase` (e.g., `CountdownDialog`)
- Functions/Variables: `camelCase` (e.g., `startTimer()`)
- Layout Files: `snake_case` (e.g., `activity_main.xml`)
- Resource IDs: `camelCase` (e.g., `btnStart`, `cvCountdown`)
- **Android Patterns**: Use `findViewById` for view binding in this project to maintain consistency with existing simple architecture.
## Architecture
- **Pattern**: Activity-Service architecture with `ForegroundService`.
- **State**: The countdown state is managed in `CountdownService` using `android.os.CountDownTimer`, persisted to `SharedPreferences` for process death recovery.
- **UI**: `MainActivity` binds to the service and acts as a thin UI projection, receiving state updates via `TimerStateListener` callback.
- **Dependency Management**: Gradle with Groovy DSL.
- **Key Constraints**:
- The notification is set to `setOngoing(true)` — cannot be swiped away.
- Timer state survives process death via `SharedPreferences` persistence.
## Critical Files Reference
- `app/src/main/java/com/example/countdowntimer/MainActivity.kt`: Entry point, binds to service, implements `TimerStateListener`.
- `app/src/main/java/com/example/countdowntimer/CountdownService.kt`: ForegroundService owning timer logic, `ToneGenerator`, `Vibrator`, notification, and state persistence.
- `app/src/main/java/com/example/countdowntimer/TimerStateListener.kt`: Callback interface for service-to-activity state updates.
- `app/src/main/java/com/example/countdowntimer/CountdownCanvasView.kt`: Custom view for the circular progress ring and countdown text.
- `app/src/main/res/layout/activity_main.xml`: Main screen layout (contains both picker and countdown UI).
- `app/src/main/AndroidManifest.xml`: Declares service and foreground service permissions.
- `app/build.gradle`: Build configuration, SDK versions (minSdk 34, targetSdk 34), and dependencies.