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
This commit is contained in:
@@ -17,16 +17,19 @@
|
||||
- **Android Patterns**: Use `findViewById` for view binding in this project to maintain consistency with existing simple architecture.
|
||||
|
||||
## Architecture
|
||||
- **Pattern**: Simple Activity-Dialog architecture.
|
||||
- **State**: The countdown state is managed locally within `CountdownDialog` using `android.os.CountDownTimer`.
|
||||
- **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 `CountdownDialog` is explicitly set to `setCancelable(false)` and `setCanceledOnTouchOutside(false)` to ensure the timer completes.
|
||||
- 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 and trigger for the timer.
|
||||
- `app/src/main/java/com/example/countdowntimer/CountdownDialog.kt`: Implementation of the countdown logic and `ToneGenerator` trigger.
|
||||
- `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.
|
||||
- `app/src/main/res/layout/dialog_countdown.xml`: Timer dialog layout.
|
||||
- `app/build.gradle`: Build configuration, SDK versions (minSdk 24, targetSdk 34), and dependencies.
|
||||
- `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.
|
||||
|
||||
Reference in New Issue
Block a user