Intermédiaire60 min45 XP
Objectifs de cette leçon
- Accéder à la caméra, géolocalisation et capteurs
- Utiliser les modules natifs via Expo
- Comprendre les bridge natif
Fonctionnalités natives 📷
Le vrai pouvoir du mobile, c'est d'accéder au matériel du téléphone : caméra, GPS, notifications, empreinte digitale...
1. Permissions — la porte d'entrée 🚪
' Avant d'accéder à une fonctionnalité native, ' il faut DEMANDER LA PERMISSION à l'utilisateur ! ' iOS : demande automatique + explication dans Info.plist ' Android : déclaration dans AndroidManifest.xml ``' ```text ' Cycle de vie d'une permission : ' 1. Vérifier si la permission est déjà accordée ' 2. Si non, demander avec une explication ' 3. L'utilisateur accepte ou refuse ' 4. Réagir en conséquence ' Conseils : ' • Expliquer POURQUOI tu as besoin de la permission ' • Gérer le cas où l'utilisateur refuse ' • Ne pas demander au lancement, mais au moment utile ``' ```tsx import * as Location from "expo-location"; import { Alert, Linking } from "react-native"; async function demanderPermissionLocalisation() { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== "granted") { Alert.alert( "Permission refusée", "Nous avons besoin de votre localisation pour fonctionner. Activez-la dans les paramètres.", [ { text: "Annuler", style: "cancel" }, { text: "Paramètres", onPress: () => Linking.openSettings() }, ], ); return false; } return true; } ``' --- ## 2. Caméra — prendre des photos 📸 tsx import { CameraView, useCameraPermissions } from "expo-camera"; import { useState, useRef } from "react"; import { View, Text, TouchableOpacity, Image, StyleSheet } from "react-native"; function AppareilPhoto() { const [permission, requestPermission] = useCameraPermissions(); const cameraRef = useRef<CameraView>(null); const [photo, setPhoto] = useState<string | null>(null); if (!permission) return <Text>Chargement...</Text>; if (!permission.granted) { return ( <View> <Text>Permission caméra requise</Text> <TouchableOpacity onPress={requestPermission}> <Text>Autoriser</Text> </TouchableOpacity> </View> ); } const prendrePhoto = async () => { if (cameraRef.current) { const resultat = await cameraRef.current.takePictureAsync(); setPhoto(resultat.uri); } }; return ( <View style={styles.container}> <CameraView ref={cameraRef} style={styles.camera} facing="back"> <TouchableOpacity style={styles.bouton} onPress={prendrePhoto}> <Text style={styles.texte}>📸</Text> </TouchableOpacity> </CameraView> {photo && <Image source={{ uri: photo }} style={styles.apercu} />} </View> ); } ``' --- ## 3. Géolocalisation — où suis-je ? 📍 ```tsx import * as Location from "expo-location"; import { View, Text, TouchableOpacity, StyleSheet } from "react-native"; import MapView, { Marker } from "react-native-maps"; function CartePosition() { const [position, setPosition] = useState<Location.LocationObject | null>(null); const obtenirPosition = async () => { const aPermission = await demanderPermissionLocalisation(); if (!aPermission) return; const loc = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High, // Haute précision (GPS) }); setPosition(loc); }; return ( <View style={styles.container}> <TouchableOpacity onPress={obtenirPosition}> <Text>📍 Ma position</Text> </TouchableOpacity> {position && ( <MapView style={styles.carte} initialRegion={{ latitude: position.coords.latitude, longitude: position.coords.longitude, latitudeDelta: 0.01, longitudeDelta: 0.01, }} > <Marker coordinate={{ latitude: position.coords.latitude, longitude: position.coords.longitude, }} title="Je suis ici !" /> </MapView> )} </View> ); } ``' --- ## 4. Notifications push 🔔 ```text ' Notifications push = messages qui arrivent ' même quand l'app est fermée ! ' Types : ' • Locales : programmées par l'app (rappel) ' • Distantes : envoyées par un serveur (FCM/APNs) ' • Avec ou sans intervention utilisateur ``' ```tsx import * as Notifications from "expo-notifications"; import { useEffect } from "react"; import { Platform } from "react-native"; // Configuration des notifications Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: true, }), }); async function configurerNotifications() { // Demander la permission const { status } = await Notifications.requestPermissionsAsync(); if (status !== "granted") return; // Obtenir le token (à envoyer au serveur) const token = await Notifications.getExpoPushTokenAsync(); console.log("Token de notification :", token.data); // Envoyer ce token à votre API : await fetch("https://api.exemple.com/notifications/token", { method: "POST", body: JSON.stringify({ token: token.data }), }); } // Envoyer une notification locale async function notificationLocale() { await Notifications.scheduleNotificationAsync({ content: { title: "Rappel 📅", body: "N'oublie pas de réviser React Native !", data: { screen: "Profil", userId: 42 }, }, trigger: { seconds: 60 }, // Dans 1 minute }); } ``' --- ## 5. Biométrie : Face ID / Touch ID 👆 ```tsx import * as LocalAuthentication from "expo-local-authentication"; async function authentifier() { // Vérifier si la biométrie est disponible const compatible = await LocalAuthentication.hasHardwareAsync(); if (!compatible) { Alert.alert("Non compatible", "Votre appareil ne supporte pas la biométrie"); return false; } // Vérifier si des empreintes/visages sont enregistrés const enregistres = await LocalAuthentication.isEnrolledAsync(); if (!enregistres) { Alert.alert("Aucune donnée", "Aucune empreinte ou visage enregistré"); return false; } // Authentifier const resultat = await LocalAuthentication.authenticateAsync({ promptMessage: "Authentifiez-vous pour accéder à l'app", fallbackLabel: "Utiliser le code", }); return resultat.success; } // Utilisation function EcranSecurise() { const [acces, setAcces] = useState(false); useEffect(() => { authentifier().then(setAcces); }, []); if (!acces) return <Text>🔒 Authentification requise</Text>; return <Text>🔓 Contenu secret déverrouillé !</Text>; } ``' --- ## Exercices pour toi 🎯 1. **Caméra** : crée une app qui prend une photo, l'affiche en aperçu et permet de la sauvegarder 2. **Carte** : affiche une carte avec la position actuelle et un marqueur "Je suis ici" 3. **Notifications + Biométrie** : crée un écran "secret" qui demande Face ID avant de s'afficher, puis envoie une notification locale de bienvenue
Création des variables pas à pas
Prêt à explorer la mémoire
Appuie sur Play pour voir les variables se créer une par une
0/5
Visualisation d'exécution
ligne 8code
1import { CameraView, useCameraPermissions } from 'expo-camera';
2import * as Location from 'expo-location';
3import * as LocalAuthentication from 'expo-local-authentication';
4
5export default function App() {
6 const [permission, requestPermission] = useCameraPermissions();
7
8 if (!permission?.granted) {
9 return <Text onPress={requestPermission}>🔐 Activer la caméra</Text>;
10 }
11
12 return (
13 <CameraView style={{ flex: 1 }}>
14 <Text>📸 Caméra prête !</Text>
15 </CameraView>
16 );
17}
Variables
permission.granted=true/false
requestPermission=ouvre la popup système
🔐 Permissions
📸
Caméra
en attente...
🗺️
GPS
en attente...
🔔
Notifications
en attente...