V0.4.2

EBO <eric.bouhana@softalys.com> committé le 2026-09-12 19:08

9264de0d59b5eec2827a3ab1102f08867119bb97

1 parent(s)

3 fichiers modifiés +72 -0
M .gitignore
+3 -0
@@ -37,6 +37,9 @@ android/.kotlin/
37 37 android/build/
38 38 android/app/build/
39 39 android/tessdata-cache/
40 +# Signature release (à sauvegarder hors git : la même clé est requise pour toute mise à jour)
41 +android/keystore/
42 +android/keystore.properties
40 43 android/app/src/main/assets/tesseract/tessdata/*.traineddata
41 44 android/local.properties
42 45 android/.idea/
M README.md
+37 -0
@@ -119,6 +119,43 @@ Pas de téléchargement réseau dans l’app pour les modèles OCR (hors sync op
119 119
120 120 APK debug filtré `arm64-v8a`. Pour émulateur x86, retirez temporairement `ndk.abiFilters` dans `app/build.gradle.kts`.
121 121
122 +## Release signée (bêta-testeurs)
123 +
124 +La signature release est lue depuis `android/keystore.properties` (gitignoré), qui pointe vers le keystore `android/keystore/piclead-release.jks` (gitignoré aussi). Sans ce fichier, `assembleRelease` produit un APK **non signé**, ininstallable par les testeurs.
125 +
126 +> ⚠️ **Sauvegardez `keystore/piclead-release.jks` + `keystore.properties` hors git** (coffre, sauvegarde chiffrée). Toute mise à jour doit être signée avec la **même clé** : une clé perdue ou changée force les testeurs à désinstaller/réinstaller (perte des données locales).
127 +
128 +**Mise en place sur une nouvelle machine** (à partir du keystore sauvegardé) — format de `android/keystore.properties` :
129 +
130 +```properties
131 +storeFile=keystore/piclead-release.jks
132 +storePassword=…
133 +keyAlias=piclead
134 +keyPassword=…
135 +```
136 +
137 +**À chaque bêta :**
138 +
139 +```bash
140 +cd android
141 +# 1. Incrémenter versionCode (obligatoire pour qu'Android accepte la mise à jour)
142 +# et versionName dans app/build.gradle.kts
143 +# 2. Builder (mêmes variantes tessdata que le debug)
144 +./gradlew :app:assembleRelease # fast (défaut)
145 +./gradlew :app:assembleRelease -Ptessdata=full # full
146 +# 3. Récupérer l'APK nommé d'après l'application
147 +ls app/build/outputs/apk/release/PicLead-*-release.apk
148 +```
149 +
150 +Vérification optionnelle de la signature avant envoi :
151 +
152 +```bash
153 +"$HOME"/Android/Sdk/build-tools/*/apksigner verify --print-certs \
154 + app/build/outputs/apk/release/PicLead-*-release.apk
155 +```
156 +
157 +Distribution : envoyez le fichier `PicLead-<version>-release.apk` tel quel (mail, lien) ; à l'installation, Android demandera d'autoriser l'installation depuis une source inconnue.
158 +
122 159 ## Build
123 160
124 161 ```bash
M android/app/build.gradle.kts
+32 -0
@@ -1,4 +1,5 @@
1 1 import java.net.URI
2 +import java.util.Properties
2 3
3 4 plugins {
4 5 id("com.android.application")
@@ -19,6 +20,13 @@ val tessdataLanguages = listOf("fra", "deu", "eng", "spa", "por", "ita", "pol")
19 20 val tessdataCacheDir = rootProject.layout.projectDirectory.dir("tessdata-cache/$tessdataVariant")
20 21 val tessdataGeneratedAssets = layout.buildDirectory.dir("generated/tessdataAssets")
21 22
23 +/** Signature release : lue depuis android/keystore.properties (hors git).
24 + * Absente → assembleRelease produit un APK non signé, comme avant. */
25 +val keystoreProperties = Properties().apply {
26 + val fichier = rootProject.file("keystore.properties")
27 + if (fichier.isFile) fichier.inputStream().use { load(it) }
28 +}
29 +
22 30 android {
23 31 namespace = "fr.ebii.card2vcf"
24 32 compileSdk = 35
@@ -46,6 +54,30 @@ android {
46 54 unitTests.isIncludeAndroidResources = true
47 55 }
48 56 sourceSets.getByName("main").assets.srcDir(tessdataGeneratedAssets)
57 + signingConfigs {
58 + if (keystoreProperties.getProperty("storeFile") != null) {
59 + create("release") {
60 + storeFile = rootProject.file(keystoreProperties.getProperty("storeFile"))
61 + storePassword = keystoreProperties.getProperty("storePassword")
62 + keyAlias = keystoreProperties.getProperty("keyAlias")
63 + keyPassword = keystoreProperties.getProperty("keyPassword")
64 + }
65 + }
66 + }
67 + buildTypes {
68 + release {
69 + isMinifyEnabled = false
70 + signingConfig = signingConfigs.findByName("release")
71 + }
72 + }
73 + // Sorties nommées d'après l'application : PicLead-<version>-<type>.apk
74 + applicationVariants.all {
75 + val variant = this
76 + outputs.all {
77 + (this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName =
78 + "PicLead-${variant.versionName}-${variant.buildType.name}.apk"
79 + }
80 + }
49 81 }
50 82
51 83 val prepareTessdata by tasks.registering {