Chapitre 9.5 — Panorama : fichiers, caméra, capteurs & co
Où on en est : Drill a tout ce qu’il lui faut côté natif. Ce chapitre est votre CARTE du reste du catalogue — pour vos apps de productivité (P19) et toutes les suivantes. Survol assumé : savoir que ça existe, ce que ça exige, où creuser.
⏱️ TL;DR — Le catalogue expo-* en familles : fichiers (expo-file-system — le disque de l’app), médias (expo-camera, expo-image-picker, expo-media-library), capteurs & position (expo-sensors, expo-location), système (expo-battery, expo-brightness, expo-keep-awake, expo-linking), identité (expo-local-authentication — biométrie). Pour chacun : le cas d’usage type, l’exigence (permission ? dev build ?), et le projet P19 qui s’en servira.
🎯 Objectifs
- Cartographier le catalogue par familles avec les exigences de chacune.
- Savoir instantanément « quel module pour quel besoin » dans vos futures apps.
- Repérer les 3 modules qui exigent plus que les autres (arrière-plan, dev build).
Fichiers : expo-file-system
Le disque privé de l’app, en lecture/écriture :
import * as FileSystem from 'expo-file-system'
const dir = FileSystem.documentDirectory // le « home » persistant de l'app
await FileSystem.writeAsStringAsync(dir + 'export.csv', csv)
await FileSystem.downloadAsync(url, dir + 'banque.json') // télécharger un fichier
const info = await FileSystem.getInfoAsync(dir + 'export.csv') // existe ? taille ?Cas d’usage : exports (le CSV des dépenses, P19-05), téléchargements volumineux, caches
maison. documentDirectory = persistant ; cacheDirectory = purgeable par le système. Pas de
permission (c’est VOTRE sandbox) ; pour écrire dans les dossiers PUBLICS (Téléchargements),
c’est le Storage Access Framework — plus lourd, la doc du module le couvre.
Médias : caméra, galerie
| Module | Cas d’usage | Exigences |
|---|---|---|
| expo-image-picker | « Choisir une photo » (galerie ou prise rapide) | Permission au vol, ✅ Expo Go — le choix à 90 % |
| expo-camera | Viewfinder DANS l’app : scan QR, photo intégrée | Permission caméra, préviews, ✅ Expo Go |
| expo-media-library | Lire/organiser TOUTE la galerie, albums | Permission large (justification store !) |
Le conseil d’architecture : commencez toujours par image-picker (l’UI système fait tout — zéro UI à coder, permission minimale) ; ne passez à expo-camera que pour une expérience caméra intégrée (le scanner de codes-barres de vos futures apps d’inventaire). media-library en dernier recours : sa permission « toutes les photos » fait tiquer les utilisateurs ET la review Play Store (P13).
Capteurs & position
// expo-sensors — accéléromètre, gyroscope, podomètre, baromètre…
import { Accelerometer } from 'expo-sensors'
const sub = Accelerometer.addListener(({ x, y, z }) => { /* secousse ? inclinaison ? */ })
Accelerometer.setUpdateInterval(100)Idées concrètes : secouer pour mélanger les questions (Drill v2 ?), niveau à bulle, compteur de pas (Pedometer). Pas de permission pour les capteurs de mouvement de base.
expo-location : la position GPS. Deux niveaux TRÈS différents — getCurrentPositionAsync
(ponctuel, permission « pendant l’utilisation », simple) vs le suivi en arrière-plan
(permission background redoutée, config plugin, justification store obligatoire, batterie).
Règle : ne JAMAIS demander le background sans nécessité absolue — c’est le sujet n°1 de rejets
et de méfiance.
Système : les petits qui rendent grand service
- expo-keep-awake :
useKeepAwake()— l’écran ne s’éteint pas. Une ligne, indispensable au Pomodoro (P19-01) et à toute app « posée sur la table ». - expo-brightness : luminosité de l’écran (app de lecture, mode nuit).
- expo-battery : niveau/état de charge (adapter les tâches lourdes).
- expo-linking : ouvrir d’AUTRES apps/URLs (
Linking.openURL('https://…'),openSettings()— déjà croisé ch. 9.1). - expo-localization : langue/région/fuseau de l’appareil (i18n).
Identité : expo-local-authentication
La biométrie (empreinte/visage) en trois lignes :
import * as LocalAuthentication from 'expo-local-authentication'
const ok = await LocalAuthentication.authenticateAsync({ promptMessage: 'Déverrouiller le journal' })
if (ok.success) { /* accès accordé */ }Le système gère TOUT (UI, capteurs, fallback code PIN). Cas d’usage P19 : verrouiller l’app Notes. Nuance de sécurité : c’est un verrou d’accès local (qui utilise le téléphone), pas une authentification serveur — pour Drill et vos apps locales, exactement le bon niveau.
La carte des exigences — le récapitulatif qui sert
| Famille | Permission runtime | Expo Go | Signal d’alarme |
|---|---|---|---|
| file-system (sandbox) | non | ✅ | dossiers publics = SAF |
| image-picker | au vol (gérée) | ✅ | — |
| camera | oui | ✅ | — |
| media-library | oui (large) | ✅ | review store tatillonne |
| sensors (mouvement) | non | ✅ | — |
| location (foreground) | oui | ✅ | — |
| location (background) | oui (spéciale) | ❌ dev build | rejets store, batterie |
| local-authentication | non (système) | ✅ | verrou local ≠ auth serveur |
| notifications push | oui | ❌ dev build | infra serveur requise |
Les trois lignes rouges du tableau (background location, push, et tout module hors SDK) ont un point commun : dev build requis — précisément le sujet de la Partie 11. La transition est toute trouvée.
💡 Pour un dev Next.js — Gardez ce chapitre en favori : c’est votre « MDN du natif ». Le réflexe de conception d’une app perso devient : (1) je liste les capacités téléphone dont j’ai besoin, (2) je vérifie dans cette carte permission/Expo Go, (3) le rituel du ch. 9.1 fait le reste. Vous ne serez plus jamais bloqué par « je ne savais pas que c’était possible ».
✏️ Exercices
1. Pour chacune des 5 apps de P19 (Pomodoro, Todo, Habitudes, Notes, Dépenses), listez les modules natifs nécessaires et leurs exigences. Lequel des cinq projets n’a besoin d’AUCUNE permission ?
✅ Solution
Pomodoro : notifications (permission), keep-awake, haptics. Todo : notifications (échéances). Habitudes : notifications. Notes : local-authentication (verrou — pas de permission), file-system (pas de permission), image-picker si photos (au vol). Dépenses : file-system (export CSV, sandbox), sharing. → Dépenses tourne sans aucune boîte de permission (et Notes aussi en version sans photos) : une app utile n’exige pas forcément de permissions — c’est même un argument produit.
2. Écrivez le POC « secouer pour lancer un quiz aléatoire » sur l’accueil de Drill (accéléromètre : magnitude > seuil → debounce → router.push).
✅ Solution
useEffect(() => {
let last = 0
Accelerometer.setUpdateInterval(120)
const sub = Accelerometer.addListener(({ x, y, z }) => {
const magnitude = Math.sqrt(x * x + y * y + z * z)
if (magnitude > 1.8 && Date.now() - last > 1500) { // seuil + debounce
last = Date.now()
feedback.tap()
router.push('/quiz?theme=melange&count=5')
}
})
return () => sub.remove()
}, [])Le debounce est la moitié du travail (une secousse = plusieurs pics). Fun à tester — et un vrai cas de « feature découvrable » à documenter dans l’app sinon personne ne la trouve.
3. Votre app Notes (P19-04) doit exporter une note en .txt vers une autre app. Trois modules candidats du chapitre — lesquels composez-vous et pourquoi pas les autres ?
✅ Solution
file-system (écrire le .txt dans cacheDirectory) + expo-sharing (shareAsync du fichier → l’utilisateur choisit la destination). PAS media-library (ce n’est pas un média de galerie) ni le SAF (pas besoin d’un emplacement public choisi — la share sheet est plus simple et plus idiomatique). Le combo « écrire dans MON sandbox puis partager » couvre 90 % des exports mobiles.
🧠 Quiz
1. documentDirectory vs cacheDirectory ?
Réponse
documentDirectory = persistant (données de l’app) ; cacheDirectory = purgeable par le système sous pression de stockage (fichiers reconstructibles, exports temporaires).
2. Pourquoi image-picker avant expo-camera ?
Réponse
L’UI système fait tout (choix galerie/photo), permission minimale gérée au vol, zéro interface à coder. expo-camera ne se justifie que pour une expérience caméra intégrée (viewfinder, scan).
3. Quel module garde l’écran allumé, et pour quel projet P19 ?
Réponse
expo-keep-awake (useKeepAwake()) — le Pomodoro (P19-01), et toute app « posée sur la
table ».
4. La biométrie locale authentifie-t-elle auprès d’un serveur ?
Réponse
Non — expo-local-authentication est un verrou d’accès local (qui tient le téléphone). Une auth serveur exige des credentials/tokens ; pour des apps locales, le verrou est le bon niveau.
5. Citez les trois cas du chapitre qui exigent un development build.
Réponse
La géolocalisation en arrière-plan, les notifications push, et tout module hors SDK Expo Go — le pont exact vers la Partie 11.
👉 Partie suivante : Partie 10 — Animations & gestes — Reanimated : le timer circulaire, les micro-interactions, et pourquoi les animations RN tournent à 120 fps.