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 Gerätebewegung oder -positionierung oder Änderungen in der Umgebung eines Geräts überwachen möchten. In einem Spiel können beispielsweise Messwerte des Schwerkraftsensors eines Geräts erfasst werden, um komplexe Nutzergesten und -bewegungen wie Neigen, Schütteln, Drehen oder Schwingen zu ermitteln. Ebenso kann eine Wetter-App den Temperatur- und den Feuchtigkeitssensor eines Geräts verwenden, um den Taupunkt zu berechnen und anzugeben. Eine Reise-App kann den Geomagnetfeldsensor und den Beschleunigungsmesser verwenden, um eine Kompasspeilung anzugeben.

Die Android-Plattform unterstützt drei große Sensorkategorien:

  • Bewegungssensoren

    Diese Sensoren messen Beschleunigungs- und Drehkräfte entlang von drei Achsen. Diese Kategorie umfasst Beschleunigungsmesser, Schwerkraftsensoren, Gyroskope und Drehvektorsensoren.

  • Umgebungssensoren

    Diese Sensoren messen verschiedene Umgebungsparameter wie die Temperatur und den Druck der Umgebungsluft, die Beleuchtung und die 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 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:

  • Sie können prüfen, welche Sensoren auf einem Gerät verfügbar sind.
  • Sie können die Funktionen eines einzelnen Sensors ermitteln, z. B. seinen maximalen Bereich, den Hersteller, die Leistungsanforderungen und die Auflösung.
  • Erfassen Sie Rohsensordaten und definieren Sie die Mindestrate, mit der Sie Sensordaten erfassen.
  • Registrieren und unregisteren Sie Sensorereignis-Listener, die Sensoränderungen überwachen.

In diesem Thema 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

Über das 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. Die Daten werden durch direkte Messung bestimmter Umwelteigenschaften wie Beschleunigung, Stärke des geomagnetischen Feldes oder Winkeländerung gewonnen. Softwarebasierte Sensoren sind keine physischen Geräte, obwohl sie hardwarebasierte Sensoren nachahmen. 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 haben alle Arten von Sensoren. So haben beispielsweise die meisten Smartphones und Tablets 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 Gravitationssensoren mit unterschiedlicher Reichweite haben.

Tabelle 1 Von der Android-Plattform unterstützte Sensortypen.

Sensor Eingeben 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) ausgeübt wird, einschließlich der Schwerkraft. Bewegungserkennung (Schütteln, Neigen usw.)
TYPE_AMBIENT_TEMPERATURE Hardware Misst die Raumtemperatur in Grad Celsius (°C). Weitere Informationen finden Sie im 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) ausgeübt 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). Drehung erkennen (Drehen, Wenden usw.)
TYPE_LIGHT Hardware Misst die Beleuchtungsstärke 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, ohne die Schwerkraft. Beschleunigung entlang einer einzelnen Achse überwachen
TYPE_MAGNETIC_FIELD Hardware Misst das Umgebungsmagnetfeld für alle drei physischen Achsen (x, y, z) in μT. Einen Kompass erstellen
TYPE_ORIENTATION Software Misst die Drehung eines Geräts um alle drei physischen Achsen (x, y, z) in Grad. Ab API-Ebene 3 können Sie die Neigungsmatrix und die Drehungsmatrix für ein Gerät mithilfe des Gravitationssensors und des Geomagnetfeldsensors in Verbindung mit der Methode getRotationMatrix() abrufen. Geräteposition ermitteln
TYPE_PRESSURE Hardware Misst den Umgebungsluftdruck in hPa oder mbar. Überwachung von Luftdruckänderungen
TYPE_PROXIMITY Hardware Misst die Nähe eines Objekts in Zentimetern relativ zum Display eines Geräts. Dieser Sensor wird in der Regel verwendet, um zu ermitteln, ob ein Mobiltelefon an das Ohr einer Person gehalten wird. Position des Smartphones während eines Anrufs
TYPE_RELATIVE_HUMIDITY Hardware Misst die relative Luftfeuchtigkeit in Prozent (%). Taupunkt, absolute und relative Luftfeuchtigkeit überwachen
TYPE_ROTATION_VECTOR Software oder Hardware Misst die Ausrichtung eines Geräts, indem die drei Elemente des Drehvektors des Geräts angegeben werden. Bewegungs- und Dreherkennung
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 TYPE_AMBIENT_TEMPERATURE-Sensor ersetzt. Temperaturüberwachung

Sensor Framework

Sie können über das Android-Sensor-Framework auf diese Sensoren zugreifen und Rohdaten 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 zum Zugriff auf und zum Auflisten von Sensoren, zum Registrieren und Entfernen von Sensorereignis-Listenern und zum Abrufen von Orientierungsinformationen. Diese Klasse bietet auch mehrere Sensorkonstanten, mit denen die Sensorgenauigkeit erfasst, die Datenerfassungsraten festgelegt und Sensoren kalibriert werden.
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 enthält. Ein Sensorereignisobjekt enthält die folgenden Informationen: die Rohsensordaten, den Sensortyp, der das Ereignis generiert hat, die Genauigkeit der Daten und den Zeitstempel für das Ereignis.
SensorEventListener
Mit dieser Schnittstelle können Sie zwei Rückrufmethoden erstellen, die Benachrichtigungen (Sensorereignisse) erhalten, wenn sich die Sensorwerte oder die Sensorgenauigkeit ändern.

In einer typischen Anwendung werden diese sensorbezogenen APIs für zwei grundlegende Aufgaben verwendet:

  • Sensoren und Sensorfunktionen identifizieren

    Die Identifizierung von Sensoren und Sensorfunktionen zur Laufzeit ist nützlich, wenn Ihre Anwendung Funktionen hat, die auf bestimmten Sensortypen oder -funktionen basieren. So können Sie beispielsweise alle Sensoren auf einem Gerät identifizieren und alle Anwendungsfunktionen deaktivieren, die auf nicht vorhandenen Sensoren basieren. Ebenso können Sie alle Sensoren eines bestimmten Typs identifizieren, um die Sensorimplementierung mit der optimalen Leistung für Ihre Anwendung auszuwählen.

  • Sensorereignisse überwachen

    Durch das Überwachen von Sensorereignissen können Sie Rohsensordaten erfassen. Ein Sensorereignis tritt jedes Mal auf, wenn ein Sensor eine Änderung bei den gemessenen Parametern erkennt. Ein Sensorereignis enthält vier Informationen: den Namen des Sensors, der das Ereignis ausgelöst hat, den Zeitstempel für das Ereignis, die Genauigkeit des Ereignisses und die Rohdaten des Sensors, die das Ereignis ausgelöst haben.

Verfügbarkeit des Sensors

Die Verfügbarkeit des Sensors kann von Gerät zu Gerät und von Android-Version zu Android-Version variieren. Das liegt daran, dass die Android-Sensoren im Laufe mehrerer Plattformversionen eingeführt wurden. So 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 waren erst dann verfügbar. 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 für jede Plattform zusammengefasst. Es sind nur vier Plattformen aufgeführt, da es sich dabei um die Plattformen handelt, bei denen Sensoränderungen vorgenommen wurden. Sensoren, die als eingestellt aufgeführt sind, sind auf nachfolgenden Plattformen weiterhin verfügbar, sofern der Sensor auf einem Gerät vorhanden ist. Dies entspricht der Richtlinie zur Abwä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 1 1
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 1 1
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, wird aber nicht mehr unterstützt.

Sensoren und Sensorfunktionen identifizieren

Das Android-Sensor-Framework bietet mehrere Methoden, mit denen Sie zur Laufzeit ganz einfach ermitteln können, welche Sensoren sich auf einem Gerät befinden. Die API bietet auch Methoden, mit denen Sie die Funktionen der einzelnen Sensoren ermitteln können, z. B. ihren maximalen Bereich, ihre Auflösung und ihre Leistungsanforderungen.

Um die Sensoren auf einem Gerät zu identifizieren, müssen Sie zuerst eine Referenz zum 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 können Sie eine Liste aller Sensoren auf einem Gerät abrufen, indem Sie die Methode getSensorList() mit der Konstante TYPE_ALL aufrufen. 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.

Sie können auch feststellen, ob ein bestimmter Sensortyp auf einem Gerät vorhanden ist, indem Sie die Methode getDefaultSensor() verwenden und die Typkonstante für einen bestimmten Sensor übergeben. 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 keinen Sensor dieses Typs hat. Mit dem folgenden Code wird beispielsweise geprüft, ob sich auf einem Gerät ein Magnetometer 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:Android-Gerätehersteller sind nicht verpflichtet, bestimmte Sensortypen in ihre Android-Geräte einzubauen. Daher können Geräte eine Vielzahl von Sensorkonfigurationen haben.

Sie können nicht nur die Sensoren auf einem Gerät auflisten, sondern auch mithilfe der öffentlichen Methoden der Klasse Sensor die Funktionen und Attribute einzelner Sensoren ermitteln. Das ist nützlich, wenn sich Ihre Anwendung je nach Sensoren oder Sensorfunktionen auf einem Gerät unterschiedlich verhalten soll. Mit den Methoden getResolution() und getMaximumRange() können Sie beispielsweise die Auflösung und den maximalen Messbereich eines Sensors ermitteln. Sie können auch die Methode getPower() verwenden, um die Leistungsanforderungen eines Sensors abzurufen.

Zwei der öffentlichen Methoden sind besonders nützlich, wenn Sie Ihre Anwendung für Sensoren verschiedener Hersteller oder verschiedener Versionen eines Sensors optimieren möchten. Wenn Ihre Anwendung beispielsweise Nutzergesten wie Neigen und Schütteln überwachen muss, können Sie eine Reihe von Datenfilterregeln und -optimierungen für neuere Geräte mit dem Gravitationssensor eines bestimmten Anbieters und eine weitere Reihe von Datenfilterregeln und -optimierungen für Geräte erstellen, die keinen Gravitationssensor, sondern nur einen Beschleunigungsmesser haben. Das folgende Codebeispiel zeigt, wie Sie dazu die Methoden getVendor() und getVersion() verwenden können. In diesem Beispiel suchen wir nach einem Gravitationssensor, bei dem Google LLC als Anbieter angegeben ist und der die Versionsnummer 3 hat. Wenn dieser Sensor nicht auf dem Gerät vorhanden ist, versuchen wir, das Gyroskop 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 0 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 bei Aufruf der getMinDelay()-Methode den Wert 0 zurückgibt, ist er kein Streaming-Sensor, 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 die entsprechenden Funktionen in Ihrer Anwendung entsprechend aktivieren oder deaktivieren.

Achtung:Die maximale Datenakquisitionsrate eines Sensors entspricht nicht unbedingt der Rate, mit der das Sensor-Framework Sensordaten an Ihre Anwendung liefert. Das Sensor-Framework meldet Daten über Sensorereignisse. Die Häufigkeit, mit der Ihre Anwendung Sensorereignisse empfängt, hängt von mehreren Faktoren ab. Weitere Informationen finden Sie unter Sensorereignisse überwachen.

Sensorereignisse überwachen

Wenn Sie Rohsensordaten überwachen möchten, müssen Sie zwei Rückrufmethoden implementieren, die über die SensorEventListener-Schnittstelle verfügbar sind: onAccuracyChanged() und onSensorChanged(). Das Android-System ruft diese Methoden auf, wenn Folgendes eintritt:

Im folgenden Code wird gezeigt, wie Sie mit der Methode onSensorChanged() Daten vom Lichtsensor überwachen. In diesem Beispiel werden die Rohsensordaten 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. Mit der Datenverzögerung (oder Abtastrate) wird das Intervall festgelegt, in dem Sensorereignisse über die onSensorChanged()-Callback-Methode an Ihre Anwendung gesendet werden. Die Standarddatenverzögerung eignet sich für das Überwachen typischer Änderungen der Bildschirmausrichtung und verwendet eine Verzögerung von 200.000 Mikrosekunden. Sie können auch andere Datenverzögerungen angeben, z. B. SENSOR_DELAY_GAME (20.000 Mikrosekunden), SENSOR_DELAY_UI (60.000 Mikrosekunden) oder SENSOR_DELAY_FASTEST (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 Empfehlung. Das Android-System und andere Anwendungen können diese Verzögerung ändern. Es wird empfohlen, die maximale Verzögerung anzugeben, da das System in der Regel eine kürzere Verzögerung verwendet als die von Ihnen angegebene. Sie sollten also die niedrigste Abtastrate auswählen, die die Anforderungen Ihrer Anwendung erfüllt. Eine längere Verzögerung belastet den Prozessor weniger und verbraucht daher weniger Strom.

Es gibt keine öffentliche Methode, um die Rate zu ermitteln, mit der das Sensor-Framework Sensorereignisse an Ihre Anwendung sendet. Sie können jedoch die Zeitstempel verwenden, die mit jedem Sensorereignis verknüpft sind, um die Abtastrate über mehrere Ereignisse hinweg zu berechnen. Die Abtastrate (Verzögerung) sollte nach der Festlegung nicht mehr geändert werden müssen. Wenn Sie die Verzögerung aus irgendeinem Grund ändern müssen, müssen Sie den Sensor-Listener unregisteren und neu registrieren.

Beachten Sie außerdem, dass in diesem Beispiel die Callback-Methoden onResume() und onPause() zum Registrieren und Entfernen des Sensorereignis-Listeners verwendet werden. Es hat sich bewährt, Sensoren, die Sie nicht benötigen, immer zu deaktivieren, insbesondere wenn Ihre Aktivität pausiert ist. Andernfalls kann der Akku in nur wenigen Stunden leer sein, da einige Sensoren einen hohen Energieverbrauch 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 beliebige Sensorkonfigurationen 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 einen bestimmten Sensortyp benötigt, müssen Sie dafür sorgen, dass der Sensor auf dem Gerät vorhanden ist, damit Ihre App ausgeführt werden kann.

Sie haben 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 eine Ausrichtung auf Geräte mit bestimmten Sensorkonfigurationen vorzunehmen.

Diese Optionen werden in den folgenden Abschnitten erläutert.

Sensoren zur Laufzeit erkennen

Wenn Ihre Anwendung einen bestimmten Sensortyp verwendet, aber nicht darauf angewiesen ist, können Sie mit dem Sensor-Framework den Sensor zur Laufzeit erkennen und dann die Anwendungsfunktionen entsprechend deaktivieren oder aktivieren. Eine Navigations-App kann beispielsweise den Temperatursensor, den Drucksensor, den GPS-Sensor und den Sensor für das geomagnetische Feld verwenden, um die Temperatur, den barometrischen Druck, den Standort und die Kompasspeilung anzuzeigen. Wenn ein Gerät keinen Drucksensor hat, können Sie mit dem Sensor-Framework das Fehlen des Drucksensors zur Laufzeit erkennen 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 sich auf einem Gerät ein Drucksensor 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 Sie Ihre App bei Google Play veröffentlichen, können Sie mit dem Element <uses-feature> in Ihrer Manifestdatei Ihre App von Geräten herausfiltern, die nicht die richtige Sensorkonfiguration für Ihre App haben. Das Element <uses-feature> hat mehrere Hardware-Beschreibungen, mit denen Sie Anwendungen basierend auf der Anwesenheit 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. Im folgenden Beispiel wird ein Manifesteintrag gezeigt, mit dem Apps ohne Beschleunigungsmesser herausgefiltert werden:

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

Wenn Sie dieses Element und diesen Descriptor dem Manifest Ihrer App hinzufügen, sehen Nutzer Ihre App bei Google Play nur, wenn ihr Gerät einen Beschleunigungsmesser hat.

Sie sollten den Deskriptor nur dann auf android:required="true" festlegen, wenn Ihre Anwendung ausschließlich auf einem bestimmten Sensor basiert. Wenn Ihre Anwendung einen Sensor für einige Funktionen verwendet, aber auch ohne Sensor ausgeführt werden kann, sollten Sie den Sensor im Element <uses-feature> angeben, aber den Descriptor auf android:required="false" setzen. So können Geräte Ihre App auch dann installieren, wenn sie diesen bestimmten Sensor nicht haben. Dies ist auch eine Best Practice für das Projektmanagement, mit der Sie den Überblick über die Funktionen Ihrer Anwendung behalten können. Wenn Ihre Anwendung einen bestimmten Sensor verwendet, aber auch ohne ihn ausgeführt wird, sollten Sie den Sensor zur Laufzeit erkennen und die App-Funktionen 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 Display des Geräts definiert, wenn es in der Standardausrichtung gehalten wird (siehe Abbildung 1). Wenn ein Gerät in der 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 Displays. 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.

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 des OpenGL-Koordinatensystems.

Außerdem darf Ihre Anwendung nicht davon ausgehen, dass die Standardausrichtung eines Geräts im Hochformat ist. Die Standardausrichtung vieler Tablets ist Querformat. Das Sensorkoordinatensystem basiert immer auf der natürlichen Ausrichtung eines Geräts.

Wenn Ihre Anwendung Sensordaten mit dem Displayinhalt abgleicht, müssen Sie die Methode getRotation() verwenden, um die Bildschirmdrehung zu ermitteln, und dann die Methode remapCoordinateSystem(), um Sensorkoordinaten den Bildschirmkoordinaten zuzuordnen. Das ist auch dann erforderlich, wenn in Ihrem Manifest nur die Hochformatanzeige angegeben ist.

Hinweis:Einige Sensoren und Methoden verwenden ein Koordinatensystem, das sich auf den Weltkoordinatenbezug bezieht (im Gegensatz zum Gerätekoordinatenbezug). 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() und getRotationMatrix(), dem Orientierungssensor und dem Rotationsvektorsensor.

Sensor-Ratenbegrenzung

Zum Schutz potenziell vertraulicher Nutzerdaten wird die Aktualisierungsrate von Daten bestimmter Bewegungs- und Positionssensoren vom System begrenzt, wenn Ihre App auf Android 12 (API-Level 31) oder höher ausgerichtet ist. Dazu gehören Werte, die vom Beschleunigungsmesser, Gyroskop und Magnetfeldsensor des Geräts erfasst wurden.

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

Wenn Ihre App Bewegungssensordaten mit höherer Rate erfassen muss, müssen Sie die Berechtigung HIGH_SAMPLING_RATE_SENSORS deklarieren, wie im folgenden Code-Snippet gezeigt. Andernfalls, wenn Ihre App versucht, Bewegungssensordaten mit einer höheren Rate zu erheben, 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 und die Verwendung von Sensoren

Beachten Sie beim Entwerfen der Sensorimplementierung die in diesem Abschnitt beschriebenen Richtlinien. Diese Richtlinien sind Best Practices für alle, die das Sensor-Framework verwenden, um auf Sensoren zuzugreifen und Sensordaten zu erfassen.

Nur Sensordaten 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:

  • Bei Sensoren, die den kontinuierlichen Berichtsmodus verwenden, z. B. Beschleunigungsmesser und Gyroskope, werden keine Ereignisse empfangen.
  • Für Sensoren, die die Berichtsmodi bei Änderung oder Einzelmessung verwenden, werden keine Ereignisse empfangen.

Angesichts dieser Einschränkungen sollten Sie Sensorereignisse entweder erkennen, wenn sich Ihre App im Vordergrund befindet, oder als Teil eines Dienstes im Vordergrund.

Registrierung von Sensor-Listenern aufheben

Deregistrieren Sie den Listener eines Sensors, wenn Sie ihn nicht mehr verwenden oder die Sensoraktivität pausiert. Wenn ein Sensor-Listener registriert ist und seine Aktivität pausiert wird, erfasst der Sensor weiterhin Daten und verbraucht Akkuressourcen, es sei denn, Sie heben die Registrierung des Sensors auf. Im folgenden Code wird gezeigt, wie ein Listener mit der Methode onPause() abgemeldet wird:

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 Sie Sensoren wie Beschleunigungsmesser, Umgebungstemperatur, Magnetometer, Näherung und Licht testen können.

Der Emulator verwendet eine Verbindung zu 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 installiert ist, muss Revision 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 anhand der neuen Werte 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:

  1. Prüfen Sie, ob die USB-Fehlerbehebung auf Ihrem Gerät aktiviert ist.
  2. Verbinden Sie Ihr Gerät über ein USB-Kabel mit Ihrem Entwicklungscomputer.
  3. Starten Sie die App SdkControllerSensor auf Ihrem Gerät.
  4. Wählen Sie in der App die Sensoren aus, die Sie emulieren möchten.
  5. Führen Sie dazu 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 Ihr Gerät bewegen.

Hinweis : Wenn sich der Simulator nicht durch die Bewegungen auf Ihrem physischen Gerät verändert, führen Sie den Befehl adb aus Schritt 5 noch einmal aus.

Weitere Informationen finden Sie im Leitfaden zum Android-Emulator.

Blockieren Sie die Methode „onSensorChanged()“ nicht.

Sensordaten können sich sehr schnell ändern, was bedeutet, dass das System die onSensorChanged(SensorEvent)-Methode möglicherweise ziemlich oft aufruft. Es empfiehlt sich, in der onSensorChanged(SensorEvent)-Methode möglichst wenig zu tun, damit sie nicht blockiert wird. Wenn für Ihre Anwendung eine Datenfilterung oder eine Reduzierung von Sensordaten erforderlich ist, sollten Sie diese Arbeit außerhalb der Methode onSensorChanged(SensorEvent) ausführen.

Verwenden Sie keine eingestellten Methoden oder Sensortypen.

Mehrere Methoden und Konstanten wurden eingestellt. Insbesondere der Sensortyp TYPE_ORIENTATION wurde eingestellt. Verwenden Sie stattdessen die Methode getOrientation(), um Daten zur Ausrichtung abzurufen. Der Sensortyp TYPE_TEMPERATURE wird ebenfalls nicht mehr unterstützt. Auf Geräten mit Android 4.0 sollten Sie stattdessen den Sensortyp TYPE_AMBIENT_TEMPERATURE verwenden.

Sensoren vor der Verwendung prüfen

Prüfen Sie immer, ob ein Sensor auf einem Gerät vorhanden ist, bevor Sie versuchen, Daten von ihm zu erfassen. Angenommen, ein Sensor ist vorhanden, nur weil er häufig verwendet wird, ist nicht richtig. Gerätehersteller sind nicht verpflichtet, bestimmte Sensoren in ihren Geräten zu verwenden.

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 Sie dem System erlauben, zusätzliche Daten zu senden, die Sie nicht benötigen, werden Systemressourcen verschwendet und der Akku entlastet.