Capacitor-Gerätesensoren sind über kleine, spezialisierte Plugins verfügbar: @capgo/capacitor-accelerometer für Bewegung, @capgo/capacitor-barometer für Luftdruck, @capgo/capacitor-compass für Heading, @capgo/capacitor-pedometer für Schritte sowie die Light-, Proximity- und Shake-Plugins. Alle folgen demselben Muster: Verfügbarkeit prüfen, bei Bedarf Berechtigung anfordern, Updates starten, lauschen und stoppen, wenn man fertig ist. Dieser Guide deckt jeden Sensor mit Capacitor 8 code ab, die relevanten Plattformunterschiede und die Akku-Regeln, damit Apps keine Probleme bekommen.
Sensor-Übersicht
| Sensor | Plugin | iOS | Android | Berechtigung |
|---|---|---|---|---|
| Accelerometer | @capgo/capacitor-accelerometer |
Ja | Ja | iOS NSMotionUsageDescription |
| Barometer | @capgo/capacitor-barometer |
Ja, mit relativer Höhe | Ja, nur Druck, auf Geräten mit Sensor | iOS-Bewegungs-Nutzungstext |
| Kompass | @capgo/capacitor-compass |
Ja | Ja, mit Genauigkeits-Events | iOS-Standort bei Nutzung |
| Schrittzähler | @capgo/capacitor-pedometer |
Schritte, Distanz, Etagen, Tempo, Kadenz | Schritte | iOS Motion, Android ACTIVITY_RECOGNITION |
| Umgebungslicht | @capgo/capacitor-light-sensor |
Kein öffentlicher API | Ja | Keine |
| Näherungssensor | @capgo/capacitor-proximity |
Ja | Ja | Keine |
| Shake-Geste | @capgo/capacitor-shake |
Ja | Ja | Keine |
| Gyroskop / Ausrichtung | Web DeviceMotionEvent / DeviceOrientationEvent |
Ja | Ja | iOS requestPermission() in der WebView |
Installiere nur, was du nutzt. Jedes Plugin ist klein, und weniger Berechtigungstexte bedeuten weniger Fragen bei der App Review.
bun add @capgo/capacitor-accelerometer @capgo/capacitor-compass @capgo/capacitor-pedometer
bunx cap sync
iOS-Setup
Füge die Usage-Strings, die deine Sensoren benötigen, zu 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>
Erkläre den Nutzen für den Nutzer in einfachen Worten. Generische Texte wie „Diese App benötigt Motion-Zugriff“ sind ein häufiger Ablehnungsgrund bei der App Review.
Android-Setup
Die meisten Sensoren brauchen keine Berechtigung. Das Pedometer-Plugin fügt ACTIVITY_RECOGNITION dem zusammengeführten Manifest hinzu, und ab Android 10+ forderst du sie zur Laufzeit an.
Ist ein Sensor essenziell, deklariere das Hardware-Feature, damit Google Play deine App auf Geräten ohne ihn ausblendet. Ist er optional, deklariere ihn mit required="false" und prüfe die Verfügbarkeit zur Laufzeit:
<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" />
Beschleunigungssensor: Bewegung und Neigung
Der Beschleunigungssensor liefert die Beschleunigung auf der x-, y- und z-Achse in G. Ein flach liegendes Smartphone misst etwa z = -1 oder 1 an, je nach Plattform-Konvention, weil die Schwerkraft mit einfließt.
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();
}
Use Cases: Neigungssteuerung in Games, „Lift to Wake“-UI, Sturz- oder Aufprallerkennung, Aktivitätsintensität. Rohdaten sind verrauscht, also glätte sie mit einem Tiefpassfilter, bevor du sie nutzt:
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;
}
Aktualisiere das DOM nicht bei jedem Sample. Speichere den neuesten Wert und rendere ihn in einer requestAnimationFrame Schleife.
Shake-Gesten
Für „Schütteln zum Melden eines Fehlers“ oder „Schütteln zum Rückgängigmachen“ müssen Sie die Schwellenwerte nicht selbst anpassen:
import { CapacitorShake } from '@capgo/capacitor-shake';
const handle = await CapacitorShake.addListener('shake', () => openFeedbackForm());
Gyroskop und Geräteausrichtung
Für die Rotation braucht es kein separates Plugin. Die WebView stellt sie bereits bereit:
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);
Rufe requestPermission aus einem Button-Tap heraus, niemals beim Laden der Seite, sonst lehnt iOS die Anfrage ab.
Kompass: Richtung
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 ist der Winkel in Grad zum magnetischen Norden, 0 bis 360. Wichtige Details:
- Das Magnetometer wird durch Magnete in Handyhüllen, Laptops oder Autohalterungen gestört. Zeigen Sie einen Kalibrierungshinweis an (das Handy in einer Acht bewegen), wenn Android eine geringe Genauigkeit meldet.
- Drosseln mit
minIntervalundminHeadingChangeanstatt in JavaScript. Das spart Bridge-Traffic. - Für eine Karte, die sich mit dem Nutzer mitdreht, kombinieren Sie Heading mit Geolocation. Wenn Sie den Standort brauchen, während die App im Hintergrund läuft, siehe Background-Geolocation-Plugin.
Schrittzähler: Schritte, Distanz und Etagen
Der Schrittzähler ist ein stromsparender Chip, der kontinuierlich zählt, selbst wenn deine App nicht läuft.
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();
Plattformunterschiede:
- iOS (Core Motion) beantwortet historische Abfragen für etwa die letzten sieben Tage und liefert auf unterstützten Geräten zudem Distanz, Etagen, Tempo und Schrittfrequenz.
- Android meldet nur Schritte. Der Hardwarezähler wird bei einem Neustart zurückgesetzt, behandle ihn also nicht als Gesamtzähler über die Lebensdauer. Speichere deine eigene Baseline.
Für Langzeithistorie, tägliche Summen über Geräte hinweg oder Daten von einer Uhr lies aus dem Health Store mit @capgo/capacitor-health stattdessen. Es aggregiert Schritte aus allen Quellen in Apple Health und Health Connect. Unser Health Connect Migrationsguide erklärt das Setup.
Barometer: Luftdruck und Höhe
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 wird auf beiden Plattformen in Hektopascal angegeben. relativeAltitude ist die Änderung in Metern seit Beginn der Updates, die nur von iOS bereitgestellt wird. Auf Android ist es immer 0, daher musst du es selbst mit der barometrischen Formel berechnen:
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;
}
Die absolute Höhe aus dem Druck weicht um Dutzende Meter ab, da das Wetter den Luftdruck auf Meereshöhe verändert. Relative Änderungen über Minuten sind auf etwa einen Meter genau, was zum Zählen von Stockwerken oder Höhenmetern reicht. Viele günstige Android-Phones haben kein Barometer, also prüfe immer isAvailable.
Umgebungslichtsensor (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 });
}
Typische Werte: unter 10 Lux ist ein dunkler Raum, ein paar hundert Lux ist ein Büro, zehntausende Lux sind direktes Sonnenlicht. Nutze es für einen Lesemodus, der sich dem Raum anpasst, oder um den Kontrast im Freien zu erhöhen. Um die Bildschirmhelligkeit selbst zu ändern, kombiniere es mit @capgo/capacitor-brightness.
Näherungssensor
Der Proximity-Sensor zeigt an, wenn etwas die Oberseite des Bildschirms verdeckt, meistens das Ohr des Nutzers während eines Telefonats.
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();
Auf iOS schaltet dies UIDevice.isProximityMonitoringEnabledum, wodurch das Display bei Verdeckung ausgeschaltet wird. Auf Android lauscht das Plugin auf den Proximity-Sensor und dimmt das App-Fenster. Aktiviere es nur während eines Telefonats, einer Sprachnachricht oder des Walkie-Talkie-Modus, damit die Wange des Nutzers keine Buttons drückt.
Praxisregeln für Sensor-Apps
- Zuerst Verfügbarkeit prüfen. Tablets haben oft keinen Schrittzähler oder Barometer, und Emulatoren fälschen die meisten Sensoren. Blende Features aus, die du nicht unterstützen kannst.
- Updates stoppen, wenn nicht sichtbar. Nutzt
@capacitor/appsappStateChangeum Listener zu stoppen, wenn die App in den Hintergrund geht, und sie beim Resume neu zu starten. Sensoren, die weiterlaufen, ziehen Akku und führen zu Ein-Stern-Bewertungen. - In nativem code drosseln, falls das Plugin es erlaubt (Kompass
minInterval, LichtsensorupdateInterval), nicht in JavaScript. - Berechtigung im Kontext anfragen Motion-Zugriff erst beim Start eines Workouts anfordern, nicht beim ersten App-Start.
- Auf echter Hardware testen. Simulatoren liefern konstante oder synthetische Werte. Teste mindestens ein günstiges Android-Smartphone, bei dem Sensoren fehlen oder verrauscht sind.
- Datenschutzregeln beachten. Bewegungs- und Standortdaten gelten in den Datenschutzangaben des App Store und im Data-Safety-Formular von Play als sensibel. Gib an, was du sammelst.
Fehlerbehebung
Keine Events unter iOS: der Usage-String fehlt in Info.plist, oder die Berechtigung wurde verweigert. Prüfe unter Einstellungen > Datenschutz & Sicherheit > Bewegung & Fitness.
Pedometer liefert 0 unter Android: ACTIVITY_RECOGNITION wurde verweigert oder das Gerät hat keinen Schrittzähler. Prüfe isAvailable().stepCounting.
Kompass springt unkontrolliert: magnetische Störungen oder keine Kalibrierung. Achte auf die Genauigkeit unter Android und zeige einen Kalibrierungshinweis an.
relativeAltitude ist immer 0: wird auf Android erwartet. Berechne es aus dem Druck wie oben gezeigt.
DeviceMotionEvent.requestPermission wirft: es wurde nicht durch eine Benutzerinteraktion ausgelöst.
Berichte zum Akkuverbrauch: Listener laufen im Hintergrund weiter. Stoppe sie bei appStateChange.
Sensor-Features schnell ausliefern
Schwellenwerte, Glättungsfaktoren und das UI für Sensor-Features erfordern meist mehrere Tuning-Runden mit echten Nutzern. Diese Logik liegt in JavaScript, sodass du sie mit Capgo Live Updates ohne Store-Review anpassen kannst, während neue Plugins und Permission-Strings einen regulären Build durchlaufen. Wenn du externe Sensoren wie Brustgurte verbindest, fahre fort mit unserem Guide zum Einen Herzfrequenzmonitor mit Capacitor bauen.