From 7daa6cfdb618f3e9e8a89e4df4d82d66ae33eec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Bautista=20Fern=C3=A1ndez?= Date: Mon, 20 Jul 2026 12:03:46 +0200 Subject: [PATCH] fix(auto): clear stuck bluetooth EQ selection on device disconnect 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. --- .../kotlin/es/freetimelab/pluriwave/MainActivity.kt | 11 ++++++++--- lib/estado/estado_ecualizador.dart | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/kotlin/es/freetimelab/pluriwave/MainActivity.kt b/android/app/src/main/kotlin/es/freetimelab/pluriwave/MainActivity.kt index 8194710..c42430a 100644 --- a/android/app/src/main/kotlin/es/freetimelab/pluriwave/MainActivity.kt +++ b/android/app/src/main/kotlin/es/freetimelab/pluriwave/MainActivity.kt @@ -1051,7 +1051,12 @@ class MainActivity : AudioServiceActivity() { override fun onAudioDevicesRemoved(removedDevices: Array) { // 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") mainHandler.post { audioDevicesSink?.success(device) } } @@ -1083,7 +1088,7 @@ class MainActivity : AudioServiceActivity() { * * Type int values sent to Dart match the AudioDeviceInfo.TYPE_* constants. */ - private fun getActiveAudioDevice(): Map { + private fun getActiveAudioDevice(excludeIds: Set = emptySet()): Map { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return mapOf("id" to "builtin_speaker", "type" to 2, "name" to "Speaker") } @@ -1099,7 +1104,7 @@ class MainActivity : AudioServiceActivity() { AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, ) val best = outputs - .filter { it.isSink } + .filter { it.isSink && it.id !in excludeIds } .sortedBy { device -> val idx = priorityOrder.indexOf(device.type) if (idx == -1) Int.MAX_VALUE else idx diff --git a/lib/estado/estado_ecualizador.dart b/lib/estado/estado_ecualizador.dart index 19c8dd7..2d9559d 100644 --- a/lib/estado/estado_ecualizador.dart +++ b/lib/estado/estado_ecualizador.dart @@ -274,6 +274,14 @@ class EstadoEcualizador extends ChangeNotifier { _eqMultiDeviceEnabled = habilitado; await servicio.guardarToggleMultiDispositivo(habilitado); _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(); }