Files
pluriwave/android/app/src/main/AndroidManifest.xml
ShanaiaBot 44849986d2
Some checks failed
Flutter CI/CD — PluriWave / Test + Build (pull_request) Has been cancelled
fix(reproduccion): robustez HTTP cleartext, errores ExoPlayer y certificados SSL
**Fix 1 — HTTP cleartext (streams sin HTTPS):**
- Añadir android/app/src/main/res/xml/network_security_config.xml con
  cleartextTrafficPermitted=true para permitir streams de radio HTTP
- Referenciar en AndroidManifest.xml con android:networkSecurityConfig
- Resuelve: 'Cleartext HTTP traffic to [host] not permitted' en ExoPlayer
- Radio Paradise (Dance Wave, HTTP) y otras radios HTTP funcionan ahora

**Fix 2 — Gestión de error TYPE_SOURCE y todos los PlaybackException:**
- Añadir listener en playbackEventStream.onError en PluriWaveAudioHandler
- _gestionarErrorReproduccion() emite AudioProcessingState.error al UI,
  loggea el error y resetea el player a estado idle limpio
- _mensajeAmigable() traduce códigos ERROR_CODE_IO_*, ERROR_CODE_PARSING_*,
  ERROR_CODE_DECODING_* y mensajes de Cleartext/HandshakeException a texto legible
- EstadoRadio.reproducir() captura la excepción y cancela el timer si estaba activo
- EstadoRadio escucha el estadoStream y cancela timer ante cualquier error

**Fix 3 — Artwork con certificado autofirmado:**
- errorWidget en CachedNetworkImage captura HandshakeException silenciosamente
- Muestra _iconoFallback (icono de radio) en lugar de imagen rota
- El error de artwork no se propaga ni interrumpe la reproducción

**Fix 4 — UI consistente en estado de error:**
- PantallaReproductor._Controles muestra mensaje + botón Reintentar en error
- PantallaReproductor._Artwork muestra overlay wifi_off en estado de error
- MiniReproductor muestra botón refresh (reintentar) en estado de error
- EstadoReproduccion.error ya estaba definido; ahora el estadoStream lo emite
- Timer cancelado automáticamente cuando la reproducción falla
- Test de smoke corregido (boilerplate MyApp → placeholder válido)

Fixes: cleartext HTTP, cert autofirmado, ExoPlayer TYPE_SOURCE, UI inconsistente
2026-04-04 20:43:56 +02:00

63 lines
2.6 KiB
XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Permisos requeridos para streaming de audio -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:label="PluriWave"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Servicio de audio en background (audio_service) -->
<service
android:name="com.ryanheise.audioservice.AudioService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<!-- Receptor de controles de media (auriculares, notificación) -->
<receiver
android:name="com.ryanheise.audioservice.MediaButtonReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
</receiver>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>