Sensoren – Übersicht

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 Position von Geräten überwachen oder Änderungen in der Umgebung in der Nähe eines Geräts beobachten möchten. Zum Beispiel könnte ein Spiel die Messwerte des Schwerkraftsensors eines Geräts aufzeichnen, um komplexe Nutzergesten und -bewegungen wie Neigen, Schütteln, Drehen oder Schaukeln abzuleiten. Ebenso kann eine Wetteranwendung den Temperatur- und Feuchtigkeitssensor eines Geräts verwenden, um den Taupunkt zu berechnen und zu melden, oder eine Reiseanwendung könnte den Sensor und den Beschleunigungsmesser für das geomagnetische Feld verwenden, um die Kompassposition zu melden.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Die Android-Plattform unterstützt drei große Kategorien von Sensoren:

  • Bewegungssensoren

    Diese Sensoren messen Beschleunigungs- und Rotationskräfte entlang drei Achsen. Diese Kategorie umfasst Beschleunigungsmesser, Schwerkraftsensoren, Gyroskope und Rotationsvektorsensoren.

  • Umgebungssensoren

    Diese Sensoren messen verschiedene Umgebungsparameter wie Umgebungstemperatur und -druck, Helligkeit und Luftfeuchtigkeit. Zu dieser Kategorie gehören 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 Sensorrohdaten abrufen. Das Sensor-Framework bietet mehrere Klassen und Schnittstellen, mit denen Sie eine Vielzahl von sensorischen Aufgaben ausführen können. Mit dem Sensor-Framework können Sie beispielsweise Folgendes tun:

  • Finde heraus, welche Sensoren auf einem Gerät verfügbar sind.
  • Bestimmen Sie die Funktionen eines einzelnen Sensors, z. B. maximale Reichweite, Hersteller, Energieanforderungen und Auflösung.
  • Erfassen Sie Sensorrohdaten und legen Sie die Mindestrate fest, mit der Sensordaten erfasst werden.
  • Sensorereignis-Listener, die Sensoränderungen überwachen, registrieren und ihre Registrierung aufheben

Hier erhalten Sie einen Überblick über die Sensoren, die auf der Android-Plattform verfügbar sind. Außerdem erhalten Sie eine Einführung in das Sensor-Framework.

Einführung in Sensoren

Das Sensor-Framework von Android ermöglicht den Zugriff auf viele Arten von Sensoren. 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 Winkelveränderungen direkt messen. Softwarebasierte Sensoren sind keine physischen Geräte, obwohl sie hardwarebasierte Sensoren imitieren. Softwarebasierte Sensoren leiten ihre Daten von einem oder mehreren der 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 von der Android-Plattform unterstützten Sensoren zusammengefasst.

Nur wenige Android-Geräte sind mit allen Sensortypen ausgestattet. Die meisten Mobiltelefon- und Tablet-Geräte haben beispielsweise einen Beschleunigungsmesser und ein Magnetometer, aber weniger Geräte haben Barometer oder Thermometer. Außerdem kann ein Gerät mehrere Sensoren 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 Sensorentypen.

Sensor Typ Beschreibung Übliche Anwendungsbereiche
TYPE_ACCELEROMETER Hardware Misst die Beschleunigungskraft in m/s2, die auf ein Gerät auf allen drei physischen Achsen (x, y und z) angewendet wird, einschließlich der Schwerkraft. Bewegungserkennung (Schütteln, Neigen usw.)
TYPE_AMBIENT_TEMPERATURE Hardware Misst die Raumtemperatur in Grad Celsius (°C). Siehe Hinweis unten. Überwachung der Lufttemperaturen.
TYPE_GRAVITY Software oder Hardware Misst die Kraft der 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 Rotationsrate eines Geräts in Rad/s um jede der drei physischen Achsen (x, y und z). Rotationserkennung (Drehung, Drehen usw.).
TYPE_LIGHT Hardware Misst die Intensität des Umgebungslichts in lx. Die Bildschirmhelligkeit wird gesteuert.
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, abzüglich der Schwerkraft. Überwachung der Beschleunigung entlang einer einzelnen Achse.
TYPE_MAGNETIC_FIELD Hardware Misst das geomagnetische Umgebungsfeld für alle drei physischen Achsen (x, y, z) in μT. Kompass wird erstellt.
TYPE_ORIENTATION Software Misst die Drehung eines Geräts um alle drei physischen Achsen (x, y, z). Ab API-Level 3 können Sie die Neigungsmatrix und die Rotationsmatrix für ein Gerät abrufen, indem Sie den Schwerkraftsensor und den Sensor für das geomagnetische Feld in Verbindung mit der Methode getRotationMatrix() verwenden. Geräteposition wird ermittelt.
TYPE_PRESSURE Hardware Misst den Luftdruck in hPa oder mbar. Überwachung von Luftdruckänderungen.
TYPE_PROXIMITY Hardware Misst die Entfernung eines Objekts in cm zum sichtbaren Bildschirm eines Geräts. Mit diesem Sensor wird normalerweise ermittelt, ob ein Mobilgerät an das Ohr einer Person gehalten wird. Smartphone-Position während eines Anrufs.
TYPE_RELATIVE_HUMIDITY Hardware Misst die relative Luftfeuchtigkeit in der Umgebung 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 Gerätedrehungsvektors bereitgestellt 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. Temperaturüberwachung.

Sensor Framework

Mit dem Sensor-Framework von Android können Sie auf diese Sensoren zugreifen und Sensorrohdaten abrufen. Das Sensor-Framework ist Teil des android.hardware-Pakets und umfasst die folgenden Klassen und Schnittstellen:

SensorManager
Sie können diese Klasse verwenden, um eine Instanz des Sensordienstes zu erstellen. Diese Klasse bietet verschiedene Methoden, um auf Sensoren zuzugreifen und diese aufzulisten, Sensorereignis-Listener zu registrieren bzw. abzumelden und Ausrichtungsinformationen abzurufen. Diese Klasse bietet auch mehrere Sensorkonstanten, die verwendet werden, um die Sensorgenauigkeit zu melden, Datenerfassungsraten festzulegen und Sensoren zu kalibrieren.
Sensor
Sie können diese Klasse verwenden, um eine Instanz eines bestimmten Sensors zu erstellen. Diese Klasse bietet verschiedene Methoden, mit denen Sie die Funktionen eines Sensors bestimmen können.
SensorEvent
Das System verwendet diese Klasse, um ein Sensorereignisobjekt zu erstellen, das Informationen zu einem Sensorereignis liefert. 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
Mit dieser Schnittstelle lassen sich 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 erkennen

    Die Identifizierung von Sensoren und Sensorfunktionen während der Laufzeit ist nützlich, wenn Ihre Anwendung Funktionen enthält, die von bestimmten Sensortypen oder -funktionen abhängig sind. Sie können beispielsweise alle Sensoren eines Geräts identifizieren und alle App-Funktionen deaktivieren, die auf nicht vorhandenen Sensoren basieren. Ebenso können Sie alle Sensoren eines bestimmten Typs ermitteln, um die Sensorimplementierung auszuwählen, die für Ihre Anwendung die optimale Leistung bietet.

  • Sensorereignisse beobachten

    Durch das Überwachen von Sensorereignissen erhalten Sie Sensorrohdaten. Ein Sensorereignis tritt immer dann auf, wenn ein Sensor eine Änderung der zu messenden Parameter erkennt. Ein Sensorereignis liefert Ihnen vier Informationen: den Namen des Sensors, der das Ereignis ausgelöst hat, den Zeitstempel des Ereignisses, die Genauigkeit des Ereignisses und die Sensor-Rohdaten, die das Ereignis ausgelöst haben.

Sensorverfügbarkeit

Die Sensorverfügbarkeit variiert zwar von Gerät zu Gerät, kann aber auch je nach Android-Version variieren. Das liegt daran, dass die Android-Sensoren im Laufe mehrerer Plattform-Releases eingeführt wurden. In Android 1.5 (API-Level 3) wurden beispielsweise viele Sensoren eingeführt. Einige davon wurden jedoch erst dann implementiert und standen erst ab Android 2.3 (API-Level 9) zur Verfügung. Gleichzeitig 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 für die einzelnen Plattformen zusammengefasst. Es sind nur vier Plattformen aufgeführt, da dies die Plattformen sind, an denen Sensoränderungen beteiligt waren. Sensoren, die als verworfen aufgeführt sind, sind auf nachfolgenden Plattformen weiterhin verfügbar (sofern der Sensor auf einem Gerät vorhanden ist). Dies entspricht der Android-Richtlinie zur Aufwärtskompatibilität.

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, konnte aber erst ab Android 2.3 (API-Level 9) verwendet werden.

2 Dieser Sensor ist verfügbar, wurde aber eingestellt.

Sensoren und Sensorfunktionen

Das Sensor-Framework von Android bietet mehrere Methoden, mit denen Sie zur Laufzeit einfach feststellen können, welche Sensoren sich auf einem Gerät befinden. Die API bietet auch Methoden, mit denen Sie die Funktionen jedes Sensors bestimmen können, z. B. die maximale Reichweite, die Auflösung und den Strombedarf.

Um die Sensoren eines Geräts zu identifizieren, müssen Sie zuerst einen Verweis auf den Sensordienst abrufen. Dazu erstellen Sie eine Instanz der SensorManager-Klasse. Dazu rufen Sie die Methode getSystemService() auf und übergeben das Argument SENSOR_SERVICE. Beispiele:

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. Beispiele:

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.

Sie können auch feststellen, ob ein bestimmter Sensortyp auf einem Gerät vorhanden ist. Dazu verwenden Sie die Methode getDefaultSensor() und übergeben die Typkonstante für einen bestimmten Sensor. 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 sich ein Magnetometer auf 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:Gerätehersteller müssen keine bestimmten Arten von Sensoren in Android-Geräte von Android-Geräten einbauen. Geräte können also eine Vielzahl von Sensorenkonfigurationen haben.

Neben einer Liste der Sensoren eines Geräts können Sie auch die öffentlichen Methoden der Klasse Sensor verwenden, um die Funktionen und Attribute einzelner Sensoren zu bestimmen. Das ist nützlich, wenn sich Ihre Anwendung je nach den auf einem Gerät verfügbaren Sensoren oder Sensorfunktionen 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 den Energiebedarf eines Sensors auch mit der Methode getPower() abrufen.

Zwei der öffentlichen Methoden sind besonders nützlich, wenn Sie Ihre Anwendung für Sensoren verschiedener Hersteller oder für verschiedene Sensorversionen 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 mit einem Schwerkraftsensor eines bestimmten Anbieters und einen weiteren Satz von Datenfilterregeln und -optimierungen für Geräte erstellen, die keinen Schwerkraftsensor und nur einen Beschleunigungsmesser haben. Das folgende Codebeispiel zeigt, wie Sie die Methoden getVendor() und getVersion() verwenden können. In diesem Beispiel suchen wir nach einem Schwerkraftsensor mit der Versionsnummer 3, bei dem Google LLC als Anbieter aufgeführt ist. Wenn dieser spezielle Sensor nicht am Gerät vorhanden ist, versuchen wir, 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, mit der das minimale Zeitintervall (in Mikrosekunden) zurückgegeben wird, 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. Streamingsensoren erfassen Daten in regelmäßigen Intervallen und wurden mit Android 2.3 (API-Level 9) eingeführt. Wenn ein Sensor beim Aufrufen der getMinDelay()-Methode null zurückgibt, ist er kein Streamingsensor, da er Daten nur dann meldet, wenn sich die zu erfassenden 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 Datenakquisitionsraten oder einen Streamingsensor erfordern, können Sie mit dieser Methode feststellen, ob ein Sensor diese Anforderungen erfüllt, und die entsprechenden Funktionen in Ihrer Anwendung entsprechend aktivieren oder deaktivieren.

Achtung:Die maximale Datenerfassungsrate eines Sensors ist nicht unbedingt die Geschwindigkeit, mit der das Sensor-Framework Sensordaten an Ihre Anwendung sendet. Das Sensor-Framework meldet Daten über Sensorereignisse, und mehrere Faktoren beeinflussen die Geschwindigkeit, mit der Ihre Anwendung Sensorereignisse empfängt. Weitere Informationen finden Sie unter Sensorereignisse überwachen.

Überwachung von Sensorereignissen

Wenn Sie Sensorrohdaten überwachen möchten, müssen Sie zwei Callback-Methoden implementieren, die über die SensorEventListener-Schnittstelle verfügbar gemacht werden: onAccuracyChanged() und onSensorChanged(). Das Android-System ruft diese Methoden in folgenden Fällen auf:

Der folgende Code zeigt, wie Sie mit der Methode onSensorChanged() Daten des Lichtsensors überwachen können. In diesem Beispiel werden die Sensor-Rohdaten in einer TextView angezeigt, die in der Main.xml-Datei 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 standardmäßige Datenverzö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 standardmäßige Datenverzögerung ermöglicht die Überwachung typischer Änderungen der Bildschirmausrichtung. Sie verwendet eine Verzögerung von 200.000 Mikrosekunden. Sie können auch andere Datenverzögerungen angeben, z. B. SENSOR_DELAY_GAME (Verzögerung von 20.000 Mikrosekunden), SENSOR_DELAY_UI (60.000 Mikrosekunden Verzögerung) oder SENSOR_DELAY_FASTEST (Verzögerung von 0 Mikrosekunden). 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 vorgeschlagene Verspätung. Das Android-System und andere Apps können diese Verzögerung verändern. Es hat sich bewährt, die größtmögliche Verzögerung anzugeben, da das System normalerweise eine kleinere Verzögerung verwendet als die von Ihnen angegebene. Wählen Sie also die langsamste Abtastrate, die den Anforderungen Ihrer Anwendung noch entspricht. Eine größere Verzögerung führt zu einer geringeren Belastung des Prozessors und verbraucht daher weniger Energie.

Es gibt keine öffentliche Methode zum Bestimmen der Rate, mit der das Sensor-Framework Sensorereignisse an Ihre Anwendung sendet. Sie können 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 Sie die Verzögerung ändern müssen, müssen Sie die Registrierung des Sensor-Listeners aufheben und ihn neu registrieren.

Wichtig: In diesem Beispiel werden die Callback-Methoden onResume() und onPause() verwendet, um den Sensorereignis-Listener zu registrieren und seine Registrierung aufzuheben. Es hat sich bewährt, nicht benötigte Sensoren immer zu deaktivieren, insbesondere wenn deine Aktivität pausiert ist. Andernfalls kann sich der Akku in nur wenigen Stunden entladen, da einige Sensoren einen hohen Strombedarf haben und den Akku schnell verbrauchen. Das System deaktiviert die Sensoren nicht automatisch, wenn sich der Bildschirm ausschaltet.

Umgang mit verschiedenen Sensorkonfigurationen

Android spezifiziert keine Standardsensorkonfiguration für Geräte. Das bedeutet, dass Gerätehersteller jede gewünschte Sensorkonfiguration in ihre Android-Geräte einbinden können. Daher können Geräte eine Vielzahl von Sensoren in einer Vielzahl von Konfigurationen enthalten. Wenn Ihre Anwendung auf einem bestimmten Sensortyp basiert, muss der Sensor auf einem Gerät vorhanden sein, damit Ihre App erfolgreich ausgeführt werden kann.

Sie haben zwei Möglichkeiten, um sicherzustellen, dass ein bestimmter Sensor auf einem Gerät vorhanden ist:

  • Erkennen Sie Sensoren während der Laufzeit und aktivieren oder deaktivieren Sie App-Funktionen nach Bedarf.
  • Nutzen Sie Google Play-Filter, um eine Ausrichtung auf Geräte mit bestimmten Sensorkonfigurationen vorzunehmen.

Die einzelnen Optionen werden in den folgenden Abschnitten erläutert.

Sensoren während der Laufzeit erkennen

Wenn Ihre Anwendung einen bestimmten Sensortyp verwendet, sich aber nicht darauf verlässt, können Sie das Sensor-Framework verwenden, um den Sensor während der Laufzeit zu erkennen. Anschließend können Sie die Anwendungsfeatures nach Bedarf deaktivieren oder aktivieren. Eine Navigationsanwendung kann beispielsweise den Temperatursensor, den Drucksensor, den GPS-Sensor und den Sensor für das geomagnetische Feld verwenden, um Temperatur, barometrischen Druck, Standort und Kompasspeilung anzuzeigen. Wenn ein Gerät keinen Drucksensor hat, können Sie mithilfe des Sensor-Frameworks feststellen, dass der Drucksensor während der Laufzeit fehlt, und dann den Teil der Benutzeroberfläche Ihrer Anwendung deaktivieren, in dem der Druck angezeigt wird. Mit dem folgenden Code wird beispielsweise geprüft, ob ein Drucksensor an einem Gerät vorhanden ist:

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 nach Geräten zu filtern, die nicht über die entsprechende Sensorkonfiguration für deine App verfügen. Das <uses-feature>-Element hat mehrere Hardwaredeskriptoren, mit denen Sie Anwendungen anhand bestimmter Sensoren filtern können. Folgende Sensoren können aufgelistet werden: Beschleunigungsmesser, Barometer, Kompass (geomagnetisches Feld), Gyroskop, Licht und Näherung. Im Folgenden finden Sie ein Beispiel für einen Manifesteintrag, mit dem Apps ohne Beschleunigungsmesser gefiltert werden:

<uses-feature android:name="android.hardware.sensor.accelerometer"
              android:required="true" />

Wenn du dieses Element und diesen Deskriptor zum Manifest deiner App hinzufügst, sehen Nutzer deine App nur dann bei Google Play, wenn ihr Gerät über einen Beschleunigungsmesser verfügt.

Sie sollten den Deskriptor nur dann auf android:required="true" festlegen, wenn Ihre Anwendung vollständig von einem bestimmten Sensor abhängt. Wenn Ihre Anwendung für bestimmte Funktionen einen Sensor verwendet, aber trotzdem ohne Sensor ausgeführt wird, sollten Sie den Sensor im Element <uses-feature> auflisten, aber den Deskriptor auf android:required="false" festlegen. 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, mit der Sie den Überblick über die von Ihrer Anwendung verwendeten Funktionen behalten können. Wenn Ihre Anwendung einen bestimmten Sensor verwendet, aber trotzdem ohne den Sensor läuft, sollten Sie den Sensor zur Laufzeit erkennen und die Anwendungsfunktionen nach Bedarf 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 zur Außenseite des Bildschirms. In diesem System haben die Koordinaten hinter dem Bildschirm negative Z-Werte. Dieses Koordinatensystem wird von folgenden Sensoren verwendet:

Abbildung 1: Koordinatensystem (relativ zu einem Gerät), das von der Sensor API verwendet wird.

Der wichtigste Punkt bei diesem Koordinatensystem ist, dass die Achsen nicht vertauscht werden, wenn sich die Bildschirmausrichtung des Geräts ändert, d. h., das Koordinatensystem des Sensors ändert sich nie, wenn sich das Gerät bewegt. Dieses Verhalten entspricht dem Verhalten des OpenGL-Koordinatensystems.

Außerdem darf Ihre Anwendung nicht davon ausgehen, dass die natürliche (Standardausrichtung) eines Geräts das Hochformat ist. Bei vielen Tablet-Geräten ist das Querformat die natürliche Ausrichtung. Und das Sensorkoordinatensystem basiert immer auf der natürlichen Ausrichtung eines Geräts.

Wenn Ihre Anwendung die Sensordaten mit dem Bildschirm auf dem Bildschirm abgleicht, müssen Sie die Methode getRotation() zur Bestimmung der Bildschirmdrehung verwenden und dann die Methode remapCoordinateSystem() verwenden, um die Sensorkoordinaten den Bildschirmkoordinaten zuzuordnen. Dies ist auch dann erforderlich, wenn in Ihrem Manifest die ausschließliche Anzeige im Hochformat angegeben ist.

Hinweis:Einige Sensoren und Methoden verwenden ein Koordinatensystem, das relativ zum Bezugsrahmen der Welt (im Gegensatz 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 den Methoden getOrientation(), getRotationMatrix(), Ausrichtungssensor und Rotationsvektorsensor.

Begrenzung der Sensorfrequenz

Wenn deine App auf Android 12 (API-Level 31) oder höher ausgerichtet ist, wird die Aktualisierungsrate der Daten bestimmter Bewegungs- und Positionssensoren vom System begrenzt, um potenziell vertrauliche Daten zu schützen. Diese Daten umfassen Werte, die vom Beschleunigungsmesser, Gyroskop und dem Geomagnetischen Feldsensor des Geräts aufgezeichnet wurden.

Das Limit für die Aktualisierungsrate hängt davon ab, wie Sie auf Sensordaten zugreifen:

Wenn Ihre App Bewegungssensordaten mit einer höheren Geschwindigkeit erfassen muss, müssen Sie die Berechtigung HIGH_SAMPLING_RATE_SENSORS deklarieren, wie im folgenden Code-Snippet gezeigt. Wenn Ihre App versucht, Bewegungssensordaten mit einer höheren Geschwindigkeit zu erfassen, ohne diese Berechtigung zu erklären, wird ein SecurityException ausgelöst.

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

Wenn du die Sensorimplementierung konzipierst, solltest du die in diesem Abschnitt beschriebenen Richtlinien beachten. Diese Richtlinien sind empfohlene Best Practices für alle, die das Sensor-Framework für den Zugriff auf Sensoren und den Abruf von Sensordaten verwenden.

Sensordaten nur im Vordergrund erheben

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 Meldemodus verwenden, z. B. Beschleunigungsmesser und Gyroskope, empfangen keine Ereignisse.
  • Sensoren, die die Berichtsmodi Bei Änderung oder One-Shot verwenden, empfangen keine Ereignisse.

Aufgrund dieser Einschränkungen sollten Sensorereignisse am besten erkannt werden, wenn sich die App im Vordergrund oder als Teil eines Diensts im Vordergrund befindet.

Registrierung von Sensor-Listenern aufheben

Heben Sie die Registrierung des Listeners eines Sensors auf, wenn Sie den Sensor nicht mehr verwenden oder die Sensoraktivität angehalten wird. Wenn ein Sensor-Listener registriert und seine Aktivität pausiert ist, erfasst der Sensor weiterhin Daten und verbraucht Akkuressourcen, es sei denn, Sie heben die Registrierung des Sensors auf. 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 umfasst 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. 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 des Geräts und überträgt sie an den Emulator. Der Emulator wird dann anhand der neuen Werte transformiert, die er von den Sensoren auf Ihrem Gerät empfängt.

Sie können den Quellcode für die SdkControllerSensor-App hier ansehen:

$ your-android-sdk-directory/tools/apps/SdkController

So übertragen Sie Daten zwischen Ihrem Gerät und dem Emulator:

  1. Prüfe, ob auf deinem Gerät USB-Debugging aktiviert ist.
  2. Verbinden Sie Ihr Gerät über ein USB-Kabel mit dem Entwicklungscomputer.
  3. Starten Sie die SdkControllerSensor App auf Ihrem Gerät.
  4. Wählen Sie in der App die Sensoren aus, die Sie emulieren möchten.
  5. Führen Sie den folgenden adb-Befehl aus:

  6. $ adb forward tcp:1968 tcp:1968
    
  7. Starten Sie den Emulator. Sie sollten jetzt Transformationen auf den Emulator anwenden können, indem Sie das Gerät verschieben.

Hinweis : Wenn die Bewegungen, die Sie an Ihrem physischen Gerät vornehmen, den Emulator nicht verändern, führen Sie den Befehl adb aus Schritt 5 noch einmal aus.

Weitere Informationen finden Sie in der Anleitung zum Android-Emulator.

onSensorChanged()-Methode nicht blockieren

Sensordaten können sich mit hoher Geschwindigkeit ändern. Daher ruft das System die Methode onSensorChanged(SensorEvent) möglicherweise recht häufig auf. Als Best Practice sollten Sie innerhalb der Methode onSensorChanged(SensorEvent) so wenig wie möglich tun, damit Sie sie nicht blockieren. Wenn Sie in Ihrer Anwendung Datenfilter oder -reduzierungen von Sensordaten vornehmen müssen, sollten Sie diese Arbeit außerhalb der onSensorChanged(SensorEvent)-Methode ausführen.

Nicht mehr unterstützte Methoden oder Sensortypen verwenden

Einige Methoden und Konstanten wurden eingestellt. Insbesondere der Sensortyp TYPE_ORIENTATION wurde verworfen. Um Ausrichtungsdaten abzurufen, sollten Sie stattdessen die Methode getOrientation() verwenden. Der Sensortyp TYPE_TEMPERATURE wurde ebenfalls eingestellt. Auf Geräten mit Android 4.0 solltest du stattdessen den Sensortyp TYPE_AMBIENT_TEMPERATURE verwenden.

Sensoren vor der Verwendung überprüfen

Überprüfe immer, ob ein Sensor an einem Gerät vorhanden ist, bevor du versuchst, Daten von ihm zu erfassen. Gehen Sie nicht davon aus, dass ein Sensor existiert, nur weil es ein häufig verwendeter Sensor ist. Gerätehersteller sind nicht verpflichtet, in ihren Geräten bestimmte Sensoren bereitzustellen.

Sensorverzögerungen sorgfältig auswählen

Wenn Sie einen Sensor mit der Methode registerListener() registrieren, müssen Sie eine Auslieferungsgeschwindigkeit auswählen, die für Ihre Anwendung oder Ihren Anwendungsfall geeignet ist. Sensoren können Daten mit einer sehr hohen Geschwindigkeit liefern. Wenn Sie dem System erlauben, zusätzliche Daten zu senden, die Sie nicht benötigen, werden Systemressourcen verbraucht und Akku verbraucht.