feat(eq): android auto custom equalizer and robust device detection
Build & Deploy PluriWave / Análisis de código (push) Successful in 26s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m16s

- MainActivity: onListen re-emits the current active device and registers
  the audio device callback idempotently, so recreated activities resync
  instead of freezing the active-device id on a disconnected device.
- servicio_dispositivo_audio: resubscribir() re-opens the event channel;
  estado_ecualizador exposes refrescarDispositivoActual() with an
  in-flight guard, invoked on app resume and when opening advanced EQ
  options, clearing stale green-dot device selections.
- navegacion_auto/servicio_audio: new 'Personalizado' browse tree in
  Android Auto (5 band folders, 13 gain steps each) applied live via
  setBanda; preset and gain taps persist at device level when
  multi-device EQ is active and respect station/matrix overrides,
  with apply-before-persist ordering and children-changed notifications.
- l10n: regenerate stale generated localizations; add rxdart as direct
  dependency for the subscribeToChildren override.
This commit is contained in:
Javier Bautista Fernández
2026-07-22 10:26:02 +02:00
parent 3473034b58
commit 163ff69f7a
29 changed files with 1883 additions and 42 deletions
@@ -1014,6 +1014,15 @@ class MainActivity : AudioServiceActivity() {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
audioDevicesSink = events
registerAudioDeviceCallback()
// Immediate resync: emit the current active device on every
// (re)subscription. The Flutter engine outlives the Activity
// (AudioServiceActivity), so a recreated Activity installs a
// fresh StreamHandler that never sees a "listen" until Dart
// resubscribes — without this emission the Dart side would
// keep a stale device until the next physical connect event.
val device = getActiveAudioDevice()
Log.d(tag, "audio_devices.onListen -> $device")
events?.success(device)
}
override fun onCancel(arguments: Any?) {
@@ -1041,6 +1050,9 @@ class MainActivity : AudioServiceActivity() {
private fun registerAudioDeviceCallback() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
// Idempotent: a re-listen without a prior cancel must not leak the
// previously registered callback.
audioDeviceCallback?.let { audioManager.unregisterAudioDeviceCallback(it) }
val callback = object : AudioDeviceCallback() {
override fun onAudioDevicesAdded(addedDevices: Array<out AudioDeviceInfo>) {
// Emit the current active output device when something connects.