Die meisten Android-Geräte haben integrierte Sensoren, die Bewegung, Ausrichtung und verschiedene Umgebungsbedingungen messen. Diese Sensoren können Rohdaten mit hoher Präzision und Genauigkeit liefern und sind nützlich, wenn Sie die dreidimensionale Bewegung oder Positionierung eines Geräts oder Änderungen in der Umgebung eines Geräts überwachen möchten. In einem Spiel können beispielsweise die Messwerte des Schwerkraftsensors eines Geräts erfasst werden, um komplexe Nutzergesten und -bewegungen wie Neigen, Schütteln, Drehen oder Schwingen zu erkennen. Ebenso kann eine Wetter-App den Temperatursensor und den Feuchtigkeitssensor eines Geräts verwenden, um den Taupunkt zu berechnen und zu melden, oder eine Reise-App kann den geomagnetischen Feldsensor und den Beschleunigungsmesser verwenden, um eine Kompasspeilung zu melden.
Weitere Informationen finden Sie hier:
Die Android-Plattform unterstützt drei allgemeine Kategorien von Sensoren:
- Bewegungssensoren
Diese Sensoren messen Beschleunigungs- und Rotationskräfte entlang dreier Achsen. Diese Kategorie umfasst Beschleunigungsmesser, Schwerkraftsensoren, Gyroskope und Rotationsvektorsensoren.
- Umgebungssensoren
Diese Sensoren messen verschiedene Umgebungsparameter wie Umgebungslufttemperatur und -druck, Beleuchtung und Luftfeuchtigkeit. Diese Kategorie umfasst Barometer, Fotometer und Thermometer.
- Positionssensoren
Diese Sensoren messen die physische Position eines Geräts. Diese Kategorie umfasst Orientierungssensoren und Magnetometer.
Mit dem Android-Sensor-Framework kannst du auf die auf dem Gerät verfügbaren Sensoren zugreifen und Rohsensordaten abrufen. Das Sensor-Framework bietet mehrere Klassen und Schnittstellen, mit denen du eine Vielzahl von sensorbezogenen Aufgaben ausführen kannst. Mit dem Sensor-Framework können Sie beispielsweise Folgendes tun:
- Ermitteln, welche Sensoren auf einem Gerät verfügbar sind.
- Bestimme die Funktionen eines einzelnen Sensors, z. B. die maximale Reichweite, den Hersteller, die Stromanforderungen und die Auflösung.
- Erfassen Sie Sensorrohdaten und legen Sie die Mindestrate fest, mit der Sie Sensordaten erfassen.
- Registrieren Sie Listener für Sensorereignisse, die Sensoränderungen überwachen, und heben Sie die Registrierung auf.
In diesem Artikel erhalten Sie einen Überblick über die Sensoren, die auf der Android-Plattform verfügbar sind. Außerdem wird das Sensor-Framework vorgestellt.
Einführung in Sensoren
Mit dem Android-Sensor-Framework können Sie auf viele Arten von Sensoren zugreifen. Einige dieser Sensoren sind hardwarebasiert, andere softwarebasiert. Hardwarebasierte Sensoren sind physische Komponenten, die in ein Smartphone oder Tablet eingebaut sind. Sie leiten ihre Daten ab, indem sie bestimmte Umgebungseigenschaften wie Beschleunigung, geomagnetische Feldstärke oder Winkeländerung direkt messen. Softwarebasierte Sensoren sind keine physischen Geräte, auch wenn sie hardwarebasierte Sensoren nachahmen. Softwarebasierte Sensoren leiten ihre Daten von einem oder mehreren hardwarebasierten Sensoren ab und werden manchmal als virtuelle oder synthetische Sensoren bezeichnet. Der Sensor für die lineare Beschleunigung und der Schwerkraftsensor sind Beispiele für softwarebasierte Sensoren. In Tabelle 1 sind die Sensoren zusammengefasst, die von der Android-Plattform unterstützt werden.
Nur wenige Android-Geräte haben alle Sensortypen. Die meisten Smartphones und Tablets haben beispielsweise einen Beschleunigungsmesser und ein Magnetometer, aber nur wenige Geräte haben ein Barometer oder Thermometer. Außerdem kann ein Gerät mehrere Sensoren eines bestimmten Typs haben. Ein Gerät kann beispielsweise zwei Schwerkraftsensoren mit jeweils unterschiedlichen Bereichen haben.
Tabelle 1. Von der Android-Plattform unterstützte Sensortypen.
| Sensor | Typ | Beschreibung | Gängige Einsatzmöglichkeiten |
|---|---|---|---|
TYPE_ACCELEROMETER |
Hardware | Misst die Beschleunigungskraft in m/s2, die auf ein Gerät auf allen drei physischen Achsen (x, y und z) ausgeübt wird, einschließlich der Schwerkraft. | Bewegungserkennung (Schütteln, Neigen usw.) |
TYPE_AMBIENT_TEMPERATURE |
Hardware | Misst die Umgebungstemperatur in Grad Celsius (°C). Siehe Hinweis unten. | Überwachung der Lufttemperaturen. |
TYPE_GRAVITY |
Software oder Hardware | Misst die Schwerkraft in m/s2, die auf ein Gerät auf allen drei physischen Achsen (x, y, z) einwirkt. | Bewegungserkennung (Schütteln, Neigen usw.) |
TYPE_GYROSCOPE |
Hardware | Misst die Rotationsgeschwindigkeit eines Geräts in rad/s um jede der drei physischen Achsen (x, y und z). | Drehungserkennung (Spin, Turn usw.) |
TYPE_LIGHT |
Hardware | Misst die Beleuchtungsstärke des Umgebungslichts in Lux. | Bildschirmhelligkeit steuern |
TYPE_LINEAR_ACCELERATION |
Software oder Hardware | Misst die Beschleunigungskraft in m/s2, die auf ein Gerät auf allen drei physischen Achsen (x, y und z) ausgeübt wird, ausgenommen die Schwerkraft. | Monitoring der Beschleunigung entlang einer einzelnen Achse. |
TYPE_MAGNETIC_FIELD |
Hardware | Misst das geomagnetische Feld der Umgebung für alle drei physischen Achsen (x, y, z) in μT. | Kompass erstellen |
TYPE_ORIENTATION |
Software | Misst die Drehgrade, die ein Gerät um alle drei physischen Achsen (x, y, z) ausführt.
Ab API-Level 3 können Sie die Neigungs- und Rotationsmatrix für ein Gerät abrufen, indem Sie den Schwerkraftsensor und den geomagnetischen Feldsensor in Verbindung mit der Methode getRotationMatrix() verwenden. |
Geräteposition wird ermittelt. |
TYPE_PRESSURE |
Hardware | Misst den Umgebungsluftdruck in hPa oder mbar. | Überwachung von Luftdruckänderungen. |
TYPE_PROXIMITY |
Hardware | Misst die Nähe eines Objekts in cm relativ zum Display eines Geräts. Dieser Sensor wird normalerweise verwendet, um festzustellen, ob ein Mobilgerät an das Ohr einer Person gehalten wird. | Position des Smartphones während eines Anrufs. |
TYPE_RELATIVE_HUMIDITY |
Hardware | Misst die relative Luftfeuchtigkeit in Prozent (%). | Überwachung von Taupunkt, absoluter und relativer Luftfeuchtigkeit. |
TYPE_ROTATION_VECTOR |
Software oder Hardware | Misst die Ausrichtung eines Geräts, indem die drei Elemente des Rotationsvektors des Geräts bereitgestellt werden. | Bewegungserkennung und Rotationserkennung |
TYPE_TEMPERATURE |
Hardware | Misst die Temperatur des Geräts in Grad Celsius (°C). Die Implementierung dieses Sensors variiert je nach Gerät. Er wurde in API-Level 14 durch den Sensor TYPE_AMBIENT_TEMPERATURE ersetzt. |
Temperaturen überwachen |
Sensor-Framework
Über das Android-Sensor-Framework kannst du auf diese Sensoren zugreifen und Rohsensordaten abrufen.
Das Sensor-Framework ist Teil des Pakets android.hardware und enthält die folgenden Klassen und Schnittstellen:
SensorManager- Mit dieser Klasse können Sie eine Instanz des Sensordienstes erstellen. Diese Klasse bietet verschiedene Methoden für den Zugriff auf Sensoren und deren Auflistung, die Registrierung und Abmeldung von Sensorereignis-Listenern sowie die Erfassung von Ausrichtungsinformationen. Diese Klasse bietet auch mehrere Sensorkonstanten, die verwendet werden, um die Sensorgenauigkeit zu melden, Datenerfassungsraten festzulegen und Sensoren zu kalibrieren.
Sensor- Mit dieser Klasse können Sie eine Instanz eines bestimmten Sensors erstellen. Diese Klasse bietet verschiedene Methoden, mit denen Sie die Funktionen eines Sensors ermitteln können.
SensorEvent- Das System verwendet diese Klasse, um ein Sensorereignisobjekt zu erstellen, das Informationen zu einem Sensorereignis liefert. Ein Sensoreventobjekt enthält die folgenden Informationen: die Rohsensordaten, den Typ des Sensors, der das Event generiert hat, die Genauigkeit der Daten und den Zeitstempel für das Event.
SensorEventListener- Über diese Schnittstelle kannst du zwei Callback-Methoden erstellen, die Benachrichtigungen (Sensorereignisse) erhalten, wenn sich Sensorwerte oder die Sensorgenauigkeit ändern.
In einer typischen Anwendung verwenden Sie diese sensorbezogenen APIs für zwei grundlegende Aufgaben:
- Sensoren und Sensorfunktionen identifizieren
Das Identifizieren von Sensoren und Sensorfunktionen zur Laufzeit ist nützlich, wenn deine Anwendung Funktionen hat, die auf bestimmte Sensortypen oder -funktionen angewiesen sind. Beispielsweise kannst du alle Sensoren auf einem Gerät identifizieren und alle Anwendungsfunktionen deaktivieren, die auf nicht vorhandenen Sensoren basieren. Ebenso kannst du alle Sensoren eines bestimmten Typs identifizieren, um die Sensorimplementierung mit der optimalen Leistung für deine Anwendung auszuwählen.
- Sensorereignisse überwachen
Durch das Monitoring von Sensorereignissen erhalten Sie Rohsensordaten. Ein Sensorereignis tritt jedes Mal auf, wenn ein Sensor eine Änderung der gemessenen Parameter erkennt. Ein Sensorereignis liefert vier Informationen: den Namen des Sensors, der das Ereignis ausgelöst hat, den Zeitstempel des Ereignisses, die Genauigkeit des Ereignisses und die Rohsensordaten, die das Ereignis ausgelöst haben.
Sensorverfügbarkeit
Die Verfügbarkeit von Sensoren variiert nicht nur von Gerät zu Gerät, sondern auch zwischen Android-Versionen. Das liegt daran, dass die Android-Sensoren im Laufe mehrerer Plattform-Releases eingeführt wurden. Beispielsweise wurden viele Sensoren in Android 1.5 (API-Level 3) eingeführt, aber einige wurden erst in Android 2.3 (API-Level 9) implementiert und verfügbar gemacht. Ebenso wurden in Android 2.3 (API-Level 9) und Android 4.0 (API-Level 14) mehrere Sensoren eingeführt. Zwei Sensoren wurden eingestellt und durch neuere, bessere Sensoren ersetzt.
In Tabelle 2 ist die Verfügbarkeit der einzelnen Sensoren nach Plattform zusammengefasst. Es werden nur vier Plattformen aufgeführt, da nur bei diesen Plattformen Sensoränderungen vorgenommen wurden. Sensoren, die als veraltet aufgeführt sind, sind auf nachfolgenden Plattformen weiterhin verfügbar (sofern der Sensor auf einem Gerät vorhanden ist). Dies entspricht der Richtlinie zur Aufwärtskompatibilität von Android.
Tabelle 2. Sensorverfügbarkeit nach Plattform.
| Sensor | Android 4.0 (API-Level 14) |
Android 2.3 (API-Level 9) |
Android 2.2 (API-Level 8) |
Android 1.5 (API-Level 3) |
|---|---|---|---|---|
TYPE_ACCELEROMETER |
Ja | Ja | Ja | Ja |
TYPE_AMBIENT_TEMPERATURE |
Ja | – | – | – |
TYPE_GRAVITY |
Ja | Ja | – | – |
TYPE_GYROSCOPE |
Ja | Ja | Nicht verfügbar1 | Nicht verfügbar1 |
TYPE_LIGHT |
Ja | Ja | Ja | Ja |
TYPE_LINEAR_ACCELERATION |
Ja | Ja | – | – |
TYPE_MAGNETIC_FIELD |
Ja | Ja | Ja | Ja |
TYPE_ORIENTATION |
Ja2 | Ja2 | Ja2 | Ja |
TYPE_PRESSURE |
Ja | Ja | Nicht verfügbar1 | Nicht verfügbar1 |
TYPE_PROXIMITY |
Ja | Ja | Ja | Ja |
TYPE_RELATIVE_HUMIDITY |
Ja | – | – | – |
TYPE_ROTATION_VECTOR |
Ja | Ja | – | – |
TYPE_TEMPERATURE |
Ja2 | Ja | Ja | Ja |
1 Dieser Sensortyp wurde in Android 1.5 (API-Level 3) hinzugefügt, war aber erst ab Android 2.3 (API-Level 9) verfügbar.
2 Dieser Sensor ist verfügbar, wurde aber verworfen.
Sensoren und Sensorfunktionen identifizieren
Das Android-Sensor-Framework bietet mehrere Methoden, mit denen du zur Laufzeit ganz einfach feststellen kannst, welche Sensoren auf einem Gerät vorhanden sind. Die API bietet auch Methoden, mit denen du die Funktionen der einzelnen Sensoren ermitteln kannst, z. B. die maximale Reichweite, die Auflösung und den Strombedarf.
Wenn du die Sensoren auf einem Gerät identifizieren möchtest, musst du zuerst eine Referenz auf den Sensordienst abrufen. Dazu erstellen Sie eine Instanz der Klasse SensorManager, indem Sie die Methode getSystemService() aufrufen und das Argument SENSOR_SERVICE übergeben. Beispiel:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Als Nächstes kannst du eine Liste aller Sensoren auf einem Gerät abrufen, indem du die Methode getSensorList() aufrufst und die Konstante TYPE_ALL verwendest. Beispiel:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Wenn du alle Sensoren eines bestimmten Typs auflisten möchtest, kannst du anstelle von TYPE_ALL eine andere Konstante verwenden, z. B. TYPE_GYROSCOPE, TYPE_LINEAR_ACCELERATION oder TYPE_GRAVITY.
Du kannst auch feststellen, ob ein bestimmter Sensortyp auf einem Gerät vorhanden ist, indem du die Methode getDefaultSensor() verwendest und die Typkonstante für einen bestimmten Sensor übergibst. Wenn ein Gerät mehr als einen Sensor eines bestimmten Typs hat, muss einer der Sensoren als Standardsensor festgelegt werden. Wenn für einen bestimmten Sensortyp kein Standardsensor vorhanden ist, gibt der Methodenaufruf „null“ zurück. Das bedeutet, dass das Gerät diesen Sensortyp nicht hat. Mit dem folgenden Code wird beispielsweise geprüft, ob ein Magnetometer auf einem Gerät vorhanden ist:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) { // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){ // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Hinweis:Android schreibt Geräteherstellern nicht vor, bestimmte Sensortypen in ihre Android-Geräte einzubauen. Daher können Geräte eine Vielzahl von Sensorkonfigurationen haben.
Zusätzlich zur Auflistung der Sensoren auf einem Gerät kannst du die öffentlichen Methoden der Klasse Sensor verwenden, um die Funktionen und Attribute einzelner Sensoren zu ermitteln. Das ist nützlich, wenn sich Ihre Anwendung je nach den auf einem Gerät verfügbaren Sensoren oder Sensorfunktionen unterschiedlich verhalten soll. Mit den Methoden getResolution() und getMaximumRange() kannst du beispielsweise die Auflösung und den maximalen Messbereich eines Sensors abrufen. Du kannst auch die Methode getPower() verwenden, um den Strombedarf eines Sensors zu ermitteln.
Zwei der öffentlichen Methoden sind besonders nützlich, wenn Sie Ihre Anwendung für Sensoren verschiedener Hersteller oder verschiedene Versionen eines Sensors optimieren möchten. Wenn Ihre Anwendung beispielsweise Nutzergesten wie Neigen und Schütteln überwachen muss, können Sie einen Satz von Datenfilterregeln und Optimierungen für neuere Geräte erstellen, die einen Schwerkraftsensor eines bestimmten Anbieters haben, und einen anderen Satz von Datenfilterregeln und Optimierungen für Geräte, die keinen Schwerkraftsensor und nur einen Beschleunigungsmesser haben. Im folgenden Codebeispiel wird gezeigt, wie Sie dazu die Methoden getVendor() und getVersion() verwenden können. In diesem Beispiel suchen wir nach einem Schwerkraftsensor, der Google LLC als Anbieter aufführt und die Versionsnummer 3 hat. Wenn dieser Sensor auf dem Gerät nicht vorhanden ist, wird versucht, den Beschleunigungsmesser zu verwenden.
Kotlin
private lateinit var sensorManager: SensorManager private var mSensor: Sensor? = null ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) { val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY) // Use the version 3 gravity sensor. mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 } } if (mSensor == null) { // Use the accelerometer. mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } else { // Sorry, there are no accelerometers on your device. // You can't play this game. null } }
Java
private SensorManager sensorManager; private Sensor mSensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensor = null; if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){ List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); for(int i=0; i<gravSensors.size(); i++) { if ((gravSensors.get(i).getVendor().contains("Google LLC")) && (gravSensors.get(i).getVersion() == 3)){ // Use the version 3 gravity sensor. mSensor = gravSensors.get(i); } } } if (mSensor == null){ // Use the accelerometer. if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){ mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } else{ // Sorry, there are no accelerometers on your device. // You can't play this game. } }
Eine weitere nützliche Methode ist die getMinDelay()-Methode, die das minimale Zeitintervall (in Mikrosekunden) zurückgibt, das ein Sensor zum Erfassen von Daten verwenden kann. Jeder Sensor, der für die Methode getMinDelay() einen Wert ungleich null zurückgibt, ist ein Streaming-Sensor. Streaming-Sensoren erfassen Daten in regelmäßigen Abständen und wurden in Android 2.3 (API-Level 9) eingeführt. Wenn ein Sensor beim Aufrufen der Methode getMinDelay() den Wert „0“ zurückgibt, handelt es sich nicht um einen Streamingsensor, da er nur dann Daten meldet, wenn sich die von ihm erfassten Parameter ändern.
Die Methode getMinDelay() ist nützlich, da Sie damit die maximale Rate bestimmen können, mit der ein Sensor Daten erfassen kann. Wenn bestimmte Funktionen in Ihrer Anwendung hohe Datenerfassungsraten oder einen Streamingsensor erfordern, können Sie mit dieser Methode feststellen, ob ein Sensor diese Anforderungen erfüllt, und dann die entsprechenden Funktionen in Ihrer Anwendung aktivieren oder deaktivieren.
Achtung:Die maximale Datenerfassungsrate eines Sensors ist nicht unbedingt die Rate, mit der das Sensor-Framework Sensordaten an deine Anwendung liefert. Das Sensor-Framework meldet Daten über Sensorereignisse. Die Rate, mit der deine Anwendung Sensorereignisse empfängt, wird von mehreren Faktoren beeinflusst. Weitere Informationen finden Sie unter Sensorenereignisse überwachen.
Sensorereignisse überwachen
Wenn du Rohsensordaten überwachen möchtest, musst du zwei Callback-Methoden implementieren, die über die SensorEventListener-Schnittstelle bereitgestellt werden: onAccuracyChanged() und onSensorChanged(). Das Android-System ruft diese Methoden in folgenden Fällen auf:
- Die Genauigkeit eines Sensors ändert sich.
In diesem Fall ruft das System die Methode
onAccuracyChanged()auf und stellt Ihnen einen Verweis auf das geänderteSensor-Objekt und die neue Genauigkeit des Sensors zur Verfügung. Die Genauigkeit wird durch eine von vier Statuskonstanten dargestellt:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGHoderSENSOR_STATUS_UNRELIABLE. - Ein Sensor meldet einen neuen Wert.
In diesem Fall ruft das System die Methode
onSensorChanged()auf und stellt Ihnen einSensorEvent-Objekt zur Verfügung. EinSensorEvent-Objekt enthält Informationen zu den neuen Sensordaten, darunter die Genauigkeit der Daten, der Sensor, der die Daten generiert hat, der Zeitstempel, zu dem die Daten generiert wurden, und die neuen Daten, die der Sensor aufgezeichnet hat.
Der folgende Code zeigt, wie Sie mit der Methode onSensorChanged() Daten vom Lichtsensor überwachen. In diesem Beispiel werden die Rohsensordaten in einer TextView angezeigt, die in der Datei „main.xml“ als sensor_data definiert ist.
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); } }
In diesem Beispiel wird die Standarddatenverzögerung (SENSOR_DELAY_NORMAL) angegeben, wenn die Methode registerListener() aufgerufen wird. Die Datenverzögerung (oder Abtastrate) steuert das Intervall, in dem Sensorereignisse über die Callback-Methode onSensorChanged() an Ihre Anwendung gesendet werden. Die Standarddatenverzögerung eignet sich für die Überwachung typischer Änderungen der Bildschirmausrichtung und verwendet eine Verzögerung von 200.000 Mikrosekunden. Sie können andere Datenverzögerungen angeben, z. B. SENSOR_DELAY_GAME (20.000 Mikrosekunden Verzögerung), SENSOR_DELAY_UI (60.000 Mikrosekunden Verzögerung) oder SENSOR_DELAY_FASTEST (0 Mikrosekunden Verzögerung). Ab Android 3.0 (API-Level 11) können Sie die Verzögerung auch als absoluten Wert (in Mikrosekunden) angeben.
Die von Ihnen angegebene Verzögerung ist nur eine empfohlene Verzögerung. Das Android-System und andere Anwendungen können diese Verzögerung ändern. Als Best Practice sollten Sie die größtmögliche Verzögerung angeben, da das System in der Regel eine kleinere Verzögerung als die von Ihnen angegebene verwendet. Sie sollten also die langsamste Abtastrate wählen, die die Anforderungen Ihrer Anwendung noch erfüllt. Eine größere Verzögerung führt zu einer geringeren Belastung des Prozessors und verbraucht daher weniger Strom.
Es gibt keine öffentliche Methode, um die Rate zu bestimmen, mit der das Sensor-Framework Sensorereignisse an deine Anwendung sendet. Du kannst jedoch die Zeitstempel, die jedem Sensorereignis zugeordnet sind, verwenden, um die Abtastrate über mehrere Ereignisse hinweg zu berechnen. Sie sollten die Abtastrate (Verzögerung) nicht mehr ändern müssen, nachdem Sie sie festgelegt haben. Wenn du die Verzögerung aus irgendeinem Grund ändern musst, musst du den Sensor-Listener abmelden und neu registrieren.
In diesem Beispiel werden die Callback-Methoden onResume() und onPause() verwendet, um den Sensor-Ereignis-Listener zu registrieren und die Registrierung aufzuheben. Als Best Practice sollten Sie Sensoren, die Sie nicht benötigen, immer deaktivieren, insbesondere wenn Ihre Aktivität pausiert ist. Andernfalls kann der Akku innerhalb weniger Stunden leer sein, da einige Sensoren einen erheblichen Strombedarf haben und den Akku schnell entladen können. Das System deaktiviert die Sensoren nicht automatisch, wenn das Display ausgeschaltet wird.
Umgang mit verschiedenen Sensorkonfigurationen
Android gibt keine Standardsensorkonfiguration für Geräte vor. Das bedeutet, dass Gerätehersteller jede beliebige Sensorkonfiguration in ihre Android-Geräte integrieren können. Daher können Geräte eine Vielzahl von Sensoren in einer breiten Palette von Konfigurationen enthalten. Wenn Ihre Anwendung einen bestimmten Sensortyp benötigt, müssen Sie dafür sorgen, dass der Sensor auf einem Gerät vorhanden ist, damit Ihre App erfolgreich ausgeführt werden kann.
Du hast zwei Möglichkeiten, um sicherzustellen, dass ein bestimmter Sensor auf einem Gerät vorhanden ist:
- Sensoren zur Laufzeit erkennen und Anwendungsfunktionen entsprechend aktivieren oder deaktivieren
- Verwenden Sie Google Play-Filter, um Geräte mit bestimmten Sensorkonfigurationen anzusprechen.
Diese Optionen werden in den folgenden Abschnitten erläutert.
Sensoren zur Laufzeit erkennen
Wenn deine Anwendung einen bestimmten Sensortyp verwendet, aber nicht darauf angewiesen ist, kannst du das Sensor-Framework verwenden, um den Sensor zur Laufzeit zu erkennen und dann die Anwendungsfunktionen entsprechend zu deaktivieren oder zu aktivieren. Eine Navigations-App kann beispielsweise den Temperatursensor, den Drucksensor, den GPS-Sensor und den geomagnetischen Feldsensor verwenden, um die Temperatur, den Luftdruck, den Standort und die Kompassrichtung anzuzeigen. Wenn ein Gerät keinen Drucksensor hat, kannst du das Sensor-Framework verwenden, um das Fehlen des Drucksensors zur Laufzeit zu erkennen und dann den Teil der Benutzeroberfläche deiner Anwendung zu deaktivieren, in dem der Druck angezeigt wird. Mit dem folgenden Code wird beispielsweise geprüft, ob ein Gerät einen Drucksensor hat:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) { // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){ // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Google Play-Filter für die Ausrichtung auf bestimmte Sensorkonfigurationen verwenden
Wenn du deine App bei Google Play veröffentlichst, kannst du das Element <uses-feature>
in deiner Manifestdatei verwenden, um deine App auf Geräten herauszufiltern, die nicht die entsprechende Sensorkonfiguration für deine App haben. Das Element <uses-feature> enthält mehrere Hardwaredeskriptoren, mit denen Sie Anwendungen nach dem Vorhandensein bestimmter Sensoren filtern können. Zu den Sensoren, die Sie auflisten können, gehören: Beschleunigungsmesser, Barometer, Kompass (geomagnetisches Feld), Gyroskop, Licht und Näherung. Das folgende Beispiel zeigt einen Manifesteintrag, mit dem Apps herausgefiltert werden, die keinen Beschleunigungsmesser haben:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Wenn du dieses Element und diesen Deskriptor dem Manifest deiner App hinzufügst, wird deine App nur Nutzern mit einem Beschleunigungsmesser auf ihrem Gerät bei Google Play angezeigt.
Du solltest den Deskriptor nur dann auf android:required="true" setzen, wenn deine Anwendung vollständig auf einen bestimmten Sensor angewiesen ist. Wenn deine Anwendung einen Sensor für bestimmte Funktionen verwendet, aber auch ohne den Sensor funktioniert, solltest du den Sensor im <uses-feature>-Element auflisten, aber den Deskriptor auf android:required="false" setzen. So können Nutzer Ihre App auch dann auf ihren Geräten installieren, wenn sie nicht über den entsprechenden Sensor verfügen. Dies ist auch eine Best Practice für das Projektmanagement, mit der Sie die von Ihrer Anwendung verwendeten Funktionen im Blick behalten können.
Wenn Ihre Anwendung einen bestimmten Sensor verwendet, aber auch ohne den Sensor ausgeführt wird, sollten Sie den Sensor zur Laufzeit erkennen und die Anwendungsfunktionen entsprechend deaktivieren oder aktivieren.
Sensorkoordinatensystem
Im Allgemeinen verwendet das Sensor-Framework ein standardmäßiges 3-Achsen-Koordinatensystem, um Datenwerte auszudrücken. Bei den meisten Sensoren wird das Koordinatensystem relativ zum Bildschirm des Geräts definiert, wenn das Gerät in seiner Standardausrichtung gehalten wird (siehe Abbildung 1). Wenn ein Gerät in seiner Standardausrichtung gehalten wird, ist die X-Achse horizontal und zeigt nach rechts, die Y-Achse ist vertikal und zeigt nach oben und die Z-Achse zeigt nach außen. In diesem System haben Koordinaten hinter dem Bildschirm negative Z-Werte. Dieses Koordinatensystem wird von den folgenden Sensoren verwendet:
Abbildung 1. Koordinatensystem (relativ zu einem Gerät), das von der Sensor API verwendet wird.
- Beschleunigungssensor
- Schwerkraftsensor
- Gyroskop
- Sensor für lineare Beschleunigung
- Geomagnetischer Sensor
Der wichtigste Punkt bei diesem Koordinatensystem ist, dass die Achsen nicht vertauscht werden, wenn sich die Bildschirmausrichtung des Geräts ändert. Das Koordinatensystem des Sensors ändert sich also nie, wenn sich das Gerät bewegt. Dieses Verhalten entspricht dem des OpenGL-Koordinatensystems.
Ein weiterer wichtiger Punkt ist, dass deine Anwendung nicht davon ausgehen darf, dass die natürliche (Standard-)Ausrichtung eines Geräts das Hochformat ist. Die natürliche Ausrichtung für viele Tablets ist das Querformat. Das Koordinatensystem des Sensors basiert immer auf der natürlichen Ausrichtung eines Geräts.
Wenn deine App Sensordaten mit der Bildschirmanzeige abgleicht, musst du die Methode getRotation() verwenden, um die Bildschirmdrehung zu bestimmen, und dann die Methode remapCoordinateSystem(), um Sensorkoordinaten auf Bildschirmkoordinaten abzubilden. Dies ist auch dann erforderlich, wenn im Manifest nur die Anzeige im Hochformat angegeben ist.
Hinweis:Einige Sensoren und Methoden verwenden ein Koordinatensystem, das sich auf das Bezugssystem der Welt bezieht (im Gegensatz zum Bezugssystem des Geräts). Diese Sensoren und Methoden geben Daten zurück, die die Bewegung oder Position des Geräts relativ zur Erde darstellen. Weitere Informationen finden Sie unter der Methode getOrientation(), der Methode getRotationMatrix(), Ausrichtungssensor und Rotationsvektorsensor.
Ratenbegrenzung für Sensoren
Wenn Ihre App auf Android 12 (API-Level 31) oder höher ausgerichtet ist, begrenzt das System die Aktualisierungsrate der Daten von bestimmten Bewegungs- und Positionssensoren, um potenziell vertrauliche Informationen über Nutzer zu schützen. Diese Daten umfassen Werte, die vom Beschleunigungsmesser, vom Gyroskop und vom geomagnetischen Feldsensor des Geräts aufgezeichnet wurden.
Die maximale Aktualisierungsrate hängt davon ab, wie du auf Sensordaten zugreifst:
- Wenn du die Methode
registerListener()aufrufst, um Sensorereignisse zu überwachen, ist die Abtastrate des Sensors auf 200 Hz begrenzt. Dies gilt für alle überladenen Varianten der MethoderegisterListener(). - Wenn du die Klasse
SensorDirectChannelverwendest, ist die Abtastrate des Sensors aufRATE_NORMALbegrenzt, was normalerweise etwa 50 Hz entspricht.
Wenn deine App Bewegungssensordaten mit einer höheren Rate erfassen muss, musst du die Berechtigung HIGH_SAMPLING_RATE_SENSORS deklarieren, wie im folgenden Code-Snippet gezeigt. Wenn deine App versucht, Bewegungssensordaten mit einer höheren Rate zu erfassen, ohne diese Berechtigung zu deklarieren, tritt eine SecurityException auf.
AndroidManifest.xml
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Best Practices für den Zugriff auf Sensoren und deren Verwendung
Beachten Sie beim Entwerfen Ihrer Sensorimplementierung die in diesem Abschnitt beschriebenen Richtlinien. Diese Richtlinien sind empfohlene Best Practices für alle, die das Sensor-Framework verwenden, um auf Sensoren zuzugreifen und Sensordaten zu erfassen.
Sensordaten nur im Vordergrund erfassen
Auf Geräten mit Android 9 (API-Level 28) oder höher gelten für im Hintergrund ausgeführte Apps die folgenden Einschränkungen:
- Sensoren, die den kontinuierlichen Berichtsmodus verwenden, z. B. Beschleunigungsmesser und Gyroskope, empfangen keine Ereignisse.
- Sensoren, die die Berichtsmodi on-change oder one-shot verwenden, empfangen keine Ereignisse.
Aufgrund dieser Einschränkungen ist es am besten, Sensorereignisse entweder zu erkennen, wenn sich Ihre App im Vordergrund befindet, oder als Teil eines Dienstes im Vordergrund.
Registrierung von Sensor-Listenern aufheben
Melde den Listener eines Sensors ab, wenn du den Sensor nicht mehr verwendest oder wenn die Sensoraktivität pausiert. Wenn ein Sensor-Listener registriert ist und seine Aktivität pausiert wird, erfasst der Sensor weiterhin Daten und verbraucht Akkuleistung, sofern Sie die Registrierung des Sensors nicht aufheben. Der folgende Code zeigt, wie Sie die Methode onPause() verwenden, um die Registrierung eines Listeners aufzuheben:
Kotlin
private lateinit var sensorManager: SensorManager ... override fun onPause() { super.onPause() sensorManager.unregisterListener(this) }
Java
private SensorManager sensorManager; ... @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
Weitere Informationen finden Sie unter unregisterListener(SensorEventListener).
Mit dem Android-Emulator testen
Der Android-Emulator enthält eine Reihe von virtuellen Sensorsteuerungen, mit denen du Sensoren wie Beschleunigungsmesser, Umgebungstemperatur, Magnetometer, Näherung, Licht und mehr testen kannst.

Der Emulator verwendet eine Verbindung mit einem Android-Gerät, auf dem die App SdkControllerSensor ausgeführt wird. Diese App ist nur auf Geräten mit Android 4.0 (API-Level 14) oder höher verfügbar. (Wenn auf dem Gerät Android 4.0 ausgeführt wird, muss Version 2 installiert sein.) Die App SdkControllerSensor überwacht Änderungen an den Sensoren auf dem Gerät und überträgt sie an den Emulator. Der Emulator wird dann basierend auf den neuen Werten transformiert, die er von den Sensoren auf Ihrem Gerät empfängt.
Den Quellcode für die SdkControllerSensor-App findest du hier:
$ your-android-sdk-directory/tools/apps/SdkController
So übertragen Sie Daten zwischen Ihrem Gerät und dem Emulator:
- Prüfen Sie, ob USB-Debugging auf Ihrem Gerät aktiviert ist.
- Verbinden Sie Ihr Gerät über ein USB-Kabel mit Ihrer Entwicklungsmaschine.
- Starten Sie die App SdkControllerSensor auf Ihrem Gerät.
- Wählen Sie in der App die Sensoren aus, die Sie emulieren möchten.
Führen Sie folgenden Befehl
adbaus:- Starten Sie den Emulator. Sie sollten jetzt Transformationen auf den Emulator anwenden können, indem Sie Ihr Gerät bewegen.
$ adb forward tcp:1968 tcp:1968
Hinweis: Wenn die Bewegungen, die Sie mit Ihrem physischen Gerät ausführen, nicht auf den Emulator übertragen werden, führen Sie den Befehl adb aus Schritt 5 noch einmal aus.
Weitere Informationen finden Sie im Leitfaden zum Android-Emulator.
Methode „onSensorChanged()“ nicht blockieren
Sensordaten können sich schnell ändern. Das bedeutet, dass das System die Methode onSensorChanged(SensorEvent) möglicherweise recht häufig aufruft. Als Best Practice sollten Sie in der Methode onSensorChanged(SensorEvent) so wenig wie möglich tun, damit sie nicht blockiert wird. Wenn Ihre Anwendung eine Datenfilterung oder Reduzierung von Sensordaten erfordert, sollten Sie diese Arbeit außerhalb der Methode onSensorChanged(SensorEvent) ausführen.
Vermeide die Verwendung veralteter Methoden oder Sensortypen.
Mehrere Methoden und Konstanten wurden eingestellt.
Insbesondere der Sensortyp TYPE_ORIENTATION wurde eingestellt. Wenn Sie Ausrichtungsdaten abrufen möchten, sollten Sie stattdessen die Methode getOrientation() verwenden. Ebenso wurde der Sensortyp TYPE_TEMPERATURE eingestellt. Auf Geräten mit Android 4.0 solltest du stattdessen den Sensortyp TYPE_AMBIENT_TEMPERATURE verwenden.
Sensoren vor der Verwendung überprüfen
Prüfen Sie immer, ob ein Sensor auf einem Gerät vorhanden ist, bevor Sie versuchen, Daten von ihm abzurufen. Gehe nicht davon aus, dass ein Sensor vorhanden ist, nur weil er häufig verwendet wird. Gerätehersteller sind nicht verpflichtet, bestimmte Sensoren in ihren Geräten bereitzustellen.
Sensorverzögerungen sorgfältig auswählen
Wenn Sie einen Sensor mit der Methode registerListener() registrieren, wählen Sie eine Übermittlungsrate aus, die für Ihre Anwendung oder Ihren Anwendungsfall geeignet ist. Sensoren können Daten mit sehr hohen Raten liefern. Wenn das System zusätzliche Daten senden kann, die Sie nicht benötigen, werden Systemressourcen verschwendet und der Akku wird beansprucht.