Start · Sprachen · JavaScript · Referenz · DeviceMotionEvent.requestPermission()

DeviceMotionEvent.requestPermission()

Methode

Statische Methode, die den Benutzer um Erlaubnis bittet, Bewegungsdaten von Beschleunigungssensor und Gyroskop über <code>devicemotion</code>-Events zu empfangen.

seit JavaScript Safari iOS 13+ (nicht standardisiert in anderen Br Kategorie: webapi

Signatur

DeviceMotionEvent.requestPermission()

Beschreibung

DeviceMotionEvent.requestPermission() ist eine statische Methode, mit der eine Webseite ausdrücklich die Zustimmung des Benutzers einholt, bevor sie devicemotion-Events mit Daten von Beschleunigungssensor und Gyroskop empfangen darf. Eingeführt hat Apple sie mit iOS 13. Hintergrund: Mit Bewegungsdaten lassen sich Nutzer über Fingerprinting wiedererkennen und sogar Tastatureingaben erraten.

Die Methode gibt ein Promise zurück, das mit "granted" oder "denied" erfüllt wird. Erst nach "granted" liefert der mit window.addEventListener("devicemotion", …) registrierte Handler echte Werte. Die Entscheidung des Nutzers gilt für den Ursprung (Origin) meist bis zum Ende der Sitzung.

Wichtig: Der Aufruf muss durch eine Benutzeraktivierung ausgelöst werden, also direkt in einem Handler für click, touchend o. Ä. Sonst wird das Promise abgelehnt. Da die Methode in Chrome, Firefox und Android-Browsern fehlt, sollte man immer per Feature-Erkennung prüfen, ob typeof DeviceMotionEvent.requestPermission === "function" gilt. Fehlt die Methode, lässt sich der Listener dort meist direkt registrieren.

Rückgabewert

Typ
Promise<"granted" | "denied">
Beschreibung
Ein Promise, das mit "granted" erfüllt wird, wenn der Nutzer zustimmt, und mit "denied", wenn er ablehnt. Abgelehnt (reject) wird es z. B. mit einem NotAllowedError, wenn der Aufruf ohne Benutzeraktivierung erfolgt.

Beispiele

Berechtigung per Button-Klick anfordern

const button = document.querySelector('#sensor-start');

const handleMotion = (event) => {
  const { x, y, z } = event.accelerationIncludingGravity ?? {};
  console.log(`Beschleunigung: x=${x?.toFixed(2)} y=${y?.toFixed(2)} z=${z?.toFixed(2)}`);
};

button.addEventListener('click', async () => {
  try {
    const state = await DeviceMotionEvent.requestPermission();
    if (state === 'granted') {
      window.addEventListener('devicemotion', handleMotion);
    } else {
      console.warn('Zugriff auf Bewegungssensoren verweigert.');
    }
  } catch (err) {
    console.error('Anfrage fehlgeschlagen:', err.name, err.message);
  }
});
Beschleunigung: x=0.12 y=9.78 z=0.31

Browserübergreifend mit Feature-Erkennung

const enableMotion = async () => {
  // Nur iOS Safari (13+) kennt requestPermission
  if (typeof DeviceMotionEvent !== 'undefined' &&
      typeof DeviceMotionEvent.requestPermission === 'function') {
    const state = await DeviceMotionEvent.requestPermission();
    if (state !== 'granted') return false;
  } else if (typeof DeviceMotionEvent === 'undefined') {
    return false; // Keine Unterstützung
  }

  window.addEventListener('devicemotion', (e) => {
    console.log('Drehrate alpha:', e.rotationRate?.alpha);
  });
  return true;
};

document.querySelector('#start').addEventListener('click', async () => {
  const ok = await enableMotion();
  console.log(ok ? 'Sensoren aktiv' : 'Sensoren nicht verfügbar');
});
Sensoren aktiv Drehrate alpha: 1.52

Bewegung und Ausrichtung zusammen freischalten

document.querySelector('#play').addEventListener('click', async () => {
  const requests = [];
  if (typeof DeviceMotionEvent?.requestPermission === 'function') {
    requests.push(DeviceMotionEvent.requestPermission());
  }
  if (typeof DeviceOrientationEvent?.requestPermission === 'function') {
    requests.push(DeviceOrientationEvent.requestPermission());
  }

  const results = await Promise.all(requests);
  const allGranted = results.every((r) => r === 'granted');
  console.log(allGranted ? 'Spiel startet' : 'Steuerung per Neigung nicht möglich');
});
Spiel startet

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Die Methode gibt es nur in Safari auf iOS/iPadOS 13+. Chrome, Firefox und Edge kennen sie nicht. Dort führt ein direkter Aufruf zu einem TypeError. Deshalb immer per Feature-Erkennung prüfen.
  • Benutzeraktivierung nötig: Ein Aufruf beim Laden der Seite oder in einem setTimeout ohne vorherige Nutzeraktion wird abgelehnt. Gehen vor dem Aufruf mehrere await-Schritte voraus, kann die Aktivierung bereits verfallen sein. Rufe die Methode daher möglichst früh im Handler auf.
  • Sicherer Kontext: Bewegungssensoren stehen nur über HTTPS (oder localhost) zur Verfügung.
  • In <iframe>-Elementen muss die Einbettung die Freigabe über die Permissions Policy erlauben, z. B. allow="accelerometer; gyroscope".
  • Hat der Nutzer abgelehnt, erscheint beim nächsten Aufruf in derselben Sitzung oft kein Dialog mehr. Das Promise liefert dann direkt "denied". Blende in diesem Fall einen Hinweis ein, wie sich die Freigabe in den Einstellungen bzw. per Neuladen der Seite erneut erteilen lässt.
  • Datenschutz: Bewegungsdaten eignen sich für Fingerprinting. Frage die Berechtigung nur an, wenn die Funktion sie wirklich braucht, und erkläre dem Nutzer vorher, wofür.