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
+54
View File
@@ -2395,6 +2395,60 @@ abstract class AppLocalizations {
/// In es, this message translates to:
/// **'Conectado'**
String get eqDeviceConnected;
/// No description provided for @localMusicSectionTitle.
///
/// In es, this message translates to:
/// **'Música local (Android Auto)'**
String get localMusicSectionTitle;
/// No description provided for @localMusicSectionDescription.
///
/// In es, this message translates to:
/// **'Elegí una carpeta de este dispositivo para explorar y reproducir sus archivos de audio desde el auto.'**
String get localMusicSectionDescription;
/// No description provided for @localMusicFolderNotConfigured.
///
/// In es, this message translates to:
/// **'No hay carpeta seleccionada'**
String get localMusicFolderNotConfigured;
/// No description provided for @localMusicFolderTitle.
///
/// In es, this message translates to:
/// **'Carpeta de música local'**
String get localMusicFolderTitle;
/// No description provided for @localMusicChoosePath.
///
/// In es, this message translates to:
/// **'Elegir carpeta'**
String get localMusicChoosePath;
/// No description provided for @localMusicChangePath.
///
/// In es, this message translates to:
/// **'Cambiar carpeta'**
String get localMusicChangePath;
/// No description provided for @localMusicFolderUpdated.
///
/// In es, this message translates to:
/// **'Carpeta de música local actualizada'**
String get localMusicFolderUpdated;
/// No description provided for @localMusicFolderSaveError.
///
/// In es, this message translates to:
/// **'No se pudo guardar la carpeta: {error}'**
String localMusicFolderSaveError(Object error);
/// No description provided for @localMusicFolderGenericName.
///
/// In es, this message translates to:
/// **'Carpeta seleccionada'**
String get localMusicFolderGenericName;
}
class _AppLocalizationsDelegate
+34 -4
View File
@@ -63,22 +63,22 @@ class AppLocalizationsAr extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours ? $minutes ? $seconds ?';
return '$hours س $minutes د $seconds ث';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes ? $seconds ?';
return '$minutes د $seconds ث';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes ?';
return '$minutes د';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds ?';
return '$seconds ث';
}
@override
@@ -1297,4 +1297,34 @@ class AppLocalizationsAr extends AppLocalizations {
@override
String get eqDeviceConnected => 'متصل';
@override
String get localMusicSectionTitle => 'الموسيقى المحلية (Android Auto)';
@override
String get localMusicSectionDescription =>
'اختر مجلدًا على هذا الجهاز لتصفح ملفاته الصوتية وتشغيلها من السيارة.';
@override
String get localMusicFolderNotConfigured => 'لم يتم تحديد مجلد';
@override
String get localMusicFolderTitle => 'مجلد الموسيقى المحلية';
@override
String get localMusicChoosePath => 'اختيار مجلد';
@override
String get localMusicChangePath => 'تغيير المجلد';
@override
String get localMusicFolderUpdated => 'تم تحديث مجلد الموسيقى المحلية';
@override
String localMusicFolderSaveError(Object error) {
return 'تعذّر حفظ المجلد: $error';
}
@override
String get localMusicFolderGenericName => 'مجلد محدد';
}
+34 -4
View File
@@ -64,22 +64,22 @@ class AppLocalizationsBn extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours ? $minutes ?? $seconds ??';
return '$hours ঘণ্টা $minutes মিনিট $seconds সেকেন্ড';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes ?? $seconds ??';
return '$minutes মিনিট $seconds সেকেন্ড';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes ??';
return '$minutes মিনিট';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds ??';
return '$seconds সেকেন্ড';
}
@override
@@ -1305,4 +1305,34 @@ class AppLocalizationsBn extends AppLocalizations {
@override
String get eqDeviceConnected => 'সংযুক্ত';
@override
String get localMusicSectionTitle => 'স্থানীয় সঙ্গীত (Android Auto)';
@override
String get localMusicSectionDescription =>
'গাড়িতে অডিও ফাইল ব্রাউজ ও চালানোর জন্য এই ডিভাইসের একটি ফোল্ডার বেছে নিন।';
@override
String get localMusicFolderNotConfigured => 'কোনো ফোল্ডার নির্বাচিত হয়নি';
@override
String get localMusicFolderTitle => 'স্থানীয় সঙ্গীত ফোল্ডার';
@override
String get localMusicChoosePath => 'ফোল্ডার বেছে নিন';
@override
String get localMusicChangePath => 'ফোল্ডার পরিবর্তন করুন';
@override
String get localMusicFolderUpdated => 'স্থানীয় সঙ্গীত ফোল্ডার আপডেট হয়েছে';
@override
String localMusicFolderSaveError(Object error) {
return 'ফোল্ডার সংরক্ষণ করা যায়নি: $error';
}
@override
String get localMusicFolderGenericName => 'নির্বাচিত ফোল্ডার';
}
+30
View File
@@ -1315,4 +1315,34 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get eqDeviceConnected => 'Verbunden';
@override
String get localMusicSectionTitle => 'Lokale Musik (Android Auto)';
@override
String get localMusicSectionDescription =>
'Wähle einen Ordner auf diesem Gerät aus, um dessen Audiodateien im Auto zu durchsuchen und abzuspielen.';
@override
String get localMusicFolderNotConfigured => 'Kein Ordner ausgewählt';
@override
String get localMusicFolderTitle => 'Ordner für lokale Musik';
@override
String get localMusicChoosePath => 'Ordner auswählen';
@override
String get localMusicChangePath => 'Ordner ändern';
@override
String get localMusicFolderUpdated => 'Ordner für lokale Musik aktualisiert';
@override
String localMusicFolderSaveError(Object error) {
return 'Ordner konnte nicht gespeichert werden: $error';
}
@override
String get localMusicFolderGenericName => 'Ausgewählter Ordner';
}
+30
View File
@@ -1301,4 +1301,34 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get eqDeviceConnected => 'Connected';
@override
String get localMusicSectionTitle => 'Local music (Android Auto)';
@override
String get localMusicSectionDescription =>
'Pick a folder on this device to browse and play its audio files from the car.';
@override
String get localMusicFolderNotConfigured => 'No folder selected';
@override
String get localMusicFolderTitle => 'Local music folder';
@override
String get localMusicChoosePath => 'Choose folder';
@override
String get localMusicChangePath => 'Change folder';
@override
String get localMusicFolderUpdated => 'Local music folder updated';
@override
String localMusicFolderSaveError(Object error) {
return 'Could not save the folder: $error';
}
@override
String get localMusicFolderGenericName => 'Selected folder';
}
+30
View File
@@ -1310,4 +1310,34 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get eqDeviceConnected => 'Conectado';
@override
String get localMusicSectionTitle => 'Música local (Android Auto)';
@override
String get localMusicSectionDescription =>
'Elegí una carpeta de este dispositivo para explorar y reproducir sus archivos de audio desde el auto.';
@override
String get localMusicFolderNotConfigured => 'No hay carpeta seleccionada';
@override
String get localMusicFolderTitle => 'Carpeta de música local';
@override
String get localMusicChoosePath => 'Elegir carpeta';
@override
String get localMusicChangePath => 'Cambiar carpeta';
@override
String get localMusicFolderUpdated => 'Carpeta de música local actualizada';
@override
String localMusicFolderSaveError(Object error) {
return 'No se pudo guardar la carpeta: $error';
}
@override
String get localMusicFolderGenericName => 'Carpeta seleccionada';
}
+30
View File
@@ -1320,4 +1320,34 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get eqDeviceConnected => 'Connecté';
@override
String get localMusicSectionTitle => 'Musique locale (Android Auto)';
@override
String get localMusicSectionDescription =>
'Choisissez un dossier sur cet appareil pour parcourir et lire ses fichiers audio depuis la voiture.';
@override
String get localMusicFolderNotConfigured => 'Aucun dossier sélectionné';
@override
String get localMusicFolderTitle => 'Dossier de musique locale';
@override
String get localMusicChoosePath => 'Choisir un dossier';
@override
String get localMusicChangePath => 'Changer de dossier';
@override
String get localMusicFolderUpdated => 'Dossier de musique locale mis à jour';
@override
String localMusicFolderSaveError(Object error) {
return 'Impossible denregistrer le dossier : $error';
}
@override
String get localMusicFolderGenericName => 'Dossier sélectionné';
}
+34 -4
View File
@@ -63,22 +63,22 @@ class AppLocalizationsHi extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours ?? $minutes ?? $seconds ??';
return '$hours घंटे $minutes मिनट $seconds सेकंड';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes ?? $seconds ??';
return '$minutes मिनट $seconds सेकंड';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes ??';
return '$minutes मिनट';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds ??';
return '$seconds सेकंड';
}
@override
@@ -1303,4 +1303,34 @@ class AppLocalizationsHi extends AppLocalizations {
@override
String get eqDeviceConnected => 'कनेक्टेड';
@override
String get localMusicSectionTitle => 'स्थानीय संगीत (Android Auto)';
@override
String get localMusicSectionDescription =>
'गाड़ी में ऑडियो फ़ाइलें ब्राउज़ और चलाने के लिए इस डिवाइस का एक फ़ोल्डर चुनें।';
@override
String get localMusicFolderNotConfigured => 'कोई फ़ोल्डर चुना नहीं गया';
@override
String get localMusicFolderTitle => 'स्थानीय संगीत फ़ोल्डर';
@override
String get localMusicChoosePath => 'फ़ोल्डर चुनें';
@override
String get localMusicChangePath => 'फ़ोल्डर बदलें';
@override
String get localMusicFolderUpdated => 'स्थानीय संगीत फ़ोल्डर अपडेट हुआ';
@override
String localMusicFolderSaveError(Object error) {
return 'फ़ोल्डर सहेजा नहीं जा सका: $error';
}
@override
String get localMusicFolderGenericName => 'चयनित फ़ोल्डर';
}
+30
View File
@@ -1309,4 +1309,34 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get eqDeviceConnected => 'Terhubung';
@override
String get localMusicSectionTitle => 'Musik lokal (Android Auto)';
@override
String get localMusicSectionDescription =>
'Pilih folder di perangkat ini untuk menjelajahi dan memutar file audio di dalamnya dari mobil.';
@override
String get localMusicFolderNotConfigured => 'Belum ada folder dipilih';
@override
String get localMusicFolderTitle => 'Folder musik lokal';
@override
String get localMusicChoosePath => 'Pilih folder';
@override
String get localMusicChangePath => 'Ubah folder';
@override
String get localMusicFolderUpdated => 'Folder musik lokal diperbarui';
@override
String localMusicFolderSaveError(Object error) {
return 'Tidak dapat menyimpan folder: $error';
}
@override
String get localMusicFolderGenericName => 'Folder terpilih';
}
+30
View File
@@ -1315,4 +1315,34 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get eqDeviceConnected => 'Connesso';
@override
String get localMusicSectionTitle => 'Musica locale (Android Auto)';
@override
String get localMusicSectionDescription =>
'Scegli una cartella su questo dispositivo per sfogliare e riprodurre i suoi file audio dall\'auto.';
@override
String get localMusicFolderNotConfigured => 'Nessuna cartella selezionata';
@override
String get localMusicFolderTitle => 'Cartella musica locale';
@override
String get localMusicChoosePath => 'Scegli cartella';
@override
String get localMusicChangePath => 'Cambia cartella';
@override
String get localMusicFolderUpdated => 'Cartella musica locale aggiornata';
@override
String localMusicFolderSaveError(Object error) {
return 'Impossibile salvare la cartella: $error';
}
@override
String get localMusicFolderGenericName => 'Cartella selezionata';
}
+34 -4
View File
@@ -62,22 +62,22 @@ class AppLocalizationsJa extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours?? $minutes? $seconds?';
return '$hours時間$minutes分$seconds秒';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes? $seconds?';
return '$minutes分$seconds秒';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes?';
return '$minutes分';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds?';
return '$seconds秒';
}
@override
@@ -1263,4 +1263,34 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get eqDeviceConnected => '接続中';
@override
String get localMusicSectionTitle => 'ローカル音楽(Android Auto';
@override
String get localMusicSectionDescription =>
'この端末のフォルダーを選択して、車内でその音声ファイルを閲覧・再生します。';
@override
String get localMusicFolderNotConfigured => 'フォルダーが選択されていません';
@override
String get localMusicFolderTitle => 'ローカル音楽フォルダー';
@override
String get localMusicChoosePath => 'フォルダーを選択';
@override
String get localMusicChangePath => 'フォルダーを変更';
@override
String get localMusicFolderUpdated => 'ローカル音楽フォルダーを更新しました';
@override
String localMusicFolderSaveError(Object error) {
return 'フォルダーを保存できませんでした: $error';
}
@override
String get localMusicFolderGenericName => '選択したフォルダー';
}
+30
View File
@@ -1307,4 +1307,34 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get eqDeviceConnected => 'Conectado';
@override
String get localMusicSectionTitle => 'Música local (Android Auto)';
@override
String get localMusicSectionDescription =>
'Escolha uma pasta neste dispositivo para navegar e reproduzir os arquivos de áudio dela no carro.';
@override
String get localMusicFolderNotConfigured => 'Nenhuma pasta selecionada';
@override
String get localMusicFolderTitle => 'Pasta de música local';
@override
String get localMusicChoosePath => 'Escolher pasta';
@override
String get localMusicChangePath => 'Alterar pasta';
@override
String get localMusicFolderUpdated => 'Pasta de música local atualizada';
@override
String localMusicFolderSaveError(Object error) {
return 'Não foi possível salvar a pasta: $error';
}
@override
String get localMusicFolderGenericName => 'Pasta selecionada';
}
+34 -4
View File
@@ -63,22 +63,22 @@ class AppLocalizationsRu extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours ? $minutes ??? $seconds ?';
return '$hours ч $minutes мин $seconds сек';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes ??? $seconds ?';
return '$minutes мин $seconds сек';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes ???';
return '$minutes мин';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds ?';
return '$seconds сек';
}
@override
@@ -1311,4 +1311,34 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get eqDeviceConnected => 'Подключено';
@override
String get localMusicSectionTitle => 'Локальная музыка (Android Auto)';
@override
String get localMusicSectionDescription =>
'Выберите папку на этом устройстве, чтобы просматривать и воспроизводить её аудиофайлы в автомобиле.';
@override
String get localMusicFolderNotConfigured => 'Папка не выбрана';
@override
String get localMusicFolderTitle => 'Папка локальной музыки';
@override
String get localMusicChoosePath => 'Выбрать папку';
@override
String get localMusicChangePath => 'Изменить папку';
@override
String get localMusicFolderUpdated => 'Папка локальной музыки обновлена';
@override
String localMusicFolderSaveError(Object error) {
return 'Не удалось сохранить папку: $error';
}
@override
String get localMusicFolderGenericName => 'Выбранная папка';
}
+33 -4
View File
@@ -62,22 +62,22 @@ class AppLocalizationsZh extends AppLocalizations {
Object minutes,
Object seconds,
) {
return '$hours ?? $minutes ? $seconds ?';
return '$hours小时$minutes分钟$seconds秒';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes ? $seconds ?';
return '$minutes分钟$seconds秒';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes ?';
return '$minutes分钟';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds ?';
return '$seconds秒';
}
@override
@@ -1256,4 +1256,33 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get eqDeviceConnected => '已连接';
@override
String get localMusicSectionTitle => '本地音乐(Android Auto';
@override
String get localMusicSectionDescription => '选择此设备上的一个文件夹,以便在车内浏览和播放其中的音频文件。';
@override
String get localMusicFolderNotConfigured => '未选择文件夹';
@override
String get localMusicFolderTitle => '本地音乐文件夹';
@override
String get localMusicChoosePath => '选择文件夹';
@override
String get localMusicChangePath => '更改文件夹';
@override
String get localMusicFolderUpdated => '本地音乐文件夹已更新';
@override
String localMusicFolderSaveError(Object error) {
return '无法保存文件夹:$error';
}
@override
String get localMusicFolderGenericName => '已选文件夹';
}