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
36 lines
2.3 KiB
Markdown
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.
|