72a291d0c0e426936af109fd1883538629e505d0
The equalizer drawables were never in the shipped binary. Verified by
pulling base.apk off the device and reading it:
res/drawable/ic_stat_pluriwave.xml PRESENT (added 02-07)
res/drawable/ic_auto_eq_on.xml ABSENT (added 31-07, 2540556)
res/drawable/ic_auto_eq_off.xml ABSENT
Neither as a zip entry nor as a name in resources.arsc. Both files are in
git with content and on disk; the older sibling in the same folder is in
the APK. The difference is when they were added.
This runner is self-hosted and the workflow never cleaned, so build/
survives between runs and Gradle's incremental resource merge went stale:
resources present when the cache was built kept working, resources added
afterwards silently never made it in.
The cost was weeks of wrong diagnosis. getResourceId returned 0 for that
icon, PlaybackStateCompat.CustomAction.Builder throws on a 0 icon, and
that throw aborts AudioService.setState BEFORE mediaSession.setActive --
so Android Auto held a frozen, inactive session. On the device that
surfaced as a dead playback screen, a play button that never became
pause, PluriWave losing its pane to whichever app did have an active
session, and audio that played "as if it were not the app". One cause,
four symptoms.
Dart changes always shipped because Dart is recompiled every build, which
is exactly why this hid for so long: every fix appeared to land and
nothing behaved differently.
flutter clean costs build time. It buys the guarantee that what is in git
is what is in the binary, which this project just spent weeks not having.
PluriWave
Radio mundial con ecualizador personalizable, reconocimiento de canciones y UI premium.
Features
- +53.000 emisoras de 238 países (Radio Browser API)
- Ecualizador por emisora — guarda tu preset favorito para cada radio
- Reconocimiento de canciones — "¿Qué suena?" sin salir de la app
- Timer de auto-apagado — perfecto para dormir
- Reproducción en segundo plano — sigue sonando con la pantalla apagada
- Favoritos — acceso rápido a emisoras preferidas
- Compartir — envía emisoras a tus amigos
- UI premium — Material You, visualizador de audio, animaciones fluidas
Monetización
- 14 días PRO gratis al instalar
- Free: radio + favoritos + timer + background (con ads)
- PRO €2.99/año: sin ads + ecualizador + reconocimiento ilimitado
Stack
- Frontend: Flutter (Android + iOS)
- Radio API: Radio Browser (gratis, +53K emisoras)
- Audio: just_audio + audio_service
- Ecualizador: just_audio equalizer (Android nativo)
- Reconocimiento: AudD API (1000 req/mes free)
- Ads: Google AdMob
- Compras: in_app_purchase
CI/CD
Workflow Gitea Actions en .gitea/workflows/ci.yml, runner macmini-flutter.
Jobs: flutter pub get → flutter test → build apk --release → build appbundle --release
Artifacts: APK y AAB guardados en Gitea con nombre pluriwave-apk-<sha> / pluriwave-aab-<sha>.
Notificaciones: Telegram al completar (éxito ✅ / fallo ❌).
Secrets necesarios en el repo:
| Secret | Uso |
|---|---|
TELEGRAM_BOT_TOKEN |
Notificaciones CI |
TELEGRAM_CHAT_ID |
Canal de destino |
Signing: build de release usa clave debug (válido para CI interno). Para Play Store se requiere keystore como secret adicional.
Desarrollador
FreeTimeLab — freetimelab.es
Licencia
MIT
Description
PluriWave — Radio mundial con ecualizador, reconocimiento de canciones y UI premium
49 MiB
Languages
Dart
86%
HTML
7.1%
Kotlin
5.1%
JavaScript
1.6%
Swift
0.1%