---
name: gametime-android-release-networking-and-apk-build
description: memory note gametime-android-release-networking-and-apk-build
metadata:
  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.ClientException` → `RemoteAuthFailure.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.

```bash
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

```bash
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)

```bash
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.