fix(auto): clear stuck bluetooth EQ selection on device disconnect
Build & Deploy PluriWave / Análisis de código (push) Successful in 24s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 1m40s

The advanced EQ device list kept the green-dot selection on the last
connected Bluetooth device after it disconnected, instead of falling
back to the default preset.

- MainActivity.kt: onAudioDevicesRemoved recomputed the active output
  device via AudioManager.getDevices(), which can still momentarily
  report the just-removed sink (observed on Bluetooth A2DP). Removed
  device ids are now excluded explicitly instead of trusting
  getDevices() to already be current.
- estado_ecualizador.dart: cambiarMultiDeviceEnabled() re-seeds
  dispositivoActualId from a fresh query when the toggle turns back
  on, matching cargarPersistido(), so a stale id from before the
  toggle flip can't leave the dot pinned to a disconnected device.
This commit is contained in:
Javier Bautista Fernández
2026-07-20 12:03:59 +02:00
parent 09e0216874
commit 7daa6cfdb6
2 changed files with 16 additions and 3 deletions
@@ -1051,7 +1051,12 @@ class MainActivity : AudioServiceActivity() {
override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) { override fun onAudioDevicesRemoved(removedDevices: Array<out AudioDeviceInfo>) {
// Emit the new active device after something disconnects. // Emit the new active device after something disconnects.
val device = getActiveAudioDevice() // AudioManager.getDevices() can still momentarily report a
// just-removed sink (observed on Bluetooth A2DP), so the
// removed ids are excluded explicitly instead of trusting
// getDevices() to already be up to date.
val excludedIds = removedDevices.map { it.id }.toSet()
val device = getActiveAudioDevice(excludeIds = excludedIds)
Log.d(tag, "audio_devices.onDevicesRemoved active=$device") Log.d(tag, "audio_devices.onDevicesRemoved active=$device")
mainHandler.post { audioDevicesSink?.success(device) } mainHandler.post { audioDevicesSink?.success(device) }
} }
@@ -1083,7 +1088,7 @@ class MainActivity : AudioServiceActivity() {
* *
* Type int values sent to Dart match the AudioDeviceInfo.TYPE_* constants. * Type int values sent to Dart match the AudioDeviceInfo.TYPE_* constants.
*/ */
private fun getActiveAudioDevice(): Map<String, Any> { private fun getActiveAudioDevice(excludeIds: Set<Int> = emptySet()): Map<String, Any> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return mapOf("id" to "builtin_speaker", "type" to 2, "name" to "Speaker") return mapOf("id" to "builtin_speaker", "type" to 2, "name" to "Speaker")
} }
@@ -1099,7 +1104,7 @@ class MainActivity : AudioServiceActivity() {
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
) )
val best = outputs val best = outputs
.filter { it.isSink } .filter { it.isSink && it.id !in excludeIds }
.sortedBy { device -> .sortedBy { device ->
val idx = priorityOrder.indexOf(device.type) val idx = priorityOrder.indexOf(device.type)
if (idx == -1) Int.MAX_VALUE else idx if (idx == -1) Int.MAX_VALUE else idx
+8
View File
@@ -274,6 +274,14 @@ class EstadoEcualizador extends ChangeNotifier {
_eqMultiDeviceEnabled = habilitado; _eqMultiDeviceEnabled = habilitado;
await servicio.guardarToggleMultiDispositivo(habilitado); await servicio.guardarToggleMultiDispositivo(habilitado);
_configurarSuscripcionDispositivo(); _configurarSuscripcionDispositivo();
// Re-seed the active device from a fresh query instead of leaving a
// stale _dispositivoActualId from before the toggle flip (it would
// otherwise only self-correct on the next native device-change event).
if (_eqMultiDeviceEnabled) {
await _sembrarDispositivoActual();
}
if (notificar) notifyListeners(); if (notificar) notifyListeners();
} }