Files
GameTime/.ideai/memory/gametime-android-release-networking-and-apk-build.md
Blomios 917777e18b chore(wip): consolidation intermédiaire multi-tickets (sprints Statistiques, UI, Bug resolution, Serveur-client)
Regroupe l'état de travail en cours réalisé dans un même worktree sur
plusieurs tickets/sprints (#85, #136, #145, #155-160, #162-164),
mélangeant des tickets QA et inProgress. Ne constitue pas une feature
terminée : commit de sauvegarde avant triage/split par ticket en
branches feature/* dédiées. Exclut les dossiers d'environnement de
build locaux et le heap dump parasite (.gitignore mis à jour).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 16:48:54 +02:00

4.0 KiB

name, description, metadata
name description metadata
gametime-android-release-networking-and-apk-build memory note gametime-android-release-networking-and-apk-build
type
project

GameTime — Réseau Android release, cleartext et build APK

Capitalise le bug de création de compte sur APK release (« Création impossible pour le moment. Réessaie plus tard ») et la procédure de build/distribution APK.

Causes du bug (toutes nécessaires, stacking)

L'erreur UI générique Création impossible pour le moment (lib/presentation/profile_screen.dart, _registerErrorMessage) est retournée pour RemoteAuthFailure.network ou tout échec non emailAlreadyUsed. Trois causes indépendantes cumulées sur le release :

  1. Permission INTERNET absente du manifest release. Elle n'était déclarée que dans android/app/src/debug/AndroidManifest.xml et .../profile/.... Le release (merge main+release, sans manifest release dédié) n'en héritait pas → aucun socket réseau possible → http.ClientExceptionRemoteAuthFailure.network.

    • Fix définitif : INTERNET déclaré dans android/app/src/main/AndroidManifest.xml (racine <manifest>), hérité par tous les build types.
  2. Trafic cleartext bloqué. Serveur de dev/LAN en http:// (pas de TLS ; reverse proxy HTTPS externe). Sur Android 9+ (API 28+) le cleartext est bloqué par défaut.

    • Fix : android:usesCleartextTraffic="true" sur <application> dans src/main/AndroidManifest.xml. Acceptable tant qu'il n'y a pas de TLS bout-en-bout ; à remplacer par une network_security_config ciblée quand la prod passe en HTTPS.
  3. Port serveur. Le conteneur API publie le port interne 8080 sur le port hôte 8090 (server/.env : API_BIND_ADDRESS=192.168.1.75, API_PORT=8090 ; server/docker-compose.yaml ${API_BIND_ADDRESS}:${API_PORT}:8080). Donc l'URL joignable est http://192.168.1.75:8090, pas 8080.

Contrat d'injection d'URL (ne pas coder en dur)

HttpApiClient.defaultBaseUrl (lib/infrastructure/remote/http_api_client.dart) reste http://localhost:8080 par défaut (fallback de dev local). L'URL réelle est injectée au build via --dart-define=GAMETIME_API_BASE_URL=.... Ne pas hardcoder d'IP/port serveur dans le code (validé par Architect). Le défaut localhost:8080 est volontairement non fonctionnel sur device physique distant.

Build APK release (env Main)

Pré-requis machine projet : Flutter 3.44.6 (/usr/bin/flutter), Android SDK /opt/android-sdk, JDK 21 obligatoire (/usr/lib/jvm/java-21-openjdk) — le JDK système par défaut (java-26) casse Gradle.

export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export ANDROID_HOME=/opt/android-sdk
export PATH="$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH"
cd /home/anthony/Documents/Projects/GameTime
flutter build apk --release --dart-define=GAMETIME_API_BASE_URL=http://192.168.1.75:8090

Sortie : build/app/outputs/flutter-apk/app-release.apk (+ .sha1). Signé avec les clés debug (android/app/build.gradle.kts : signingConfig = debug) → installable sans keystore prod.

Note : les sandboxes agents (QA, codex runner) échouent à lancer Gradle (« Could not determine a usable wildcard IP for this machine ») ; le build release se fait depuis l'environnement Main uniquement.

Vérification du manifest mergé d'un APK

AAPT=/opt/android-sdk/build-tools/34.0.0/aapt2
$AAPT dump permissions <apk>                        # doit lister android.permission.INTERNET
$AAPT dump xmltree <apk> --file AndroidManifest.xml | grep -iE 'INTERNET|usesCleartextTraffic'

Pour un release GameTime sain : INTERNET présent ET usesCleartextTraffic=true.

Santé serveur (pre-flight)

curl http://192.168.1.75:8090/health        # attendu {"status":"ok"}
curl -X POST http://192.168.1.75:8090/auth/register \
  -H 'content-type: application/json' \
  -d '{"email":"probe@example.com","password":"probe12345"}'   # attendu HTTP 201

docker ps : server-api-1 expose 192.168.1.75:8090->8080/tcp, server-postgres-1 healthy.