Les capteurs de périphérique Capacitor sont disponibles via de petits plugins ciblés : @capgo/capacitor-accelerometer pour le mouvement, @capgo/capacitor-barometer pour la pression atmosphérique, @capgo/capacitor-compass pour l’orientation, @capgo/capacitor-pedometer pour les pas, ainsi que des plugins de luminosité, de proximité et de secousse. Chacun suit le même schéma : vérifier la disponibilité, demander l’autorisation si nécessaire, démarrer les mises à jour, écouter, puis arrêter une fois terminé. Ce guide couvre chaque capteur avec Capacitor 8 code, les différences de plateforme qui comptent, et les règles de batterie qui évitent les problèmes aux applications.
Aperçu des capteurs
| Capteur | Plugin | iOS | Android | Autorisation |
|---|---|---|---|---|
| Accéléromètre | @capgo/capacitor-accelerometer |
Oui | Oui | iOS NSMotionUsageDescription |
| Baromètre | @capgo/capacitor-barometer |
Oui, avec l'altitude relative | Oui, pression uniquement, sur les appareils équipés d'un capteur | Description d'utilisation du mouvement iOS |
| Boussole | @capgo/capacitor-compass |
Oui | Oui, avec des événements de précision | Localisation iOS lors de l'utilisation |
| Podomètre | @capgo/capacitor-pedometer |
Pas, distance, étages, allure, cadence | Étapes | Mouvement iOS, Android ACTIVITY_RECOGNITION |
| Lumière ambiante | @capgo/capacitor-light-sensor |
Pas de API public | Oui | Aucun |
| Proximité | @capgo/capacitor-proximity |
Oui | Oui | Aucun |
| Geste de secousse | @capgo/capacitor-shake |
Oui | Oui | Aucun |
| Gyroscope / orientation | Le Web DeviceMotionEvent / DeviceOrientationEvent |
Oui | Oui | iOS requestPermission() dans la WebView |
N'installez que ce que vous utilisez. Chaque plugin est léger, et moins de permissions signifie moins de questions lors de l'App Review.
bun add @capgo/capacitor-accelerometer @capgo/capacitor-compass @capgo/capacitor-pedometer
bunx cap sync
Configuration iOS
Ajoutez les chaînes d'utilisation requises par vos capteurs à ios/App/App/Info.plist:
<!-- Accelerometer, pedometer, barometer altitude -->
<key>NSMotionUsageDescription</key>
<string>Counts your steps and detects movement during workouts.</string>
<!-- Compass heading -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>Shows which direction you are facing on the map.</string>
Expliquez le bénéfice pour l'utilisateur en termes simples. Un texte générique comme « Cette app a besoin d'accéder aux mouvements » est une cause fréquente de rejet à l'App Review.
Configuration Android
La plupart des capteurs ne nécessitent aucune permission. Le plugin pedometer ajoute ACTIVITY_RECOGNITION au manifeste fusionné, et vous la demandez au runtime sur Android 10+.
Si un capteur est essentiel, déclarez la fonctionnalité matérielle pour que Google Play masque votre application sur les appareils qui ne l'ont pas. S'il est facultatif, déclarez-l’avec required="false" et vérifiez la disponibilité au runtime :
<uses-feature android:name="android.hardware.sensor.barometer" android:required="false" />
<uses-feature android:name="android.hardware.sensor.stepcounter" android:required="false" />
<uses-feature android:name="android.hardware.sensor.compass" android:required="false" />
Accéléromètre : mouvement et inclinaison
L'accéléromètre renvoie l'accélération sur les axes x, y et z en G. Un téléphone posé à plat mesure environ z = -1 ou 1 selon la convention de la plateforme, car la gravité est incluse.
import { CapacitorAccelerometer } from '@capgo/capacitor-accelerometer';
const { isAvailable } = await CapacitorAccelerometer.isAvailable();
if (isAvailable) {
await CapacitorAccelerometer.requestPermissions();
const listener = await CapacitorAccelerometer.addListener('measurement', ({ x, y, z }) => {
const tiltX = Math.atan2(x, Math.sqrt(y * y + z * z)) * (180 / Math.PI);
ball.style.transform = `translateX(${tiltX * 3}px)`;
});
await CapacitorAccelerometer.startMeasurementUpdates();
// later
await CapacitorAccelerometer.stopMeasurementUpdates();
await listener.remove();
}
Cas d'usage : contrôles d'inclinaison dans les jeux, interface « lever pour réveiller », détection de chute ou d'impact, intensité de l'activité. Les données brutes sont bruitées, lissez-les donc avec un filtre passe-bas avant de les utiliser :
const alpha = 0.2;
let smoothed = { x: 0, y: 0, z: 0 };
function lowPass(m: { x: number; y: number; z: number }) {
smoothed = {
x: smoothed.x + alpha * (m.x - smoothed.x),
y: smoothed.y + alpha * (m.y - smoothed.y),
z: smoothed.z + alpha * (m.z - smoothed.z),
};
return smoothed;
}
Ne mettez pas à jour le DOM à chaque échantillon. Stockez la dernière valeur et affichez-la dans une requestAnimationFrame boucle.
Gestes de secousse
Pour « secouer pour signaler un bug » ou « secouer pour annuler », vous n’avez pas besoin de régler les seuils vous-même :
import { CapacitorShake } from '@capgo/capacitor-shake';
const handle = await CapacitorShake.addListener('shake', () => openFeedbackForm());
Gyroscope et orientation de l'appareil
Aucun plugin séparé n’est nécessaire pour la rotation. La WebView l’expose déjà :
async function enableMotion() {
// iOS 13+ requires a user gesture and explicit permission
const DME = DeviceMotionEvent as unknown as { requestPermission?: () => Promise<'granted' | 'denied'> };
if (typeof DME.requestPermission === 'function') {
const result = await DME.requestPermission();
if (result !== 'granted') return;
}
window.addEventListener('devicemotion', (e) => {
const r = e.rotationRate; // alpha, beta, gamma in degrees per second
if (r) updateRotation(r.alpha ?? 0, r.beta ?? 0, r.gamma ?? 0);
});
window.addEventListener('deviceorientation', (e) => {
// alpha: 0-360 around z, beta: -180..180 front/back, gamma: -90..90 left/right
updateOrientation(e.alpha, e.beta, e.gamma);
});
}
document.querySelector('#enable-motion')!.addEventListener('click', enableMotion);
Appelez requestPermission à partir d’un appui sur un bouton, jamais au chargement de la page, sinon iOS refuse la requête.
Boussole : cap
import { CapgoCompass, CompassAccuracy } from '@capgo/capacitor-compass';
const status = await CapgoCompass.requestPermissions(); // iOS: location permission
if (status.compass === 'granted') {
await CapgoCompass.addListener('headingChange', ({ value }) => {
needle.style.transform = `rotate(${-value}deg)`;
});
await CapgoCompass.startListening({
minInterval: 100, // ms between events
minHeadingChange: 2, // degrees
});
// Android only: ask the user to calibrate when accuracy drops
await CapgoCompass.addListener('accuracyChange', ({ accuracy }) => {
calibrationHint.hidden = accuracy >= CompassAccuracy.MEDIUM;
});
await CapgoCompass.watchAccuracy();
}
// One-off reading
const { value } = await CapgoCompass.getCurrentHeading();
value est en degrés par rapport au nord magnétique, de 0 à 360. À savoir :
- Le magnétomètre est perturbé par les aimants des coques, des ordinateurs portables et des supports de voiture. Affichez un indice de calibration (bouger le téléphone en huit) lorsque Android signale une précision faible.
- Throttlez avec
minIntervaletminHeadingChangeplutôt que dans JavaScript. Cela réduit le trafic du bridge. - Pour une carte qui tourne avec l'utilisateur, combinez le cap de direction et la géolocalisation. Si vous avez besoin de la localisation en arrière-plan, consultez le plugin de géolocalisation en arrière-plan.
Podomètre : pas, distance et étages
Le compteur de pas est une puce basse consommation qui compte en continu, même lorsque votre application n'est pas ouverte.
import { CapacitorPedometer } from '@capgo/capacitor-pedometer';
const features = await CapacitorPedometer.isAvailable();
// { stepCounting, distance, pace, cadence, floorCounting }
const perm = await CapacitorPedometer.requestPermissions();
if (perm.activityRecognition !== 'granted') {
// explain why and link to settings
}
// Steps today (start and end are required on iOS)
const startOfDay = new Date();
startOfDay.setHours(0, 0, 0, 0);
const today = await CapacitorPedometer.getMeasurement({
start: startOfDay.getTime(),
end: Date.now(),
});
console.log(today.numberOfSteps, today.distance, today.floorsAscended);
// Live updates during a walk
await CapacitorPedometer.addListener('measurement', (m) => {
stepsEl.textContent = String(m.numberOfSteps ?? 0);
});
await CapacitorPedometer.startMeasurementUpdates();
Différences de plateforme :
- iOS (Core Motion) répond aux requêtes historiques sur les sept derniers jours environ et fournit également la distance, les étages, le rythme et la cadence sur les appareils pris en charge.
- Android ne signale que les étapes. Le compteur matériel se réinitialise au redémarrage, ne le considérez donc pas comme un total cumulé. Enregistrez votre propre référence.
Pour l’historique à long terme, les totaux quotidiens entre appareils ou les données d’une montre, lisez depuis le health store avec @capgo/capacitor-health à la place. Il agrège les étapes de toutes les sources d’Apple Health et Health Connect. Notre guide de migration Health Connect explique la configuration.
Baromètre : pression et altitude
import { CapacitorBarometer } from '@capgo/capacitor-barometer';
const { isAvailable } = await CapacitorBarometer.isAvailable();
if (isAvailable) {
await CapacitorBarometer.requestPermissions();
await CapacitorBarometer.addListener('measurement', ({ pressure, relativeAltitude }) => {
pressureEl.textContent = `${pressure.toFixed(1)} hPa`;
altitudeEl.textContent = `${relativeAltitude.toFixed(1)} m`;
});
await CapacitorBarometer.startMeasurementUpdates();
}
pressure est en hectopascals sur les deux plateformes. relativeAltitude est la variation en mètres depuis le début des mises à jour, fournie uniquement par iOS. Sur Android, elle est toujours 0, calculez-la donc vous-même avec la formule barométrique :
const P0 = 1013.25; // standard sea-level pressure in hPa
const altitudeMeters = (p: number) => 44330 * (1 - Math.pow(p / P0, 1 / 5.255));
let baseline: number | null = null;
function relativeAltitude(pressure: number) {
baseline ??= altitudeMeters(pressure);
return altitudeMeters(pressure) - baseline;
}
L’altitude absolue dérivée de la pression est erronée de plusieurs dizaines de mètres car la météo modifie la pression au niveau de la mer. Les variations relatives sur quelques minutes sont précises à un mètre près, ce qui suffit pour compter les étages ou les ascensions. De nombreux téléphones Android d’entrée de gamme n’ont pas de baromètre, vérifiez donc toujours isAvailable.
Capteur de lumière ambiante (Android)
import { LightSensor } from '@capgo/capacitor-light-sensor';
const { available } = await LightSensor.isAvailable(); // always false on iOS
if (available) {
await LightSensor.addListener('lightSensorChange', ({ illuminance }) => {
document.body.classList.toggle('high-contrast', illuminance > 10_000); // bright sunlight
});
await LightSensor.start({ updateInterval: 500 });
}
Valeurs typiques : moins de 10 lux correspond à une pièce sombre, quelques centaines de lux à un bureau, des dizaines de milliers au soleil direct. Utilisez-le pour un mode lecture qui s’adapte à la pièce, ou pour augmenter le contraste en extérieur. Pour modifier la luminosité de l’écran elle-même, associez-l’à @capgo/capacitor-brightness.
Capteur de proximité
Le capteur de proximité détecte quand un objet couvre le haut de l’écran, généralement l’oreille de l’utilisateur pendant un appel.
import { CapacitorProximity } from '@capgo/capacitor-proximity';
const status = await CapacitorProximity.getStatus();
if (status.available) {
await CapacitorProximity.enable(); // screen turns off when covered
}
// when the call or voice message ends
await CapacitorProximity.disable();
Sur iOS, cela active UIDevice.isProximityMonitoringEnabled, qui éteint l’écran lorsqu’il est couvert. Sur Android, le plugin écoute le capteur de proximité et assombrit la fenêtre de l’application. Activez-l’uniquement pendant un appel vocal, un message vocal ou un mode talkie-walkie, pour éviter que la joue de l’utilisateur n’appuie sur des boutons.
Règles pratiques pour les applications utilisant des capteurs
- Vérifiez d'abord la disponibilité. Tablets often lack a step counter or barometer, and emulators fake most sensors. Hide features you cannot support.
- Arrêtez les mises à jour quand l'app n'est pas visible. Utiliser
@capacitor/appdeappStateChangepour arrêter les listeners quand l'app passe en arrière-plan et les redémarrer au retour au premier plan. Des capteurs laissés actifs vident la batterie et provoquent des avis à une étoile. - Limitez la fréquence dans le code natif si le plugin le permet (boussole
minInterval, capteur de luminositéupdateInterval), pas en JavaScript. - Demandez l'autorisation en contexte. Demandez l'accès aux mouvements lorsque l'utilisateur démarre un entraînement, pas au premier lancement.
- Testez sur du matériel réel. Les simulateurs renvoient des valeurs constantes ou synthétiques. Testez au moins un téléphone Android d'entrée de gamme, où les capteurs sont absents ou bruités.
- Respectez les règles de confidentialité. Motion and location data count as sensitive in App Store privacy labels and the Play data safety form. Declare what you collect.
Troubleshooting
Aucun événement sur iOS : la chaîne d'utilisation est manquante dans Info.plist, ou l'autorisation a été refusée. Vérifiez Réglages > Confidentialité et sécurité > Mouvement et forme.
Le podomètre renvoie 0 sur Android: ACTIVITY_RECOGNITION a été refusée, ou l'appareil n'a pas de compteur de pas. Vérifiez isAvailable().stepCounting.
La boussole est instable : interférence magnétique ou absence de calibration. Surveillez la précision sur Android et affichez une indication de calibration.
relativeAltitude est toujours 0: attendu sur Android. Calculez-l’à partir de la pression, comme indiqué ci-dessus.
DeviceMotionEvent.requestPermission throws: il n’a pas été appelé depuis un geste utilisateur.
Rapports de consommation de batterie: les listeners continuent de s’exécuter en arrière-plan. Arrêtez-les sur appStateChange.
Déployez rapidement des fonctionnalités capteurs
Les seuils, les facteurs de lissage et l’interface des fonctionnalités capteurs nécessitent généralement plusieurs itérations avec de vrais utilisateurs. Cette logique étant en JavaScript, vous pouvez l’ajuster avec les live updates Capgo sans passer par une revue du store, tandis que les nouveaux plugins et chaînes de permissions passent par un build classique. Si vous connectez des capteurs externes comme des ceintures thoraciques, poursuivez avec notre guide sur créer un moniteur de fréquence cardiaque avec Capacitor.