Conversation
This commit introduces DataStore for managing application preferences, migrating from SharedPreferences. It also integrates Hilt for dependency injection, setting up the `LiveInPeaceApplication` class. A new preference `PREF_HIDE_IN_LAUNCHER` has been added.
…cies This commit moves the creation of notification channels from the `QSTileService` to the `LiveInPeaceApplication` class. This ensures channels are created when the application starts. Additionally, several dependencies have been updated to their latest versions, including: - `androidx.core:core-ktx` - `androidx.appcompat:appcompat` - `androidx.databinding:databinding-runtime` - `androidx.lifecycle:lifecycle-runtime-ktx` - `androidx.compose:compose-bom` - `androidx.lifecycle:lifecycle-livedata-ktx` and related lifecycle components - `com.google.dagger:hilt-android` - `androidx.datastore:datastore-preferences` New dependencies added: - `androidx.lifecycle:lifecycle-viewmodel-compose` - `com.google.accompanist:accompanist-permissions` - `androidx.compose.material:material-icons-extended`
This commit moves the `ConnectionViewModel` class from the `com.maary.liveinpeace` package to the `com.maary.liveinpeace.viewmodel` package. The import statements in `HistoryActivity.kt` have been updated accordingly.
This commit introduces a new settings screen with the following features: - Toggle for foreground service - Toggle for alert notifications - Toggle for ear protection - Toggle for hiding the app icon in the launcher - Navigation to system notification settings - Navigation to connection history (placeholder) It also includes: - `SettingsViewModel` to manage settings state and logic. - `SettingsScreen.kt` for the UI implementation. - `SettingsComponents.kt` for reusable UI components. - New string resources for the settings screen.
This commit replaces SharedPreferences with PreferenceRepository (DataStore) for managing application preferences. The following changes were made: - Removed SharedPreferences usage from `ForegroundService` and `QSTileService`. - `ForegroundService` now uses `PreferenceRepository` to access and modify preference values, including ear protection, watching state, and service running state. - `QSTileService` now uses `PreferenceRepository` to determine the service running state and manage the welcome finished state. - Removed the `PREF_ICON` preference and related logic for choosing notification icon style, defaulting to the numeric volume icon. - Removed the "Greeting" composable and its preview from `MainActivity`. - The settings action in the foreground service notification now opens `MainActivity` instead of `SettingsReceiver`. - Removed the ear protection toggle action from the foreground service notification.
This commit introduces `MainActivityAlias` to enable hiding the app from the launcher. The `SettingsViewModel` now handles toggling the enabled state of `MainActivityAlias` based on the "Hide in Launcher" preference. The `android:foregroundServiceType` attribute has been added to the `ForegroundService` declaration in `AndroidManifest.xml` to comply with Android 14 requirements.
This commit refactors the `ForegroundService` to enhance concurrency and the ear protection feature. - Introduced a `Mutex` to protect the `deviceMap` from concurrent access issues. - Ear protection logic is now executed within a coroutine for each connected device, allowing for individual cancellation upon device disconnection. - Removed unused constants.
This commit refactors the `AudioDeviceCallback` within `ForegroundService.kt` to improve code clarity, maintainability, and robustness.
Key changes include:
- **Centralized Logic for Device Handling:** The `onAudioDevicesAdded` and `onAudioDevicesRemoved` methods now delegate core processing to new helper functions like `processNewDevice`, `processRemovedDevice`, `applyEarProtection`, and `saveConnectionToDatabase`.
- **Improved Readability:**
- Introduced constants for magic numbers (e.g., `EAR_PROTECTION_LOWER_THRESHOLD`, `VOLUME_ADJUST_ATTEMPTS`).
- Used a `Set` (`IGNORED_DEVICE_TYPES`) for ignored device types, making it easier to manage.
- Added more descriptive logging messages.
- **Optimized Preference Reading:** Preferences like `isWatchingEnabled` and `isEarProtectionOn` are now read once outside the loop in `onAudioDevicesAdded` to avoid repeated reads.
- **Enhanced Ear Protection Logic:**
- The ear protection logic is now more robust, checking `isActive` within the volume adjustment loops to handle cancellations.
- Uses the device name as the key for `protectionJobs` for better consistency.
- **Unified UI Updates:** A new `updateUiAndNotifications` function centralizes the broadcasting of connection updates and updating the foreground notification, reducing redundancy.
- **Clearer Device Name Handling:** The `getDeviceName` helper function standardizes how device names are retrieved and handles null or blank names.
- **State Management:** A `hasChanges` flag is used in `onAudioDevicesAdded` and `onAudioDevicesRemoved` to track if any actual device changes occurred, preventing unnecessary UI updates.
- **Error Handling:** Added a `try-catch` block around database insertion in `saveConnectionToDatabase`.
- **Permission Annotation:** Added `@RequiresPermission(Manifest.permission.POST_NOTIFICATIONS)` to functions that directly trigger notifications.
- Renamed `ConnectionsApplication` to `LiveInPeaceApplication`. - Moved database and repository initialization from the deleted `ConnectionsApplication` to `LiveInPeaceApplication`. - Updated `AndroidManifest.xml` to reflect the new application class name. - Updated `HistoryActivity` to use `LiveInPeaceApplication` for accessing the repository. - Moved `DynamicColors.applyToActivitiesIfAvailable(this)` call to `LiveInPeaceApplication`.
This commit refactors the `ForegroundService` to improve its structure, readability, and reliability. Key changes include: - **Encapsulation and Cohesion**: Related logic, such as permission checks and notification updates, is now encapsulated in helper functions. - **Constant Usage**: Magic numbers (e.g., PendingIntent request codes, device type IDs) have been replaced with meaningful constants. `TYPE_UNKNOWN_DEVICE_28` is introduced for the previously unnamed device type. - **Code Simplification**: Broadcast receiver implementations are streamlined. - **Robustness**: Unified permission checks are added before all notification operations to ensure stability on Android 13+. - **Readability**: Function and variable names are improved, and comments are added for clarity. - **Structural Optimization**: The `audioDeviceCallback` logic has been broken down into smaller, single-responsibility functions, reducing complexity. - **Resource Management**: Implemented safer unregistering of receivers and callbacks. - **Notification Logic**: Notification creation and icon generation logic is clarified and centralized. - **Coroutine Scope**: Uses `SupervisorJob` for the service scope to prevent one job's failure from canceling others. - **Error Handling**: Improved logging for errors during resource cleanup and data saving.
This commit updates the Compose BOM to version `2025.06.00`. It also removes the `lifecycle_version` and `room_version` variables, as their values were already hardcoded in the dependencies.
This commit moves `MainActivity` and `HistoryActivity` into a new `activity` subpackage to improve project structure. Key changes: - Moved `MainActivity.kt` to `activity/MainActivity.kt` and updated its package declaration. - Moved `HistoryActivity.kt` to `activity/HistoryActivity.kt` and updated its package declaration. - Updated `AndroidManifest.xml` to reflect the new activity paths for `MainActivity`, `MainActivityAlias`, and `HistoryActivity`. - Changed `android:label` for `MainActivityAlias` to `@string/app_name`. - Set `android:enabled="false"` for `MainActivityAlias` to ensure it's not the default launcher activity initially. - Updated `HistoryTileService.kt` to import `HistoryActivity` from the new `activity` package. - Removed unused imports from `MainActivity.kt`.
This commit changes the `PendingIntent` for the settings action in the foreground service notification. Instead of using `PendingIntent.getBroadcast` with a custom action, it now uses `PendingIntent.getActivity` to directly launch `MainActivity`. This aligns with the intended behavior of opening the app's settings. Additionally, `launchIn(viewModelScope)` has been added to the preference flows in `SettingsViewModel` to ensure they are properly collected within the ViewModel's lifecycle.
This commit implements navigation functionality in the `SettingsScreen`. - The close button in the top app bar now finishes the `SettingsActivity`. - The history button in the top app bar now navigates to `HistoryActivity`.
This commit introduces a new welcome flow for the application.
- **WelcomeActivity**: A new `ComponentActivity` that displays the `WelcomeScreen`. It handles edge-to-edge display.
- **WelcomeViewModel**:
- Manages the state for notification permission, battery optimization status, and app icon visibility.
- Provides functions to:
- Handle permission results.
- Check and update battery optimization status.
- Toggle the app icon's visibility in the launcher by enabling/disabling `MainActivityAlias`.
- Persist the "welcome finished" state and app icon visibility preference using `PreferenceRepository`.
- Start the `ForegroundService` when the welcome flow is completed.
- Observes the `isShowingIcon` flow from `PreferenceRepository` to initialize the app icon state.
- **WelcomeScreen (Composable)**:
- Displays UI for requesting necessary and optional permissions/settings:
- Notification permission.
- Disabling battery optimization.
- Showing/hiding the app icon in the launcher.
- Uses `rememberLauncherForActivityResult` to request notification permission.
- Updates battery optimization status on resume using `LifecycleEventObserver`.
- Provides a "Finish" button that becomes enabled once notification permission is granted, which then calls `welcomeViewModel.welcomeFinished()`.
- **PreferenceRepository**:
- Added `isShowingIcon()` flow to observe the app icon visibility state.
- Added `setShowIcon()` function to persist the app icon visibility state.
- **AndroidManifest.xml**:
- Registered `WelcomeActivity`.
- Set `MainActivityAlias` to `android:enabled="false"` by default.
- **SettingsComponents.kt**:
- Added new composable functions (`TopBox`, `MiddleBox`, `BottomBox`, `StandaloneBox`) for styling settings items with rounded corners.
- Modified `SwitchRow` to trigger its `onCheckedChange` callback when the entire row is tapped.
- **strings.xml**: Added new string resources for the welcome screen.
This commit refactors the `QSTileService` and `SettingsViewModel`. **QSTileService:** - Simplified the `onClick` logic. - If the welcome process is not finished, it now directly launches `WelcomeActivity`. - Removed the logic for requesting notification permissions and creating a welcome notification within the `QSTileService` as this is now handled by `WelcomeActivity`. - Ensured that `ForegroundService` is only started or stopped after the welcome check. **SettingsViewModel:** - Fixed an issue where the `_hideInLauncherSwitchState` was not being updated correctly after changing the component enabled setting. It now correctly reflects the new state.
This commit refactors the "Hide in Launcher" setting to "Show Icon" for better clarity.
- **SettingsScreen:**
- Renamed the switch title from "Hide in Launcher" to "Show Icon".
- Updated the description to "Show app icon in the launcher".
- The switch state now reflects `settingsViewModel.showIconState`.
- The `onCheckedChange` lambda now calls `settingsViewModel.toggleShowIcon()`.
- **SettingsViewModel:**
- Renamed `_hideInLauncherSwitchState` to `_showIconState`.
- Renamed `hideInLauncherSwitchState` to `showIconState`.
- Renamed `hideInLauncherSwitch()` to `toggleShowIcon()`.
- The logic for `toggleShowIcon()` is inverted to match the "Show Icon" behavior.
- `preferenceRepository.setShowIcon()` is now called with the new `_showIconState.value`.
- Preference loading now updates `_showIconState` with `isHideInLauncher()` (which implicitly becomes `isShowIcon`).
- **SettingsComponents.kt:**
- Changed `SwitchRow` interaction from `pointerInput` with `detectTapGestures` to a standard `clickable` modifier for simplicity and better accessibility.
- **WelcomeScreen.kt:**
- Removed a `/*todo*/` comment.
- **HistoryTileService.kt:**
- Added `@SuppressLint("StartActivityAndCollapseDeprecated")` to `onClick` method to suppress lint warning for `startActivityAndCollapse` which is deprecated but necessary for TileService functionality.
This commit refactors the `BootCompleteReceiver` to use `WorkManager` for starting the `ForegroundService` on device boot. - A new `BootWorker` (`CoroutineWorker`) is introduced to handle the foreground service start logic. - The `BootCompleteReceiver` now enqueues a `OneTimeWorkRequest` for the `BootWorker` when `Intent.ACTION_BOOT_COMPLETED` is received. This approach aligns with modern Android practices for background tasks and service initiation. - Added `androidx.work:work-runtime-ktx` dependency.
This commit refactors `SettingsViewModel` to directly expose `StateFlow`s from `PreferenceRepository` for managing UI states related to: - Foreground service status - Alert/watching state - Ear protection status - Launcher icon visibility Key changes: - Removed private `MutableStateFlow` instances and their corresponding public `StateFlow` counterparts (`_foregroundSwitchState`, `_alertSwitchState`, `_protectionSwitchState`, `_showIconState`). - Directly assigned public `StateFlow` properties (`foregroundSwitchState`, `alertSwitchState`, `protectionSwitchState`, `showIconState`) by collecting flows from `preferenceRepository` using `stateIn` with `SharingStarted.WhileSubscribed(5000)`. - Updated `foregroundSwitch()`, `alertSwitch()`, `protectionSwitch()`, and `toggleShowIcon()` methods to use the new public `StateFlow` values for their logic. - Removed the `init` block that was previously used to initialize the `MutableStateFlow`s by observing repository flows. - In `toggleShowIcon()`, the logic for updating the package manager and then persisting the new state to the repository is maintained, now using the value from the public `showIconState` `StateFlow`.
This commit refactors `WelcomeViewModel` to manage `showIconState` using a `StateFlow` directly from the `preferenceRepository`. Key changes: - `showIconState` is now a `StateFlow<Boolean>` initialized by `preferenceRepository.isHideInLauncher().stateIn(...)`. This provides a reactive stream directly from the data source. - The local `_showIconState` `MutableStateFlow` and its manual update in the `init` block have been removed. - `toggleShowIcon()` now reads the current state from `showIconState.value` to determine the new component enabled state for `MainActivityAlias`. - The call to `preferenceRepository.setShowIcon()` has been updated to reflect its new signature (likely now parameterless, inferring the state to toggle).
This commit introduces a customizable ear protection threshold feature, allowing users to define a safe volume range.
Key changes include:
- **Settings Screen:**
- Added a `ThresholdSlider` composable in `SettingsScreen.kt` to allow users to set the minimum and maximum safe volume levels.
- The slider uses a custom `ValueIndicatorThumb` for better visual feedback.
- **Preference Repository:**
- Introduced new preference keys (`PREF_EAR_PROTECTION_THRESHOLD_MAX`, `PREF_EAR_PROTECTION_THRESHOLD_MIN`) and constants (`EAR_PROTECTION_LOWER_THRESHOLD`, `EAR_PROTECTION_UPPER_THRESHOLD`) in `Constants.kt`.
- Added functions in `PreferenceRepository.kt` (`getEarProtectionThreshold`, `setEarProtectionThreshold`) to read and write the threshold range using `DataStore`.
- **Settings ViewModel:**
- Added a `StateFlow` (`earProtectionThreshold`) in `SettingsViewModel.kt` to expose the current threshold range to the UI.
- Implemented `setEarProtectionThreshold` function to update the stored threshold.
- **Foreground Service:**
- Modified `ForegroundService.kt` to fetch the user-defined ear protection threshold from `PreferenceRepository` before applying volume adjustments.
- Removed hardcoded threshold values.
- **String Resources:**
- Added a new string resource `safe_volume_threshold` in `strings.xml`.
This commit introduces a static `isRunning` flag in `ForegroundService` to track its active state in memory.
Key changes:
- **ForegroundService:**
- Added a public, volatile `isRunning` static boolean variable, updated in `onCreate()` and `onDestroy()`.
- **QSTileService:**
- In `onStartListening()`, the tile state is now synchronized with `ForegroundService.isRunning`.
- If the persisted state indicates the service should be running but `ForegroundService.isRunning` is false (suggesting a system kill), the persisted state is corrected to false, and the tile is updated accordingly.
- **SettingsViewModel:**
- A new `checkAndSyncServiceState()` function is called during initialization.
- This function compares the persisted service switch state with `ForegroundService.isRunning`.
- If the persisted state is "on" but the service is not running in memory, the service is automatically restarted.
This commit refactors the logic for managing the app icon's visibility in the launcher.
- Renamed `PREF_HIDE_IN_LAUNCHER` to `PREF_VISIBLE_IN_LAUNCHER` in `PreferenceRepository` for clarity.
- Updated `PreferenceRepository` methods:
- `isHideInLauncher()` renamed to `isIconShown()`.
- `setHideInLauncher()` and `setShowIcon()` consolidated into `toggleIconVisibility()`.
- Adjusted `WelcomeViewModel` and `SettingsViewModel` to use the updated `PreferenceRepository` methods for managing icon visibility state and toggling.
- Removed unused imports in `WelcomeViewModel` and `SettingsViewModel`.
The `ThresholdSlider` for setting the ear protection threshold is now wrapped in an `AnimatedVisibility` composable. This means the slider will only be visible and animate in when the "Ear Protection" switch is enabled, and animate out when disabled.
This commit introduces a unified `SettingsItem` composable to replace the individual `TopBox`, `MiddleBox`, `BottomBox`, and `StandaloneBox` composables. The new `SettingsItem` composable takes a `GroupPosition` enum (TOP, MIDDLE, BOTTOM, SINGLE) to determine the appropriate corner rounding for the settings item, simplifying the layout code and improving maintainability. The `WelcomeScreen.kt` has been updated to use the new `SettingsItem` composable with the corresponding `GroupPosition`.
This commit refactors the settings screen UI for better organization and introduces conditional visibility for notification settings. - The "Default Channel" (Enable Foreground Service) and "Notification Settings" are now grouped. - The "Notification Settings" item is only visible when the "Default Channel" switch is enabled. Clicking it opens the app's notification settings in the system settings. - The "Enable Watching", "Ear Protection", "Safe Volume Threshold", and "Show Icon in Launcher" settings are grouped together. - `SettingsItem` composable is used to visually group related settings. - A spacer is added at the bottom of the scrollable content to account for bottom padding.
This commit refactors the foreground service control logic in `SettingsViewModel.kt`. - Renamed `startForegroundService()` to `enableForegroundService()` and `stopForegroundService()` to `disableForegroundService()` for clarity. - These methods now update the `service_running` preference via `preferenceRepository.setServiceRunning()` to accurately reflect the desired service state. This ensures the service's running state is persisted even if the service is killed by the system. - The `foregroundSwitch()` and `checkForegroundService()` methods have been updated to use these new function names.
This commit adds vertical spacing (16.dp) between some settings items in the `SettingsScreen` to improve visual separation.
This commit refactors the `SettingsScreen` and its components to improve visual consistency and user experience.
Key changes include:
- **TopAppBar Styling**:
- Switched from `MediumTopAppBar` to `TopAppBar` with a `pinnedScrollBehavior`.
- Updated `TopAppBar` colors to use `inversePrimary` for the container and `primary` for title and icons.
- Applied a custom style (bold, italic) to the app name in the `TopAppBar`.
- **Settings Item Styling**:
- Introduced `containerColor` parameter to `SettingsItem` for better theming flexibility.
- Set specific container colors for different groups of settings (e.g., `tertiaryContainer` for foreground service settings, `secondaryContainer` for watching and protection settings).
- Updated `SettingsItem` background to use `inversePrimary`.
- **Switch Component Styling**:
- Added `switchColor` parameter to `SwitchRow` to customize switch track color.
- `SwitchRow` description is now optional.
- **Slider Component Styling**:
- `RangeSlider` now fills the available width.
- Updated `RangeSlider` and `SliderValueIndicator` colors to align with the new theme (using `secondary` and `onSecondary` colors).
- Adjusted padding and width for `SliderValueIndicator` text for better layout.
- **Layout Adjustments**:
- Added top padding to the main `Column` in `SettingsScreen` to account for the `TopAppBar`.
- Removed `EnableForegroundRow` as its functionality is now integrated into `SettingsItem` and `SwitchRow`.
- Added a `Spacer` between the text content and the switch in `SwitchRow` for better visual separation.
- **Material3 Version**:
- Updated Material3 dependency to `1.4.0-alpha15`.
This commit updates the `TextContent` composable function to allow specifying a custom color. - The `TextContent` function now accepts an optional `color` parameter, which defaults to `MaterialTheme.colorScheme.secondary`. - In `SettingsScreen.kt`, the "Notification settings" `TextContent` now uses `MaterialTheme.colorScheme.tertiary` for its text. - The `SettingsToggleComponent` now passes its `switchColor` to the `TextContent` composable for consistent coloring.
This commit introduces several changes to the `WelcomeScreen`:
- **UI Update:**
- The TopAppBar and background colors are updated to use `inversePrimary` and `tertiaryContainer` from the MaterialTheme.
- Text color for section titles ("Necessary Permissions", "Optional Permissions") is set to `MaterialTheme.colorScheme.primary`.
- The switch color for the notification permission is set to `MaterialTheme.colorScheme.tertiary`.
- Added padding to the top of the content.
- **Navigation Change:**
- Upon clicking the "Finish" button, instead of finishing the current activity, the app now navigates to `MainActivity`.
- **Permission Request:**
- The `WelcomeScreen` now requests the `POST_NOTIFICATIONS` permission, which is necessary for Android 13 and higher to display notifications.
This commit enables the `generateLocaleConfig` option in the `androidResources` block of `app/build.gradle`. It also adds a `resources.properties` file to `app/src/main/res/` to specify `en-US` as the `unqualifiedResLocale`. This configuration helps ensure correct locale handling for resources.
This commit updates several string resources to improve clarity and provide Chinese translations for newly added strings. Key changes: - Renamed "Enable alert" to "Take a Break Reminder". - Renamed "Protect My Ears" to "Safe Volume Start". - Added `translatable="false"` to strings that should not be translated, such as `title_activity_main`, `icon_type`, `icon_type_description`, `hide_in_launcher`, and `title_activity_welcome`. - Updated the description for `show_icon_description` to mention potential system limitations in hiding the app icon. - Added new strings `enable_watching_detail` and `protection_detail` to provide more context for their respective features. - Added Chinese translations for new and existing strings including those related to notification settings, permissions, battery optimization, and feature details.
This commit updates the descriptive text for the "Enable Watching" and "Protection" switch rows in the `SettingsScreen`. Additionally, the color and padding of the settings group titles in `SettingsComponents.kt` have been adjusted.
This commit adds the `<monochrome>` element to the adaptive icon definitions (`ic_launcher.xml` and `ic_launcher_round.xml`). This allows the launcher icon to adapt to themed icon settings on supported Android versions, using `ic_launcher_foreground` as the drawable for the monochrome version.
This commit updates the following Gradle plugin versions: - Android Application and Library plugins to `8.9.3` - Kotlin Android plugin to `2.0.21` - KSP plugin to `2.0.21-1.0.26` - Kotlin Compose plugin to `2.0.21` - Dagger Hilt Android plugin to `2.56.2`
There was a problem hiding this comment.
Summary of Changes
Hello @Steve-Mr, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request represents a substantial architectural overhaul, migrating the application's UI to Jetpack Compose, integrating Dagger Hilt for dependency injection, and modernizing preference management with DataStore. It also includes comprehensive updates to the build system and refactors core service logic for improved reliability and maintainability.
Highlights
- UI Modernization: The application's user interface has been largely migrated from traditional Android Views to Jetpack Compose, introducing new
MainActivity,WelcomeActivity, and dedicated Compose screens for settings and onboarding, along with reusable UI components. - Architectural Enhancements: Dagger Hilt has been integrated for robust dependency injection, and preference management has transitioned from
SharedPreferencestoDataStorefor improved efficiency and type safety. - Build System & SDK Upgrade: The project's build environment has undergone significant updates, including newer Android Gradle Plugin, Kotlin, and Gradle versions, alongside the addition of Compose and Hilt-specific plugins and an upgrade to
compileSdkandtargetSdk35. - Service Reliability & Refinement: The core
ForegroundServicehas been refactored to leverage Kotlin Coroutines for asynchronous operations and WorkManager for reliable boot-time service startup. Its audio device monitoring and ear protection logic have also been refined for clarity and thread safety. - Dynamic App Icon Control: New product flavors and manifest configurations have been introduced to provide users with the option to dynamically hide or show the application's launcher icon.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request introduces a substantial refactoring of the application, migrating to Jetpack Compose for UI, Hilt for dependency injection, DataStore for preferences, and WorkManager for boot operations. The changes significantly modernize the codebase and improve its architecture, maintainability, and robustness. Key highlights include a cleaner ForegroundService with improved state management, a new WelcomeActivity for onboarding, and a Compose-based SettingsScreen. The state synchronization between the service, QSTile, and UI is well-handled. A few minor suggestions are provided, mainly concerning comments in non-English language.
app/src/main/java/com/maary/liveinpeace/receiver/BootCompleteReceiver.kt
Show resolved
Hide resolved
app/src/main/java/com/maary/liveinpeace/receiver/BootCompleteReceiver.kt
Show resolved
Hide resolved
app/src/main/java/com/maary/liveinpeace/receiver/BootCompleteReceiver.kt
Show resolved
Hide resolved
This commit introduces two product flavors, `iconEnabled` and `iconDisabled`, to control the initial visibility of the app icon in the launcher.
- **Build Flavors**:
- `iconEnabled`: Sets `mainActivityEnabled` to `true` in `AndroidManifest.xml` and defines `ICON_ENABLED` as `true` in `BuildConfig`.
- `iconDisabled`: Sets `mainActivityEnabled` to `false` in `AndroidManifest.xml` and defines `ICON_ENABLED` as `false` in `BuildConfig`.
- **PreferenceRepository**:
- The default value for `PREF_VISIBLE_IN_LAUNCHER` in `isIconShown()` and `toggleIconVisibility()` now uses `BuildConfig.ICON_ENABLED`.
- **APK Naming**:
- Updated APK naming convention to include flavor name, ABI (if applicable), and version name (e.g., `LiveInPeace-iconEnabled-arm64-v8a-1.0.apk`, `LiveInPeace-iconDisabled-universal-1.0.apk`).
- **ABI Configuration**:
- Modified ABI splits to only include `arm64-v8a` and enable `universalApk`.
- **Dependency Update**:
- Updated `com.google.dagger:hilt-compiler` to version `2.56.2`.
d79f9a5 to
f4fb9f3
Compare
This commit refactors the GitHub Actions workflow and the Telegram upload script: **GitHub Actions Workflow (`android.yml`):** - Updated artifact upload and download actions to `v4`. - Modified APK naming convention to include flavor (e.g., `iconEnabled`, `iconDisabled`) and ABI. - Updated artifact and release asset names to reflect the new APK naming. - Changed `asset_content_type` for release assets from `application/zip` to `application/vnd.android.package-archive`. - Adjusted environment variable names for APK paths to align with the new naming scheme. - Simplified some run commands by removing redundant `ls` calls. **Telegram Upload Script (`upload.py`):** - Refactored script to send APKs as a `MediaGroup` instead of individual documents. - Implemented `sendMediaGroup` function to handle sending multiple files. - Implemented `sendTextMessage` for sending formatted release messages. - The script now expects two APK paths (`APK_FILE_UPLOAD1`, `APK_FILE_UPLOAD2`) from environment variables. - The notification message now includes version name and commit message, retrieved from environment variables. - Removed unused `findString` and `genFileDirectory` functions. - The main execution block now constructs a formatted message with version and commit details and sends the APKs and the message to a predefined Telegram chat.
This commit removes the `SettingsReceiver` class and its associated constants. The receiver was previously used for handling settings changes via notifications, but this functionality is no longer needed.
- Deleted `SettingsReceiver.kt`.
- Removed `SettingsReceiver` declaration from `AndroidManifest.xml`.
- Deleted the following constants from `Constants.kt`:
- `ACTION_CANCEL`
- `ACTION_NAME_SET_IMG`
- `ACTION_NAME_SET_NUM`
- `ACTION_ENABLE_WATCHING`
- `ACTION_DISABLE_WATCHING`
- `ACTION_TOGGLE_AUTO_CONNECTION_ADJUSTMENT`
- `ACTION_NAME_SETTINGS`
This commit removes unused constants, imports, and code sections to improve maintainability and reduce clutter. Specifically, the following were removed: - Unused constants in `Constants.kt` related to icon modes, notification text size, and specific notification IDs. - Unused imports across several files including `ConnectionDao.kt`, `ConnectionRoomDatabase.kt`, `BootCompleteReceiver.kt`, `ForegroundService.kt`, `QSTileService.kt`, `ConnectionListAdapter.kt`, and various UI screens. - The unused `DropdownItem` and `DropdownRow` composables in `SettingsComponents.kt`. - Unused `java.sql.Date` import in `ConnectionDao.kt`. - Public modifier from `ConnectionRoomDatabase`. - Unused `Context.notificationManager()` extension function in `SleepNotification.kt` was made private. - Removed unused `VOLUME_ADJUST_ATTEMPTS` constant in `ForegroundService.kt`. - Cleaned up comments and TODOs in `HistoryActivity.kt`. - Simplified the `LiveInPeaceTheme` by removing an unnecessary `Build.VERSION.SDK_INT` check for dynamic colors.
…tive This commit addresses an issue where the Quick Settings (QS) tile might indicate the `ForegroundService` is running, even if the system has killed it. Now, if the QS tile is clicked and `ForegroundService.IS_SERVICE_RUNNING` is false despite the preference indicating it should be running, the `ForegroundService` is restarted. The tile state is then updated to reflect the actual running state of the service.
This commit updates the following: - `versionName` to `2025.06.20_01` - `androidx.compose:compose-bom` to `2025.06.01` - `androidx.compose.material3:material3` to `1.4.0-alpha16` - `androidx.room` dependencies to version `2.7.2` - `androidx.work:work-runtime-ktx` to `2.10.2`
This commit updates the Android CI workflow (`android.yml`) to improve the release process:
- **Release Tagging and Naming:** Releases are now tagged and named using the current date and a daily incrementing count (e.g., `release-YYYY-MM-DD-01`, `Release YYYY-MM-DD`). This replaces the previous `v${{ github.run_number }}` scheme.
- **Commit Log in Release Body:** The body of the GitHub release now includes the commit messages from the pull request using `steps.show_pr_commits.outputs.commits`.
- **Simplified Telegram Message:** The `upload.py` script has been modified to remove the commit message from the Telegram notification, as this information is now included in the GitHub release notes.
Summary
This pull request represents a comprehensive modernization of the entire application. It replaces the legacy View-based UI with Jetpack Compose, introduces Hilt for dependency injection, migrates from SharedPreferences to Jetpack DataStore for preferences, and refactors the background processing and CI/CD pipeline for improved robustness and maintainability.
The core user-facing changes include a completely new UI for settings, a new first-launch "Welcome" screen to handle permissions, and the ability to hide the app's launcher icon via build flavors.
Detailed Changes
Modern Architecture & Tech Stack
SettingsScreenandWelcomeScreenprovide a modern, reactive user experience. Close [feat] Settings Page #25 [feat] 添加启动引导 #24HistoryActivity.SharedPreferenceswithDataStorefor asynchronous and safer data persistence, managed through a newPreferenceRepository. Close [feat] 迁移到 preference datastore(低优先级) #26BootCompleteReceivernow uses aBootWorkerto reliably start the foreground service on device boot, following modern Android best practices.Build and CI/CD Pipeline Enhancements
iconEnabledandiconDisabledproduct flavors to control the visibility of the launcher icon using manifest placeholders.LiveInPeace-iconEnabled-arm64-v8a-2025.06.20_01.apk).android.yml) is updated to build and upload artifacts for the new product flavors.upload.py) is rewritten to send multiple APKs as asendMediaGroupmessage to Telegram, with a more detailed release message.Service & Receiver Refactoring
ForegroundServiceRewrite:CoroutineScopeand inject dependencies likePreferenceRepositoryvia Hilt.BROADCAST_ACTION_CONNECTIONS_UPDATE) to communicate state changes instead of direct listeners.QSTileServiceImprovements:onStartListeningby comparing its persisted state (from DataStore) with the service's actual running state, reliably handling cases where the service is killed by the system.HistoryActivityuses aBroadcastReceiverto receive live updates from theForegroundService, making the communication more robust and decoupled.Connectiondata class now implementsParcelablefor efficient data transfer.Code Cleanup and Simplification
ConnectionsApplication,HistoryActivity, and theSettingsReceiver.LiveInPeaceApplicationclass.Constants.ktfile.