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. Sie sind nützlich, wenn Sie die dreidimensionale Bewegung oder Positionierung von Geräten oder Änderungen in der Umgebungsumgebung in der Nähe eines Geräts beobachten möchten. Ein Spiel könnte beispielsweise die Messwerte des Schwerkraftsensors eines Geräts erfassen, um komplexe Nutzergesten und -bewegungen wie Neigung, Schütteln, Drehen oder Schlagen abzuleiten. Ebenso könnte eine Wetteranwendung den Temperatur- und Luftfeuchtigkeitssensor eines Geräts verwenden, um den Taupunkt zu berechnen und zu melden, oder eine Reiseanwendung könnte den Sensor für geomagnetische Felder und den Beschleunigungsmesser verwenden, um die Kompassposition zu melden.
Weitere Informationen finden Sie in den folgenden verwandten Ressourcen:
Die Android-Plattform unterstützt drei große Kategorien von Sensoren:
- Bewegungssensoren
Diese Sensoren messen Beschleunigungs- und Rotationskräfte entlang drei Achsen. Zu dieser Kategorie gehören Beschleunigungsmesser, Schwerkraftsensoren, Gyroskope und Rotationsvektorsensoren.
- Umgebungssensoren
Diese Sensoren messen verschiedene Umgebungsparameter wie Umgebungstemperatur 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 Ausrichtungssensoren und Magnetometer.
Mit dem Android-Sensor-Framework können Sie auf die auf dem Gerät verfügbaren Sensoren zugreifen und Sensor-Rohdaten erfassen. Das Sensor-Framework bietet mehrere Klassen und Schnittstellen, mit denen Sie eine Vielzahl von sensorbezogenen Aufgaben ausführen können. Mit dem Sensor-Framework können Sie beispielsweise Folgendes tun:
- Herausfinden, welche Sensoren auf einem Gerät verfügbar sind
- Bestimmen Sie die Funktionen eines einzelnen Sensors, z. B. maximale Reichweite, Hersteller, Energiebedarf und Auflösung.
- Erfassen Sie Sensorrohdaten und definieren Sie die Mindestrate, mit der Sie Sensordaten erfassen.
- Sensorereignis-Listener, die Sensoränderungen überwachen, registrieren und die Registrierung aufheben
In diesem Artikel erhalten Sie einen Überblick über die Sensoren, die auf der Android-Plattform verfügbar sind. Sie bietet auch eine Einführung in das Sensorsystem.
Einführung in Sensoren
Mit dem Android-Sensor-Framework kannst du auf viele Arten von Sensoren zugreifen. Einige dieser Sensoren sind hardwarebasiert, andere softwarebasiert. Hardwarebasierte Sensoren sind physische Komponenten, die in ein Mobiltelefon oder Tablet integriert 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, obwohl sie hardwarebasierte Sensoren imitieren. Softwarebasierte Sensoren leiten ihre Daten von einem oder mehreren hardwarebasierten Sensoren ab und werden manchmal als virtuelle Sensoren oder synthetische Sensoren bezeichnet. Der lineare Beschleunigungssensor und der Schwerkraftsensor sind Beispiele für softwarebasierte Sensoren. In Tabelle 1 sind die Sensoren aufgeführt, die von der Android-Plattform unterstützt werden.
Nur wenige Android-Geräte haben alle Arten von Sensor. Die meisten Mobilgeräte und Tablets haben beispielsweise einen Beschleunigungsmesser und ein Magnetometer, aber weniger Geräte haben Barometer oder Thermometer. Außerdem kann ein Gerät mehr als einen Sensor eines bestimmten Typs haben. Ein Gerät kann beispielsweise zwei Schwerkraftsensoren haben, die jeweils einen anderen Bereich haben.
Tabelle 1 Von der Android-Plattform unterstützte Sensortypen.
Sensor | Typ | Beschreibung | Übliche Anwendungsbereiche |
---|---|---|---|
TYPE_ACCELEROMETER |
Hardware | Misst die Beschleunigungskraft in m/s2, die auf ein Gerät auf alle drei physischen Achsen (x, y und z) angewendet wird, einschließlich der Schwerkraft. | Bewegungserkennung (Schütteln, Neigen usw.). |
TYPE_AMBIENT_TEMPERATURE |
Hardware | Gibt die Raumtemperatur in Grad Celsius (°C) an. 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) angewendet wird. | Bewegungserkennung (Schütteln, Neigen usw.). |
TYPE_GYROSCOPE |
Hardware | Misst die Drehgeschwindigkeit eines Geräts in Rad/s um jede der drei physischen Achsen (x, y und z). | Rotationserkennung (Drehen, Drehen usw.). |
TYPE_LIGHT |
Hardware | Gibt die Lichtintensität der Umgebung (Beleuchtung) in x L an. | Bildschirmhelligkeit regeln |
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) angewendet wird, ohne die Schwerkraft. | Beschleunigung entlang einer einzelnen Achse überwachen |
TYPE_MAGNETIC_FIELD |
Hardware | Misst das geomagnetische Umgebungsfeld für alle drei physischen Achsen (x, y, z) in μT. | Kompass erstellen |
TYPE_ORIENTATION |
Software | Misst die Drehungsgrade eines Geräts um alle drei physischen Achsen (x, y, z).
Ab API-Level 3 können Sie die Neigungs- und Rotationsmatrix für ein Gerät abrufen, indem Sie den Schwerkraftsensor und den Sensor für geomagnetische Felder in Verbindung mit der getRotationMatrix() -Methode verwenden. |
Geräteposition wird ermittelt. |
TYPE_PRESSURE |
Hardware | Misst den Luftdruck in hPa oder mbar. | Überwachung von Luftdruckänderungen. |
TYPE_PROXIMITY |
Hardware | Misst die Nähe eines Objekts in cm relativ zum Anzeigebildschirm eines Geräts. Dieser Sensor wird in der Regel verwendet, um festzustellen, ob ein Mobilgerät an das Ohr einer Person gehalten wird. | Position des Telefons während eines Anrufs. |
TYPE_RELATIVE_HUMIDITY |
Hardware | Gibt die relative Luftfeuchtigkeit in Prozent (%) an. | Ü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 angegeben werden. | Bewegungserkennung und Rotationserkennung. |
TYPE_TEMPERATURE |
Hardware | Misst die Temperatur des Geräts in Grad Celsius (°C). Diese Sensorimplementierung variiert je nach Gerät. Dieser Sensor wurde in API-Level 14 durch den TYPE_AMBIENT_TEMPERATURE -Sensor ersetzt. |
Überwachen von Temperaturen. |
Sensorrahmen
Mithilfe des Android-Sensor-Frameworks können Sie auf diese Sensoren zugreifen und Sensorrohdaten erfassen.
Das Sensor-Framework ist Teil des android.hardware
-Pakets und umfasst 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 und das Auflisten von Sensoren, das Registrieren und Aufheben der Registrierung von Sensorereignis-Listenern sowie das Erfassen von Ausrichtungsinformationen. Diese Klasse bietet auch mehrere Sensorkonstanten, mit denen die Sensorgenauigkeit gemeldet, Datenaufnahmeraten festgelegt und Sensoren kalibriert werden können.
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 bereitstellt. Ein Sensorereignisobjekt enthält die folgenden Informationen: die Sensorrohdaten, den Sensortyp, der das Ereignis generiert hat, die Genauigkeit der Daten und den Zeitstempel des Ereignisses.
SensorEventListener
- Sie können diese Oberfläche verwenden, um zwei Callback-Methoden zu erstellen, die Benachrichtigungen (Sensorereignisse) erhalten, wenn sich Sensorwerte oder die Sensorgenauigkeit ändern.
In einer typischen Anwendung verwenden Sie diese sensorbezogenen APIs, um zwei grundlegende Aufgaben auszuführen:
- Sensoren und Sensorfunktionen erkennen
Die Identifizierung von Sensoren und Sensorfunktionen während der Laufzeit ist nützlich, wenn Ihre Anwendung Funktionen enthält, die auf bestimmten Sensortypen oder ‐funktionen basieren. Beispielsweise können Sie alle auf einem Gerät vorhandenen Sensoren ermitteln und alle Anwendungsfunktionen deaktivieren, die auf nicht vorhandenen Sensoren basieren. Ebenso können Sie alle Sensoren eines bestimmten Typs identifizieren, damit Sie die Sensorimplementierung auswählen können, die für Ihre Anwendung die optimale Leistung bietet.
- Sensorereignisse beobachten
Über das Monitoring von Sensorereignissen werden Sensorrohdaten erfasst. Ein Sensorereignis tritt jedes Mal auf, wenn ein Sensor eine Änderung der zu messenden Parameter erkennt. Bei einem Sensorereignis erhalten Sie vier Informationen: den Namen des Sensors, der das Ereignis ausgelöst hat, den Zeitstempel des Ereignisses, die Genauigkeit des Ereignisses und die Sensorrohdaten, die das Ereignis ausgelöst haben.
Sensorverfügbarkeit
Die Sensorverfügbarkeit variiert je nach Gerät, kann aber auch zwischen Android-Versionen variieren. 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, einige waren jedoch erst implementiert und konnten erst ab Android 2.3 (API-Level 9) verwendet werden. Außerdem 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 sind nur vier Plattformen aufgeführt, da auf diesen Plattformen Sensoränderungen vorgenommen wurden. Sensoren, die als veraltet aufgeführt sind, sind weiterhin auf nachfolgenden Plattformen 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 eingestellt.
Sensoren und Sensorfunktionen identifizieren
Das Android-Sensor-Framework bietet mehrere Methoden, mit denen Sie ganz einfach ermitteln können, welche Sensoren sich auf einem Gerät befinden. Die API bietet auch Methoden, mit denen Sie die Funktionen jedes Sensors ermitteln können, z. B. maximale Reichweite, Auflösung und Leistungsanforderungen.
Um die Sensoren eines Geräts zu identifizieren, musst du zuerst eine Referenz zum Sensordienst abrufen. Dazu erstellen Sie eine Instanz der SensorManager
-Klasse. Dazu rufen Sie die Methode getSystemService()
auf und übergeben das Argument SENSOR_SERVICE
. 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 können Sie eine Liste aller Sensoren auf einem Gerät abrufen. Dazu rufen Sie die Methode getSensorList()
auf und verwenden die Konstante TYPE_ALL
. Beispiel:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Wenn Sie alle Sensoren eines bestimmten Typs auflisten möchten, können Sie anstelle von TYPE_ALL
eine andere Konstante verwenden, z. B. TYPE_GYROSCOPE
, TYPE_LINEAR_ACCELERATION
oder TYPE_GRAVITY
.
Mit der Methode getDefaultSensor()
und Übergeben der Typkonstante für einen bestimmten Sensor können Sie auch feststellen, ob auf einem Gerät ein bestimmter Sensortyp vorhanden ist. 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 nicht über diesen Sensortyp verfügt. Der folgende Code prüft beispielsweise, ob sich ein Magnetometer an einem Gerät befindet:
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:Bei Android müssen Gerätehersteller keine bestimmten Sensorentypen in ihre Android-Geräte einbauen. Daher können die Geräte eine Vielzahl von Sensorkonfigurationen haben.
Neben der Auflistung der Sensoren eines Geräts kannst du die öffentlichen Methoden der Klasse Sensor
verwenden, um die Funktionen und Attribute der einzelnen Sensoren zu ermitteln. Dies ist nützlich, wenn sich Ihre Anwendung je nachdem, welche Sensoren oder Sensorfunktionen auf einem Gerät verfügbar sind, anders verhalten soll. Sie können beispielsweise die Methoden getResolution()
und getMaximumRange()
verwenden, um die Auflösung und den maximalen Messbereich eines Sensors zu ermitteln. Sie können auch die Methode getPower()
verwenden, um den Energiebedarf eines Sensors zu ermitteln.
Zwei der öffentlichen Methoden sind besonders nützlich, wenn Sie Ihre Anwendung für verschiedene Sensoren verschiedener Hersteller oder verschiedene Versionen eines Sensors optimieren möchten. Wenn Ihre Anwendung beispielsweise Nutzergesten wie Neigung und Schütteln überwachen muss, können Sie einen Satz von Datenfilterregeln und Optimierungen für neuere Geräte mit einem bestimmten Schwerkraftsensor eines bestimmten Anbieters und einen weiteren Satz von Datenfilterregeln und Optimierungen für Geräte erstellen, die keinen Gravitationssensor und nur einen Beschleunigungsmesser haben. Das folgende Codebeispiel zeigt, wie Sie die Methoden getVendor()
und getVersion()
dazu verwenden können. In diesem Beispiel suchen wir nach einem Schwerkraftsensor, der Google LLC als Anbieter angibt und die Versionsnummer 3 hat. Wenn dieser Sensor nicht auf dem Gerät vorhanden ist, versuchen wir, ihn 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 Methode getMinDelay()
. Sie gibt das minimale Zeitintervall (in Mikrosekunden) zurück, 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 Streamingsensor. Streamingsensoren 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()
Null zurückgibt, ist der Sensor kein Streamingsensor, da er Daten nur dann ausgibt, wenn sich die zu erkennenden Parameter ändern.
Die Methode getMinDelay()
ist nützlich, da Sie damit die maximale Rate ermitteln können, mit der ein Sensor Daten erfassen kann. Wenn bestimmte Funktionen Ihrer Anwendung hohe Datenakquiseraten 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 Datenaufnahmerate eines Sensors ist nicht unbedingt die Geschwindigkeit, mit der das Sensor-Framework Sensordaten an Ihre Anwendung liefert. Das Sensor-Framework meldet Daten anhand von Sensorereignissen. Dabei beeinflussen mehrere Faktoren die Geschwindigkeit, mit der Ihre Anwendung Sensorereignisse empfängt. Weitere Informationen finden Sie unter Sensorereignisse überwachen.
Sensorereignisse überwachen
Zum Überwachen von Sensorrohdaten müssen zwei Callback-Methoden implementiert werden, die über die SensorEventListener
-Schnittstelle verfügbar gemacht werden: onAccuracyChanged()
und onSensorChanged()
. Das Android-System ruft diese Methoden immer dann auf, wenn Folgendes eintritt:
- Die Genauigkeit eines Sensors ändert sich.
In diesem Fall ruft das System die Methode
onAccuracyChanged()
auf und gibt Ihnen einen Verweis auf das geänderteSensor
-Objekt und die neue Genauigkeit des Sensors. Die Genauigkeit wird durch eine von vier Statuskonstanten angegeben:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
oderSENSOR_STATUS_UNRELIABLE
. - Ein Sensor meldet einen neuen Wert.
In diesem Fall ruft das System die Methode
onSensorChanged()
auf und stellt einSensorEvent
-Objekt bereit. EinSensorEvent
-Objekt enthält Informationen zu den neuen Sensordaten, darunter die Genauigkeit der Daten, den Sensor, der die Daten generiert hat, den 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 Sensorrohdaten in einem TextView
angezeigt, das 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) bestimmt das Intervall, in dem Sensorereignisse über die Callback-Methode onSensorChanged()
an Ihre App gesendet werden. Die Standarddatenverzögerung eignet sich zum Überwachen 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
(Verzögerung von 0 Mikrosekunden). Ab Android 3.0 (API-Level 11) kannst du die Verzögerung auch als absoluten Wert (in Mikrosekunden) angeben.
Die von Ihnen angegebene Verzögerung ist nur eine vorgeschlagene Verzögerung. Das Android-System und andere Anwendungen können diese Verzögerung ändern. Sie sollten die größtmögliche Verzögerung angeben, da das System normalerweise eine kleinere Verzögerung als die von Ihnen angegebene verwendet. Sie sollten also die langsamste Sampling-Rate auswählen, die noch den Anforderungen Ihrer Anwendung entspricht. Eine größere Verzögerung führt zu einer geringeren Belastung des Prozessors und verbraucht so weniger Energie.
Es gibt keine öffentliche Methode, um die Rate zu bestimmen, mit der das Sensor-Framework Sensorereignisse an Ihre Anwendung sendet. Sie können jedoch die Zeitstempel für jedes Sensorereignis verwenden, um die Abtastrate für mehrere Ereignisse zu berechnen. Die Stichprobenrate (Verzögerung) sollte nach dem Festlegen nicht mehr geändert werden müssen. Wenn Sie die Verzögerung ändern müssen, müssen Sie die Registrierung des Sensor-Listeners aufheben und dann noch einmal registrieren.
In diesem Beispiel werden die Callback-Methoden onResume()
und onPause()
verwendet, um den Sensorereignis-Listener zu registrieren und die Registrierung aufzuheben. Es hat sich bewährt, nicht benötigte Sensoren immer zu deaktivieren, insbesondere wenn die Aktivität pausiert ist. Andernfalls kann sich der Akku innerhalb weniger Stunden entladen, da einige Sensoren einen hohen Strombedarf haben und die Batterie schnell verbrauchen können. Das System deaktiviert die Sensoren nicht automatisch, wenn der Bildschirm ausgeschaltet wird.
Umgang mit verschiedenen Sensorkonfigurationen
Android spezifiziert keine standardmäßige Sensorkonfiguration für Geräte. Das bedeutet, dass Gerätehersteller eine beliebige Sensorkonfiguration in ihre Android-Geräte integrieren können. Daher können Geräte eine Vielzahl von Sensoren in einer Vielzahl 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 die App erfolgreich ausgeführt werden kann.
Sie haben zwei Möglichkeiten, um sicherzustellen, dass ein bestimmter Sensor auf einem Gerät vorhanden ist:
- Erkennt Sensoren während der Laufzeit und aktivieren oder deaktivieren Sie Anwendungsfunktionen nach Bedarf.
- Verwenden Sie Google Play-Filter, um eine Ausrichtung auf Geräte mit bestimmten Sensorkonfigurationen vorzunehmen.
Jede Option wird in den folgenden Abschnitten erläutert.
Sensoren während der Laufzeit erkennen
Wenn Ihre Anwendung einen bestimmten Sensortyp verwendet, aber nicht auf diesen angewiesen ist, können Sie das Sensor-Framework verwenden, um den Sensor zur Laufzeit zu erkennen und dann Anwendungsfunktionen nach Bedarf zu deaktivieren oder zu aktivieren. Beispielsweise kann eine Navigationsanwendung den Temperatursensor, den Drucksensor, den GPS-Sensor und den Sensor für geomagnetische Felder verwenden, um Temperatur, barometrischen Druck, Standort und Kompasspeilung anzuzeigen. Wenn ein Gerät keinen Drucksensor hat, können Sie das Sensor-Framework verwenden, um das Fehlen des Drucksensors zur Laufzeit zu erkennen und dann den Teil der Benutzeroberfläche Ihrer Anwendung zu deaktivieren, in dem der Druck angezeigt wird. Mit dem folgenden Code wird beispielsweise geprüft, ob sich ein Drucksensor am Gerät befindet:
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 von Geräten zu filtern, die nicht über die entsprechende Sensorkonfiguration für deine App verfügen. Das Element <uses-feature>
enthält mehrere Hardwaredeskriptoren, mit denen Sie Anwendungen anhand bestimmter Sensoren filtern können. Sie können folgende Sensoren auflisten: Beschleunigungsmesser, Barometer, Kompass (geomagnetisches Feld), Gyroskop, Licht und Näherung. Das folgende Beispiel zeigt einen Manifesteintrag, mit dem Apps gefiltert 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, können Nutzer deine App nur dann bei Google Play sehen, wenn ihr Gerät über einen Beschleunigungsmesser verfügt.
Sie sollten den Deskriptor nur dann auf android:required="true"
setzen, wenn Ihre Anwendung vollständig auf einem bestimmten Sensor basiert. Wenn Ihre Anwendung einen Sensor für bestimmte Funktionen verwendet, aber trotzdem ohne den Sensor ausgeführt wird, sollten Sie den Sensor im Element <uses-feature>
auflisten, aber den Deskriptor auf android:required="false"
setzen. So können Geräte deine App auch dann installieren, wenn sie diesen speziellen Sensor nicht haben. Dies ist auch eine Best Practice für das Projektmanagement, die Ihnen hilft, den Überblick über die Funktionen zu behalten, die Ihre Anwendung verwendet.
Wenn Ihre Anwendung einen bestimmten Sensor verwendet, aber trotzdem ohne den Sensor ausgeführt wird, sollten Sie den Sensor zur Laufzeit erkennen und die Anwendungsfunktionen nach Bedarf deaktivieren oder aktivieren.
Koordinatensystem mit Sensor
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 es in der 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 zur Außenseite des Bildschirms. In diesem System haben die Koordinaten hinter dem Bildschirm negative Z-Werte. Dieses Koordinatensystem wird von den folgenden Sensoren verwendet:
![](https://developer.android.google.cn/static/images/axis_device.png?authuser=6&hl=de)
Abbildung 1: Koordinatensystem (relativ zu einem Gerät), das von der Sensor API verwendet wird.
- Beschleunigungssensor
- Schwerkraftsensor
- Gyroskop
- Linearer Beschleunigungssensor
- Sensor für geomagnetisches Feld
Das Wichtigste 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 Verhalten des OpenGL-Koordinatensystems.
Außerdem sollten Sie wissen, dass Ihre Anwendung nicht davon ausgehen darf, dass die natürliche (Standard-)Ausrichtung eines Geräts das Hochformat ist. Die natürliche Ausrichtung vieler Tablets ist das Querformat. Außerdem basiert das Sensorkoordinatensystem immer auf der natürlichen Ausrichtung eines Geräts.
Wenn Ihre Anwendung schließlich Sensordaten mit dem Bildschirm auf dem Bildschirm abgleicht, müssen Sie die Methode getRotation()
verwenden, um die Bildschirmdrehung zu bestimmen, und dann die Methode remapCoordinateSystem()
verwenden, um die Sensorkoordinaten den Bildschirmkoordinaten zuzuordnen. Das ist auch dann erforderlich, wenn in deinem Manifest angegeben ist, dass die Anzeige nur im Hochformat angezeigt werden darf.
Hinweis:Einige Sensoren und Methoden verwenden ein Koordinatensystem, das relativ zum Bezugsrahmen der Welt (und nicht zum Bezugsrahmen des Geräts) ist. Diese Sensoren und Methoden geben Daten zurück, die die Gerätebewegung oder die Geräteposition relativ zur Erde darstellen. Weitere Informationen finden Sie unter der Methode getOrientation()
, der Methode getRotationMatrix()
, dem Ausrichtungssensor und dem Drehvektorsensor.
Sensorratenbegrenzung
Wenn Ihre App auf Android 12 (API-Level 31) oder höher ausgerichtet ist, legt das System zum Schutz potenziell vertraulicher Nutzerdaten ein Limit für die Aktualisierungsrate der Daten bestimmter Bewegungssensoren und Positionssensoren fest. Dazu gehören Werte, die vom Beschleunigungsmesser, dem Gyroskop und dem Geomagnetischen Feldsensor des Geräts aufgezeichnet wurden.
Die Beschränkung der Aktualisierungsrate hängt davon ab, wie Sie auf Sensordaten zugreifen:
- Wenn Sie die Methode
registerListener()
aufrufen, um Sensorereignisse zu beobachten, ist die Sensor-Abtastrate auf 200 Hz begrenzt. Dies gilt für alle überlasteten Varianten der MethoderegisterListener()
. - Wenn Sie die Klasse
SensorDirectChannel
verwenden, ist die Sensor-Abtastrate aufRATE_NORMAL
beschränkt, die normalerweise bei etwa 50 Hz liegt.
Wenn Ihre App Bewegungssensordaten mit einer höheren Frequenz erfassen muss, müssen Sie die Berechtigung HIGH_SAMPLING_RATE_SENSORS
wie im folgenden Code-Snippet gezeigt deklarieren. Andernfalls tritt ein SecurityException
auf, wenn deine App versucht, Bewegungssensordaten mit einer höheren Rate zu erheben, ohne diese Berechtigung zu erklären.
AndroidManifest.xml
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Best Practices für den Zugriff auf und die Verwendung von Sensoren
Beachten Sie beim Entwerfen der Sensorimplementierung die in diesem Abschnitt beschriebenen Richtlinien. Diese Richtlinien sind empfohlene Best Practices für alle, die das Sensor-Framework für den Zugriff auf Sensoren und den Erhalt von Sensordaten verwenden.
Sensordaten nur im Vordergrund erheben
Auf Geräten mit Android 9 (API-Level 28) oder höher gelten für Apps, die im Hintergrund ausgeführt werden, die folgenden Einschränkungen:
- Sensoren, die den kontinuierlichen Berichtsmodus verwenden, wie Beschleunigungsmesser und Gyroskope, empfangen keine Ereignisse.
- Sensoren, die die Berichtsmodi Bei Änderung oder Einzeleinstellung verwenden, empfangen keine Ereignisse.
Angesichts dieser Einschränkungen ist es am besten, Sensorereignisse zu erkennen, wenn Ihre App im Vordergrund ausgeführt wird oder wenn sie Teil eines Dienstes im Vordergrund ist.
Sensor-Listener abmelden
Achten Sie darauf, die Registrierung des Sensors aufzuheben, wenn Sie den Sensor nicht mehr benötigen oder die Sensoraktivität pausiert. Wenn ein Sensor-Listener registriert und seine Aktivität pausiert wird, erfasst der Sensor weiterhin Daten und verwendet Akkuressourcen, bis Sie die Registrierung des Sensors aufheben. Der folgende Code zeigt, wie Sie mit der Methode onPause()
die Registrierung eines Listeners aufheben:
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 findest du unter unregisterListener(SensorEventListener)
.
Mit dem Android-Emulator testen
Der Android-Emulator enthält eine Reihe virtueller Sensorsteuerelemente, mit denen Sie Sensoren wie Beschleunigungsmesser, Umgebungstemperatur, Magnetometer, Näherungssensor, Licht und mehr testen können.
Der Emulator verwendet eine Verbindung mit einem Android-Gerät, auf dem die App SdkControllerSensor ausgeführt wird. Beachten Sie, dass diese App nur auf Geräten mit Android 4.0 (API-Level 14) oder höher verfügbar ist. Wenn auf dem Gerät Android 4.0 ausgeführt wird, muss Version 2 installiert sein. Die SdkControllerSensor-App überwacht Änderungen in 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 App SdkControllerSensor finden Sie hier:
$ your-android-sdk-directory/tools/apps/SdkController
So übertragen Sie Daten zwischen Ihrem Gerät und dem Emulator:
- Prüfe, ob auf deinem Gerät USB-Debugging aktiviert ist.
- Verbinden Sie Ihr Gerät über ein USB-Kabel mit dem Entwicklungscomputer.
- 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 den folgenden
adb
-Befehl aus:- Starten Sie den Emulator. Sie sollten jetzt in der Lage sein, durch Verschieben des Geräts Transformationen auf den Emulator anzuwenden.
$ adb forward tcp:1968 tcp:1968
Hinweis: Wenn die Bewegungen, die Sie an Ihrem physischen Gerät machen, den Emulator nicht verändern, führen Sie den Befehl adb
aus Schritt 5 noch einmal aus.
Weitere Informationen finden Sie in der Android-Emulator-Anleitung.
onSensorChanged()-Methode nicht blockieren
Sensordaten können sich sehr schnell ändern. Das bedeutet, dass das System die Methode onSensorChanged(SensorEvent)
möglicherweise recht oft aufruft. Als Best Practice sollten Sie in der onSensorChanged(SensorEvent)
-Methode so wenig wie möglich unternehmen, damit Sie sie nicht blockieren. Wenn Ihre Anwendung Datenfilterung oder -reduzierung von Sensordaten erfordert, sollten Sie diese Arbeit außerhalb der Methode onSensorChanged(SensorEvent)
ausführen.
Nicht mehr unterstützte Methoden oder Sensortypen verwenden
Mehrere Methoden und Konstanten wurden eingestellt.
Insbesondere der Sensortyp TYPE_ORIENTATION
wurde eingestellt. Zum Abrufen von Ausrichtungsdaten sollten Sie stattdessen die Methode getOrientation()
verwenden. Ebenso wurde der Sensortyp TYPE_TEMPERATURE
eingestellt. Auf Geräten mit Android 4.0 sollten Sie stattdessen den Sensortyp TYPE_AMBIENT_TEMPERATURE
verwenden.
Prüfen Sie die Sensoren vor der Verwendung
Prüfen Sie immer, ob ein Sensor auf einem Gerät vorhanden ist, bevor Sie versuchen, Daten von ihm zu erfassen. Gehen Sie nicht davon aus, dass ein Sensor nur existiert, weil er ein häufig verwendeter Sensor ist. Gerätehersteller müssen keine bestimmten Sensoren in ihren Geräten bereitstellen.
Sensorverzögerungen sorgfältig auswählen
Wenn Sie einen Sensor mit der Methode registerListener()
registrieren, müssen Sie eine Übermittlungsrate auswählen, die für Ihre Anwendung oder Ihren Anwendungsfall geeignet ist. Sensoren können Daten mit sehr hohen Frequenzen liefern. Wenn Sie dem System erlauben, zusätzliche Daten zu senden, die nicht benötigt werden, werden Systemressourcen verschwendet und es wird Akkuleistung verbraucht.