Card2vcf
Application Android hors-ligne : scan d’une carte de visite → OCR local (Tesseract) → brouillon éditable → carnet local (SQLite), contact Android et export .vcf.
Aucune dépendance Google Play Services / ML Kit, aucun LLM. OCR et carnet restent 100 % hors-ligne ; la permission Internet sert uniquement à la sync optionnelle avec un serveur Projectiaon (voir ci-dessous).
Mini-CRM (carnet local)
L’écran d’accueil est un carnet offline stocké en SQLite (Room) sur l’appareil :
- Recherche FTS sur nom, entreprise, téléphones, e-mails et notes
- Tri (nom, prénom, entreprise, date) + abcédaire
- Fiche contact (swipe), notes, édition, photo de profil, rescan de la carte (les notes sont conservées)
- Import VCF : lecture vCard 3.0 et 4.0, anti-doublons (skip si déjà présent)
- Export VCF : écriture vCard 3.0 uniquement
- Gestion des doublons : badge, revue, fusion ou marquage « contacts différents »
- Création : scan, saisie manuelle ou import
Sans configuration sync : aucun compte, aucune donnée CRM envoyée hors appareil (export VCF manuel possible).
Sync Projectiaon (optionnelle)
Sync offline-first avec un serveur Projectiaon (ailiance-brain) : carnet, projets, tâches kanban et comptes-rendus. L’OCR et le scan ne nécessitent pas Internet.
Prérequis serveur : variable AILIANCE_API_CLES (clés API par utilisateur), endpoints /api/auth/cle, /api/sync/status, /api/sync/pull — voir le plan serveur.
Configuration dans l’app : Paramètres (engrenage) → URL HTTPS du serveur → identifiant + mot de passe → « Obtenir la clé » → retaper le mot de passe pour déchiffrer la clé API (stockée chiffrée sur l’appareil ; le mot de passe n’est jamais conservé).
Pour le développement, un réseau interne ou une démo sans TLS : cocher « Autoriser HTTP (clair) » avant de saisir une URL http://…. Sans cette case, l’app refuse le HTTP (HTTPS obligatoire). Ne pas activer cette option en production sur Internet.
Utilisation : à l’ouverture, un bandeau signale les changements distants sans pull automatique. Le bouton Sync pousse les modifications locales (contacts créés/édités dans le carnet y compris l’image de carte scannée et la photo de profil si présentes, tâches, CR…) puis tire le delta serveur. Sans sync configurée, le carnet reste local uniquement.
Plan d’implémentation client : docs/plans/sync_card2vcf_projectiaon_v1.md.
Sync images carte/photo : docs/plans/sync_cartes_visite_v1.md.
Upgrade schéma v2 : la migration Room peut réinitialiser les données locales (documenté dans le plan sync).
Agenda / calendriers (optionnel, dépend de la sync)
Card2vcf ne contient aucun écran agenda : les rendez-vous et réservations de ressources se consultent et se modifient dans l’app Agenda système (calendriers locaux, hors-GMS — aucun compte Google requis), via des calendriers dédiés que l’app crée et synchronise avec Projectiaon.
Permissions : READ_CALENDAR / WRITE_CALENDAR, demandées à l’exécution depuis Paramètres. Sans autorisation, le pont Agenda reste désactivé ; le carnet et la sync CRM (contacts/projets/tâches) continuent de fonctionner normalement.
Configuration dans l’app : Paramètres → section Calendriers (visible une fois connecté) :
- Toggle « Mes RDV » → crée/lie le calendrier local
Card2vcf — Mes RDV; les événements qui y sont créés/modifiés deviennent des RDV Projectiaon à la sync. - Si des identifiants sont configurés, la liste des ressources (salles, matériel, véhicules) du serveur s’affiche avec un toggle par ressource active ; les ressources inactives sont grisées (non sélectionnables). Activer une ressource crée le calendrier
Card2vcf — {Salle|Matériel|Véhicule} {nom}; un événement qui y est créé devient une réservation Active poussée au serveur. - Désactiver un toggle demande confirmation avant de retirer la liaison. Le retrait supprime uniquement la liaison locale (sync arrêtée pour ce calendrier) — l’API
CalendarBridgen’expose pas de suppression de calendrier Android, le calendrier créé reste donc visible (vide, non synchronisé) dans l’app Agenda système.
Sync et conflits : le bouton Sync pousse aussi les événements Agenda liés (RDV + réservations) puis tire le delta serveur (RDV, réservations actives, indisponibilités en lecture). Un bandeau signale un calendrier local en avance (événements pas encore poussés). Si une réservation entre en conflit avec le serveur (HTTP 409, chevauchement), Card2vcf conserve l’événement local, retire le blocage serveur pour affichage, puis propose un dialog « Annuler ma réservation ? » :
- Oui → la réservation locale et son événement Agenda sont supprimés.
- Non → rien n’est modifié ; l’arbitrage se fait sur le serveur web (demandes / réclamations restent hors périmètre mobile).
Spec détaillée : docs/superpowers/specs/2026-07-22-sync-agenda-rdv-ressources-v2-design.md. Plan d’implémentation : docs/plans/sync_agenda_rdv_ressources_v2.md.
Room v3 (agenda) : l’ajout des tables RDV/réservations/indisponibilités passe la base Room en version 3 avec
fallbackToDestructiveMigration— comme pour l’upgrade v2 ci-dessus, la mise à jour réinitialise les données locales (carnet inclus) ; ré-exportez en VCF ou synchronisez avant de mettre à jour l’app si nécessaire.
Fonctionnement (scan / OCR)
- Cadrez la carte et capturez (CameraX).
- Correction géométrique (OpenCV) + orientation EXIF.
- OCR Tesseract (7 langues) + post-traitement.
- Structuration heuristique (pas de modèle de langage).
- Vérifiez le brouillon, puis :
- Enregistrer → carnet local (SQLite)
- Créer le contact →
ACTION_INSERTContacts - Exporter VCF → partage d’un fichier
.vcf(vCard 3.0)
Langues OCR
| Code | Langue |
|---|---|
fra | Français |
deu | Allemand |
eng | Anglais |
spa | Espagnol |
por | Portugais |
ita | Italien |
pol | Polonais |
Choix fast / full à la compilation
| Variante | Propriété Gradle | Source | Taille approx. |
|---|---|---|---|
| fast (défaut) | -Ptessdata=fast | tessdata_fast | ~18 Mo |
| full | -Ptessdata=full | tessdata | ~80 Mo+ |
cd android ./gradlew :app:assembleDebug # fast ./gradlew :app:assembleDebug -Ptessdata=full # full
Premier build d’une variante : téléchargement dans android/tessdata-cache/{fast,full}/ (gitignored), puis injection dans les assets générés. Réseau requis uniquement si le cache est vide.
Chargement ultérieur (sans rebuild / sans Internet dans l’APK)
Oui. Au runtime, Tesseract lit filesDir/tesseract/tessdata/ :
- Première exécution (ou changement fast↔full du APK) → copie depuis les assets embarqués.
- Ensuite → réutilisation des fichiers locaux.
- Sideload : déposer/remplacer les
*.traineddatadans ce dossier (ex.adb push), puis éventuellement écrire le stampexternalpour empêcher l’écrasement au prochain changement de variante APK :
/data/data/fr.ebii.card2vcf/files/tesseract/tessdata/ fra.traineddata … .card2vcf-tessdata-variant # "fast" | "full" | "external"
Pas de téléchargement réseau dans l’app pour les modèles OCR (hors sync optionnelle Projectiaon).
APK debug filtré arm64-v8a. Pour émulateur x86, retirez temporairement ndk.abiFilters dans app/build.gradle.kts.
Build
cd android ./gradlew :app:assembleDebug ./gradlew :app:testDebugUnitTest
APK debug : android/app/build/outputs/apk/debug/app-debug.apk
Prérequis : JDK 21, Android SDK (API 35).
Limites (assumées)
- Pas de LLM : la qualité du brouillon dépend des heuristiques + du texte OCR. Cartes très décoratives ou manuscrites peuvent échouer.
- Caméra obligatoire (
android.hardware.camerarequired) pour le scan ; le carnet et l’import VCF restent utilisables sans. - Pas de sync obligatoire : sans configuration Projectiaon, le carnet est local uniquement ; perte/désinstallation = perte des données sauf export VCF ou sync préalable.
- Structuration sémantique avancée (homonymes, mises en page atypiques) hors périmètre.
Design
UI N&B éditoriale (design.md) : coins carrés, hairlines, polices TTF embarquées (Playfair Display, Lora, Manrope — OFL, voir docs/licenses/OFL-fonts.txt). Icône : icon.png.
Origine du code
Pipeline scan/OCR/contact adapté depuis le projet open source luciole-mobile (AGPL), sans le module LLM (cerveau).
GitRust