Conversation
This commit introduces the ability to record and display the media volume before a device connects and after it disconnects.
- **Database:**
- The `Connection` entity is updated with `startVolume` and `endVolume` fields to store volume percentages.
- The database version is bumped to `2`, and a migration (`MIGRATION_1_2`) is added to alter the `connection_table` with the new `start_volume` and `end_volume` columns.
- **UI:**
- A new `TextView` (`text_volume_log`) is added to the `item_connection.xml` layout to display the volume change.
- The `ConnectionListAdapter` is updated to bind the `startVolume` and `endVolume` data to the new `TextView`, showing it only when the data is available.
This commit introduces a new feature that saves the system volume when a wired headset is connected and restores it after disconnection. This includes: - A new toggle in the settings screen to enable or disable this feature. - `DataStore` preferences to store the feature's enabled state and the last known system volume. - Updates to the `SettingsViewModel` and `PreferenceRepository` to handle the logic for storing and retrieving these new settings.
This commit refactors the volume restoration logic to be more reliable and introduces several key improvements:
- **Delayed Volume Restoration:** When a device disconnects, the service now waits 600ms before restoring the volume. This delay allows the system to switch audio output back to the internal speakers, ensuring the correct volume is restored.
- **Improved Volume Capture:**
- The `startVolume` (volume when a device connects) is now recorded.
- The `endVolume` (system volume after a device disconnects) is also recorded.
- **System Volume Tracking:**
- The service now caches the system's speaker volume when no devices are connected.
- This cached volume is used as the `startVolume` for a new connection if it's the first one, providing a more accurate restoration point.
- **Conditional Restoration:** The volume restoration now only occurs if all Bluetooth audio devices are disconnected, preventing interference when switching between different headphones.
- **Code Cleanup:** Added a `percentageToVolumeIndex` helper function for cleaner volume calculations and removed commented-out legacy code.
This commit adds new string resources for the "Restore Volume on Disconnect" feature. - `volume_log_format`: A format string to log volume changes. - `restore_system_volume`: The title for the feature toggle. - `restore_volume_description`: A description explaining what the feature does, noting it's experimental. Translations for Simplified Chinese are also included.
This commit updates various dependencies to their latest versions and increments the app version.
**Version Changes:**
- `versionCode` increased from `5` to `6`.
- `versionName` updated from `2025.09.21` to `2025.12.04`.
**Dependency Updates:**
- **Kotlin:**
- `org.jetbrains.kotlin.android` plugin to `2.2.21`.
- `org.jetbrains.kotlin.plugin.compose` plugin to `2.2.21`.
- **KSP:**
- `com.google.devtools.ksp` plugin to `2.2.21-2.0.4`.
- **Dagger Hilt:**
- `com.google.dagger.hilt.android` plugin and dependencies to `2.57.2`.
- **AndroidX Activity:**
- `androidx.activity:activity-ktx` and `androidx.activity:activity-compose` to `1.12.1`.
- **AndroidX Lifecycle:**
- All `androidx.lifecycle` artifacts to `2.10.0`.
- **AndroidX Compose:**
- `androidx.compose:compose-bom` to `2025.12.00`.
- `androidx.compose.material3:material3` to `1.4.0`.
- **AndroidX Room:**
- All `androidx.room` artifacts to `2.8.4`.
- **AndroidX WorkManager:**
- `androidx.work:work-runtime-ktx` to `2.11.0`.
- **AndroidX Databinding:**
- `androidx.databinding:databinding-runtime` to `8.13.1`.
- **AndroidX DataStore:**
- `androidx.datastore:datastore-preferences` to `1.2.0`.
Summary of ChangesHello @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 introduces a significant feature set focused on audio volume management during device connections. It enables the application to monitor and log system volume changes when devices connect and disconnect, and provides users with an experimental option to automatically revert the volume to its initial state after disconnection. These changes are supported by necessary database schema updates, user interface modifications to display volume history, and a comprehensive update of various core Android and third-party libraries to their latest versions. Highlights
Using Gemini Code AssistThe 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 by creating a comment using either
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 Limitations & Feedback Gemini Code Assist 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. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. 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
|
There was a problem hiding this comment.
Code Review
This pull request introduces a valuable feature for tracking and restoring volume, complete with a database migration and significant dependency upgrades. The implementation is solid, especially the clever use of a delay in ForegroundService to handle audio output switching. My review focuses on enhancing the clarity and robustness of the new logic, with suggestions to improve maintainability by removing magic numbers and clarifying control flow.
| if (startVol == null || endVol == null) connectionVolumeLogView.visibility = View.GONE | ||
| else { | ||
| val startVolString = startVol.toString() | ||
| val endVolString = endVol.toString() | ||
| connectionVolumeLogView.visibility = View.VISIBLE | ||
| connectionVolumeLogView.text = itemView.context.getString(R.string.volume_log_format, startVolString, endVolString) | ||
| } |
There was a problem hiding this comment.
This block can be simplified. You can remove the intermediate startVolString and endVolString variables, as getString can directly accept the Int? values and will call toString() on them. This makes the code more concise and idiomatic.
if (startVol == null || endVol == null) {
connectionVolumeLogView.visibility = View.GONE
} else {
connectionVolumeLogView.visibility = View.VISIBLE
connectionVolumeLogView.text = itemView.context.getString(R.string.volume_log_format, startVol, endVol)
}| fun getLastSystemVolume(): Flow<Int> = datastore.data | ||
| .map { preferences -> preferences[PREF_LAST_SYSTEM_VOLUME] ?: -1 } |
There was a problem hiding this comment.
This function uses -1 as a default value to indicate that no volume has been saved. While functional, this "magic number" can make the code harder to understand for others who might not know its special meaning. It's a best practice to define such special values as named constants.
I recommend adding a constant like const val VOLUME_NOT_SET = -1 to your Constants.kt file and using it here and in ForegroundService where you check if (savedVolume != -1). This will make the code more self-documenting and maintainable.
| fun getLastSystemVolume(): Flow<Int> = datastore.data | |
| .map { preferences -> preferences[PREF_LAST_SYSTEM_VOLUME] ?: -1 } | |
| fun getLastSystemVolume(): Flow<Int> = datastore.data | |
| .map { preferences -> preferences[PREF_LAST_SYSTEM_VOLUME] ?: Constants.VOLUME_NOT_SET } |
| if (connectionToSave != null) { | ||
| // [核心修改] 延迟 600ms,等待系统将音频输出切换回扬声器并更新音量状态 | ||
| // 具体的毫秒数可能因机型而异,500-800ms 通常是安全的 | ||
| delay(600) |
There was a problem hiding this comment.
Using a fixed delay(600) is a good pragmatic approach for this experimental feature, but it can be fragile. On some devices or under heavy load, this delay might not be sufficient, leading to an incorrect endVolume being recorded. On faster devices, it adds an unnecessary wait.
For future improvement, you might consider a more robust mechanism. For example, you could listen for the AudioManager.ACTION_AUDIO_BECOMING_NOISY broadcast intent, which signals that the audio output is about to change. This would provide a more reliable trigger than a fixed delay. For now, the current implementation is a reasonable starting point.
| return finalConnection | ||
| } | ||
|
|
||
| return connectionToSave |
There was a problem hiding this comment.
The statement return connectionToSave on this line is slightly confusing. If the if (connectionToSave != null) block above is entered, finalConnection is returned and this line is unreachable. If the if block is skipped, connectionToSave is null at this point.
To improve code clarity and explicitly show that null is returned in that case, it's better to return null directly.
| return connectionToSave | |
| return null |
Summary
This PR introduces a new feature to record the system volume level at the start and end of a device connection session. It also adds an experimental setting to automatically restore the system volume to its pre-connection level when a device disconnects. Additionally, this update includes a database migration, UI updates to display volume logs, and a comprehensive upgrade of project dependencies (Kotlin, Compose, Room, Hilt).
Changes
New Features & Logic
Connectionentity now includesstartVolumeandendVolumefields to store volume percentages.MIGRATION_1_2to add the new volume columns to the existing table.ForegroundServiceto capture volume before connection and after disconnection.PREF_RESTORE_VOLUMEandPREF_LAST_SYSTEM_VOLUME.UI Updates
ConnectionListAdapteranditem_connection.xmlto display volume logs (e.g., "Vol: 20% -> 50%") for past connections.Dependency & Build Updates
versionCodeto 6 andversionNameto "2025.12.04".2.2.21and KSP to2.2.21-2.0.4.2025.12.00.2.8.4) libraries.2.57.2.