gigafibre-fsm/apps/field-tech/BUILD-ANDROID.md
louispaulb aa108ab13f feat(field-tech): app Capacitor native (geofence Transistorsoft + scan MLKit) + CI
App technicien : appairage 1x (QR), géorepérage natif en arrière-plan (app fermée)
-> checkpoints au hub /field/ts, scan série/MAC on-device MLKit. UI réutilisée depuis
le hub (/field). APK Android buildé (debug, 19 Mo, arm64-v8a + armeabi-v7a).

- apps/field-tech : Capacitor 6 + Vite ; src/main.js (appairage @capacitor/preferences
  + BackgroundGeolocation.addGeofences + redirection /field) ; projet android/ avec les
  4 correctifs Gradle commités (force work-runtime 2.9.1, minSdk 24, repos maven xms.g
  + Huawei, googlePlayServicesLocationVersion 21.0.1) ; abiFilters arm (APK 32->19 Mo).
- README : recette de build complète (toolchain M4, les 4 fixes, install/appairage) ;
  BUILD-ANDROID.md (Docker + Android Studio + release signée) ; CI-SETUP.md (runner Gitea).
- CI Gitea Actions (.gitea/workflows) : android (runner Linux HORS prod, cache Gradle/npm
  -> artefact APK) + ios (runner macOS, workflow_dispatch, en attente compte Apple).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 19:47:27 -04:00

55 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Build Android — Targo Tech (app native)
Objectif : **app installée** (icône, pas de lien sur place) + **géorepérage natif en arrière-plan** (Transistorsoft) → arrivées/départs auto **app fermée** → checkpoints au hub. UI réutilisée depuis le hub. iOS = même base plus tard (compte Apple en attente).
> **Recette exacte + les 4 correctifs Gradle** (force work-runtime 2.9.1, minSdk 24, repos maven `xms.g`/Huawei, `googlePlayServicesLocationVersion 21.0.1`) : voir [`README.md` § Recette de build](README.md#recette-de-build-android). Ils sont **déjà appliqués et commités** dans `android/`. Ce document couvre le build Docker, Android Studio et la release signée.
## Architecture (ce qui est déjà fait)
- **Appairage 1×** : au bureau, Ops affiche le lien/QR du tech (bouton 📱 dans la liste des techs → `techFieldLink`). Le tech le scanne **une fois**`src/main.js` stocke le token (`@capacitor/preferences`). Plus jamais de lien sur place.
- **Géorepérage** : `src/main.js``BackgroundGeolocation.ready({ url:HUB+'/field/ts', autoSync:true, stopOnTerminate:false, startOnBoot:true, ... })` + `addGeofences(jobs)` (identifier = token signé du job). Transistorsoft POSTe enter/exit **nativement** → hub `/field/ts` (déjà déployé) mappe l'identifier → checkpoint (actual_start/end). Survit à l'app fermée + reboot.
- **UI** : après appairage, `location.replace(HUB+'/field?t=token)` → liste/détail/carte/Street View/photo/scan (hébergé, déjà en prod). MLKit injecté par Capacitor pour le scan on-device.
## Prérequis
- Node 18+, **Android Studio** + SDK, un appareil Android (ou émulateur) en mode développeur.
- **Licence Transistorsoft** (achat unique par app) : https://shop.transistorsoft.com → clé pour `com.transistorsoft` + l'appId `ca.targo.field`.
## Build via DOCKER (recommandé — sans Android Studio ni Mac)
Une « machine de compilation » conteneurisée (SDK + Gradle + Node) produit l'APK headless. Sur n'importe quel hôte Docker (serveur, laptop). **Android seulement** (iOS = macOS).
```bash
cd apps/field-tech
docker build -t targo-android-build . # ~1re fois : télécharge le SDK (qq min, ~2-3 Go d'image)
docker run --rm -v "$PWD":/app -v targo-gradle:/root/.gradle targo-android-build
# → APK : apps/field-tech/android/app/build/outputs/apk/debug/app-debug.apk
```
- 1re exécution = npm + Gradle téléchargent les deps (qq min) ; le volume `targo-gradle` les met en cache pour les builds suivants (rapides).
- **DEBUG sans licence** : Transistorsoft tourne en mode dev en debug → l'APK debug suffit pour tester (sideload). Pour **release** : `-e APP_BUILD=release` + clé licence (meta-data ci-dessous) + keystore.
- Distribuer l'APK : sideload direct, ou le copier sur le hub (`/opt/targo-hub/uploads`) pour un lien de téléchargement interne.
## Build local (Android Studio) — alternative
```bash
cd apps/field-tech
npm install
npm run build # Vite → www/
npx cap add android
npx cap sync android
```
1. **Licence Transistorsoft** — dans `android/app/src/main/AndroidManifest.xml`, sous `<application>` :
```xml
<meta-data android:name="com.transistorsoft.locationmanager.license" android:value="VOTRE_CLE" />
```
2. **Permissions** (le plugin les ajoute en grande partie ; vérifier `AndroidManifest.xml`) :
`ACCESS_FINE_LOCATION`, `ACCESS_COARSE_LOCATION`, **`ACCESS_BACKGROUND_LOCATION`**, `FOREGROUND_SERVICE`, `FOREGROUND_SERVICE_LOCATION`, `POST_NOTIFICATIONS`, `CAMERA` (MLKit), `INTERNET`.
3. **Build / installer** :
```bash
npx cap open android # Android Studio → Run sur l'appareil
# ou APK : cd android && ./gradlew assembleDebug → app/build/outputs/apk/debug/app-debug.apk (sideload)
```
4. **Appairage** : ouvrir l'app → « Scanner le QR » → scanner le QR du tech depuis Ops (bouton 📱). Le token est mémorisé.
5. **Tester** : se déplacer vers/depuis une adresse de job (rayon 200 m) → vérifier dans Ops que `actual_start/end` se posent (geofence natif). Avec l'app **fermée**, ça doit fonctionner (c'est tout l'intérêt de Transistorsoft).
## Notes
- **Distribution** : APK interne (sideload / MDM) — pas besoin du Play Store. Play « test interne » = compte 25 $ une fois si désiré.
- **iOS** (plus tard, compte Apple) : `npx cap add ios` + licence Transistorsoft iOS + `NSLocationAlwaysAndWhenInUseUsageDescription` + mode arrière-plan `location`. Même `src/main.js`.
- **Rafraîchir les geofences** : à l'ouverture, `main.js` recharge les jobs du jour. Pour une MAJ quotidienne app-fermée, ajouter `@transistorsoft/capacitor-background-fetch` (déjà en dépendance) → refetch + `addGeofences` périodique.
- **Scan IA** reste dispo en repli (texte) via `/field/vision` (Gemini) ; MLKit on-device est prioritaire.