La plupart des appareils Android sont équipés de capteurs intégrés qui mesurent le mouvement, l'orientation et diverses conditions environnementales. Ces capteurs sont capables de fournir des données brutes avec une grande précision et sont utiles si vous souhaitez surveiller le mouvement ou le positionnement tridimensionnel d'un appareil, ou les changements dans l'environnement ambiant à proximité d'un appareil. Par exemple, un jeu peut suivre les lectures du capteur de gravité d'un appareil pour déduire des gestes et des mouvements complexes de l'utilisateur, tels que l'inclinaison, la secousse, la rotation ou le balancement. De même, une application météo peut utiliser les capteurs de température et d'humidité d'un appareil pour calculer et indiquer le point de rosée, ou une application de voyage peut utiliser le capteur de champ géomagnétique et l'accéléromètre pour indiquer un cap de boussole.
Consultez les ressources associées suivantes :
La plate-forme Android prend en charge trois grandes catégories de capteurs :
- Capteurs de mouvement
Ces capteurs mesurent les forces d'accélération et de rotation sur trois axes. Cette catégorie inclut les accéléromètres, les capteurs de gravité, les gyroscopes et les capteurs de vecteur de rotation.
- Capteurs environnementaux
Ces capteurs mesurent différents paramètres environnementaux, tels que la température et la pression de l'air ambiant, l'éclairage et l'humidité. Cette catégorie inclut les baromètres, les photomètres et les thermomètres.
- Capteurs de position
Ces capteurs mesurent la position physique d'un appareil. Cette catégorie inclut les capteurs d'orientation et les magnétomètres.
Vous pouvez accéder aux capteurs disponibles sur l'appareil et acquérir des données brutes de capteur à l'aide du framework de capteur Android. Le framework de capteurs fournit plusieurs classes et interfaces qui vous aident à effectuer un large éventail de tâches liées aux capteurs. Par exemple, vous pouvez utiliser le framework de capteurs pour effectuer les opérations suivantes :
- Déterminez quels capteurs sont disponibles sur un appareil.
- Déterminez les capacités d'un capteur individuel, telles que sa portée maximale, son fabricant, ses besoins en énergie et sa résolution.
- Acquérir des données brutes de capteur et définir le taux minimal d'acquisition de ces données
- Enregistrez et désenregistrez les écouteurs d'événements de capteur qui surveillent les changements de capteur.
Cet article présente les capteurs disponibles sur la plate-forme Android. Il fournit également une introduction au framework de capteurs.
Présentation des capteurs
Le framework de capteurs Android vous permet d'accéder à de nombreux types de capteurs. Certains de ces capteurs sont matériels et d'autres logiciels. Les capteurs matériels sont des composants physiques intégrés à un téléphone ou une tablette. Ils obtiennent leurs données en mesurant directement des propriétés environnementales spécifiques, telles que l'accélération, l'intensité du champ géomagnétique ou la variation angulaire. Les capteurs logiciels ne sont pas des appareils physiques, bien qu'ils imitent les capteurs matériels. Les capteurs logiciels tirent leurs données d'un ou de plusieurs capteurs matériels. Ils sont parfois appelés capteurs virtuels ou capteurs synthétiques. Le capteur d'accélération linéaire et le capteur de gravité sont des exemples de capteurs logiciels. Le tableau 1 récapitule les capteurs compatibles avec la plate-forme Android.
Peu d'appareils Android disposent de tous les types de capteurs. Par exemple, la plupart des téléphones et des tablettes sont équipés d'un accéléromètre et d'un magnétomètre, mais moins d'appareils disposent d'un baromètre ou d'un thermomètre. De plus, un appareil peut comporter plusieurs capteurs d'un même type. Par exemple, un appareil peut disposer de deux capteurs de gravité, chacun ayant une plage différente.
Tableau 1. Types de capteurs compatibles avec la plate-forme Android.
Capteur | Saisie | Description | Utilisations courantes |
---|---|---|---|
TYPE_ACCELEROMETER |
Matériel | Mesure la force d'accélération en m/s2 appliquée à un appareil sur les trois axes physiques (x, y et z), y compris la force de gravité. | Détection des mouvements (secousse, inclinaison, etc.) |
TYPE_AMBIENT_TEMPERATURE |
Matériel | Mesure la température ambiante de la pièce en degrés Celsius (°C). Voir la note ci-dessous. | Surveillance des températures de l'air |
TYPE_GRAVITY |
Logiciel ou matériel | Mesure la force de gravité en m/s2 appliquée à un appareil sur les trois axes physiques (x, y, z). | Détection des mouvements (secousse, inclinaison, etc.) |
TYPE_GYROSCOPE |
Matériel | Mesure la vitesse de rotation d'un appareil en rad/s autour de chacun des trois axes physiques (x, y et z). | Détection de la rotation (rotation, virage, etc.). |
TYPE_LIGHT |
Matériel | Mesure le niveau de luminosité ambiante (éclairage) en lux. | Contrôle la luminosité de l'écran. |
TYPE_LINEAR_ACCELERATION |
Logiciel ou matériel | Mesure la force d'accélération en m/s2 appliquée à un appareil sur les trois axes physiques (x, y et z), à l'exclusion de la force de gravité. | Surveillance de l'accélération sur un seul axe. |
TYPE_MAGNETIC_FIELD |
Matériel | Mesure le champ géomagnétique ambiant pour les trois axes physiques (x, y, z) en μT. | Créer un compas. |
TYPE_ORIENTATION |
Logiciel | Mesure les degrés de rotation d'un appareil autour des trois axes physiques (x, y et z).
À partir du niveau d'API 3, vous pouvez obtenir la matrice d'inclinaison et la matrice de rotation d'un appareil en utilisant le capteur de gravité et le capteur de champ géomagnétique en combinaison avec la méthode getRotationMatrix() . |
Déterminer la position de l'appareil. |
TYPE_PRESSURE |
Matériel | Mesure la pression atmosphérique ambiante en hPa ou en mbar. | Surveiller les variations de pression atmosphérique. |
TYPE_PROXIMITY |
Matériel | Mesure la proximité d'un objet en cm par rapport à l'écran de l'appareil. Ce capteur est généralement utilisé pour déterminer si un téléphone est tenu à l'oreille d'une personne. | Position du téléphone pendant un appel. |
TYPE_RELATIVE_HUMIDITY |
Matériel | Mesure l'humidité relative ambiante en pourcentage (%). | Surveillance du point de rosée, de l'humidité absolue et de l'humidité relative. |
TYPE_ROTATION_VECTOR |
Logiciel ou matériel | Mesure l'orientation d'un appareil en fournissant les trois éléments du vecteur de rotation de l'appareil. | Détection des mouvements et de la rotation. |
TYPE_TEMPERATURE |
Matériel | Mesure la température de l'appareil en degrés Celsius (°C). L'implémentation de ce capteur varie selon les appareils. Il a été remplacé par le capteur TYPE_AMBIENT_TEMPERATURE au niveau d'API 14. |
Surveillance des températures. |
Framework de capteurs
Vous pouvez accéder à ces capteurs et obtenir des données brutes à l'aide du framework de capteur Android.
Le framework de capteurs fait partie du package android.hardware
et inclut les classes et interfaces suivantes :
SensorManager
- Vous pouvez utiliser cette classe pour créer une instance du service de capteur. Cette classe fournit différentes méthodes pour accéder aux capteurs et les lister, enregistrer et désenregistrer les écouteurs d'événements de capteur, et obtenir des informations sur l'orientation. Cette classe fournit également plusieurs constantes de capteur qui sont utilisées pour indiquer la précision du capteur, définir les taux d'acquisition de données et calibrer les capteurs.
Sensor
- Vous pouvez utiliser cette classe pour créer une instance d'un capteur spécifique. Cette classe fournit différentes méthodes qui vous permettent de déterminer les capacités d'un capteur.
SensorEvent
- Le système utilise cette classe pour créer un objet d'événement de capteur, qui fournit des informations sur un événement de capteur. Un objet d'événement de capteur inclut les informations suivantes : les données brutes du capteur, le type de capteur qui a généré l'événement, la précision des données et le code temporel de l'événement.
SensorEventListener
- Vous pouvez utiliser cette interface pour créer deux méthodes de rappel qui reçoivent des notifications (événements de capteur) lorsque les valeurs ou la précision du capteur changent.
Dans une application classique, vous utilisez ces API liées aux capteurs pour effectuer deux tâches de base :
- Identifier les capteurs et leurs fonctionnalités
L'identification des capteurs et de leurs capacités au moment de l'exécution est utile si votre application comporte des fonctionnalités qui reposent sur des types ou des capacités de capteurs spécifiques. Par exemple, vous pouvez identifier tous les capteurs présents sur un appareil et désactiver toutes les fonctionnalités d'application qui s'appuient sur des capteurs qui ne sont pas présents. De même, vous pouvez identifier tous les capteurs d'un type donné afin de choisir l'implémentation de capteur qui offre les performances optimales pour votre application.
- Surveiller les événements de capteur
La surveillance des événements de capteur est la façon dont vous acquérez les données brutes des capteurs. Un événement de capteur se produit chaque fois qu'un capteur détecte une modification des paramètres qu'il mesure. Un événement de capteur vous fournit quatre informations : le nom du capteur qui a déclenché l'événement, le code temporel de l'événement, la précision de l'événement et les données brutes du capteur qui ont déclenché l'événement.
Disponibilité des capteurs
La disponibilité des capteurs varie d'un appareil à l'autre, mais aussi d'une version d'Android à l'autre. En effet, les capteurs Android ont été introduits au cours de plusieurs versions de la plate-forme. Par exemple, de nombreux capteurs ont été introduits dans Android 1.5 (niveau d'API 3), mais certains n'ont pas été implémentés et n'étaient pas disponibles avant Android 2.3 (niveau d'API 9). De même, plusieurs capteurs ont été introduits dans Android 2.3 (niveau d'API 9) et Android 4.0 (niveau d'API 14). Deux capteurs ont été abandonnés et remplacés par des capteurs plus récents et plus performants.
Le tableau 2 récapitule la disponibilité de chaque capteur pour chaque plate-forme. Seules quatre plates-formes sont listées, car ce sont celles qui ont subi des modifications au niveau des capteurs. Les capteurs listés comme obsolètes sont toujours disponibles sur les plates-formes ultérieures (à condition que le capteur soit présent sur un appareil), ce qui est conforme à la politique de compatibilité ascendante d'Android.
Tableau 2. Disponibilité des capteurs par plate-forme.
Capteur | Android 4.0 (niveau d'API 14) |
Android 2.3 (niveau d'API 9) |
Android 2.2 (niveau d'API 8) |
Android 1.5 (niveau d'API 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
Oui | Oui | Oui | Oui |
TYPE_AMBIENT_TEMPERATURE |
Oui | n/a | n/a | n/a |
TYPE_GRAVITY |
Oui | Oui | n/a | n/a |
TYPE_GYROSCOPE |
Oui | Oui | n/a1 | n/a1 |
TYPE_LIGHT |
Oui | Oui | Oui | Oui |
TYPE_LINEAR_ACCELERATION |
Oui | Oui | n/a | n/a |
TYPE_MAGNETIC_FIELD |
Oui | Oui | Oui | Oui |
TYPE_ORIENTATION |
Oui2 | Oui2 | Oui2 | Oui |
TYPE_PRESSURE |
Oui | Oui | n/a1 | n/a1 |
TYPE_PROXIMITY |
Oui | Oui | Oui | Oui |
TYPE_RELATIVE_HUMIDITY |
Oui | n/a | n/a | n/a |
TYPE_ROTATION_VECTOR |
Oui | Oui | n/a | n/a |
TYPE_TEMPERATURE |
Oui2 | Oui | Oui | Oui |
1 Ce type de capteur a été ajouté dans Android 1.5 (niveau d'API 3), mais il n'était pas disponible avant Android 2.3 (niveau d'API 9).
2 Ce capteur est disponible, mais il a été abandonné.
Identifier les capteurs et leurs capacités
Le framework de capteurs Android fournit plusieurs méthodes qui vous permettent de déterminer facilement, au moment de l'exécution, quels capteurs sont présents sur un appareil. L'API fournit également des méthodes qui vous permettent de déterminer les capacités de chaque capteur, telles que sa plage maximale, sa résolution et ses besoins en énergie.
Pour identifier les capteurs présents sur un appareil, vous devez d'abord obtenir une référence au service de capteur. Pour ce faire, créez une instance de la classe SensorManager
en appelant la méthode getSystemService()
et en transmettant l'argument SENSOR_SERVICE
. Exemple :
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Vous pouvez ensuite obtenir la liste de tous les capteurs d'un appareil en appelant la méthode getSensorList()
et en utilisant la constante TYPE_ALL
. Exemple :
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Si vous souhaitez lister tous les capteurs d'un type donné, vous pouvez utiliser une autre constante au lieu de TYPE_ALL
, comme TYPE_GYROSCOPE
, TYPE_LINEAR_ACCELERATION
ou TYPE_GRAVITY
.
Vous pouvez également déterminer si un type de capteur spécifique existe sur un appareil à l'aide de la méthode getDefaultSensor()
et en transmettant la constante de type pour un capteur spécifique. Si un appareil possède plusieurs capteurs d'un type donné, l'un d'eux doit être désigné comme capteur par défaut. Si aucun capteur par défaut n'existe pour un type de capteur donné, l'appel de méthode renvoie la valeur "null", ce qui signifie que l'appareil ne dispose pas de ce type de capteur. Par exemple, le code suivant vérifie si un magnétomètre est présent sur un appareil :
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. }
Remarque : Android n'oblige pas les fabricants d'appareils à intégrer des types de capteurs spécifiques dans leurs appareils Android. Les appareils peuvent donc avoir un large éventail de configurations de capteurs.
En plus de lister les capteurs présents sur un appareil, vous pouvez utiliser les méthodes publiques de la classe Sensor
pour déterminer les capacités et les attributs de chaque capteur. Cela peut être utile si vous souhaitez que votre application se comporte différemment en fonction des capteurs ou des fonctionnalités de capteur disponibles sur un appareil. Par exemple, vous pouvez utiliser les méthodes getResolution()
et getMaximumRange()
pour obtenir la résolution et la plage de mesure maximale d'un capteur. Vous pouvez également utiliser la méthode getPower()
pour obtenir les besoins en énergie d'un capteur.
Deux des méthodes publiques sont particulièrement utiles si vous souhaitez optimiser votre application pour les capteurs de différents fabricants ou pour différentes versions d'un capteur. Par exemple, si votre application doit surveiller les gestes de l'utilisateur, tels que l'inclinaison et la secousse, vous pouvez créer un ensemble de règles et d'optimisations de filtrage des données pour les appareils récents qui disposent d'un capteur de gravité d'un fournisseur spécifique, et un autre ensemble de règles et d'optimisations de filtrage des données pour les appareils qui ne disposent pas de capteur de gravité et qui n'ont qu'un accéléromètre. L'exemple de code suivant montre comment utiliser les méthodes getVendor()
et getVersion()
pour ce faire. Dans cet exemple, nous recherchons un capteur de gravité dont le fournisseur est Google LLC et dont le numéro de version est 3. Si ce capteur n'est pas présent sur l'appareil, nous essayons d'utiliser l'accéléromètre.
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. } }
Une autre méthode utile est getMinDelay()
, qui renvoie l'intervalle de temps minimal (en microsecondes) qu'un capteur peut utiliser pour détecter des données. Tout capteur qui renvoie une valeur non nulle pour la méthode getMinDelay()
est un capteur de flux. Les capteurs de flux détectent les données à intervalles réguliers. Ils ont été introduits dans Android 2.3 (niveau d'API 9). Si un capteur renvoie zéro lorsque vous appelez la méthode getMinDelay()
, cela signifie qu'il ne s'agit pas d'un capteur de flux, car il ne signale les données que lorsque les paramètres qu'il détecte changent.
La méthode getMinDelay()
est utile, car elle vous permet de déterminer la fréquence maximale à laquelle un capteur peut acquérir des données. Si certaines fonctionnalités de votre application nécessitent des taux d'acquisition de données élevés ou un capteur de flux, vous pouvez utiliser cette méthode pour déterminer si un capteur répond à ces exigences, puis activer ou désactiver les fonctionnalités concernées dans votre application en conséquence.
Attention : La fréquence maximale d'acquisition de données d'un capteur n'est pas nécessairement la fréquence à laquelle le framework de capteurs fournit les données de capteur à votre application. Le framework de capteurs transmet les données par le biais d'événements de capteur. Plusieurs facteurs influencent la fréquence à laquelle votre application reçoit ces événements. Pour en savoir plus, consultez Surveillance des événements de capteur.
Surveiller les événements de capteur
Pour surveiller les données brutes des capteurs, vous devez implémenter deux méthodes de rappel exposées par l'interface SensorEventListener
: onAccuracyChanged()
et onSensorChanged()
. Le système Android appelle ces méthodes chaque fois que les événements suivants se produisent :
- La précision d'un capteur change.
Dans ce cas, le système appelle la méthode
onAccuracyChanged()
, en vous fournissant une référence à l'objetSensor
qui a changé et la nouvelle précision du capteur. La précision est représentée par l'une des quatre constantes d'état suivantes :SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, ouSENSOR_STATUS_UNRELIABLE
. - Un capteur a signalé une nouvelle valeur.
Dans ce cas, le système appelle la méthode
onSensorChanged()
et vous fournit un objetSensorEvent
. Un objetSensorEvent
contient des informations sur les nouvelles données du capteur, y compris la précision des données, le capteur qui les a générées, le code temporel auquel elles ont été générées et les nouvelles données enregistrées par le capteur.
Le code suivant montre comment utiliser la méthode onSensorChanged()
pour surveiller les données du capteur de luminosité. Cet exemple affiche les données brutes du capteur dans un TextView
qui est défini dans le fichier main.xml en tant que sensor_data
.
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); } }
Dans cet exemple, le délai de données par défaut (SENSOR_DELAY_NORMAL
) est spécifié lorsque la méthode registerListener()
est appelée. Le délai des données (ou taux d'échantillonnage) contrôle l'intervalle auquel les événements de capteur sont envoyés à votre application via la méthode de rappel onSensorChanged()
. Le délai de données par défaut convient à la surveillance des changements d'orientation d'écran typiques et utilise un délai de 200 000 microsecondes. Vous pouvez spécifier d'autres délais de données, tels que SENSOR_DELAY_GAME
(délai de 20 000 microsecondes), SENSOR_DELAY_UI
(délai de 60 000 microsecondes) ou SENSOR_DELAY_FASTEST
(délai de 0 microseconde). Depuis Android 3.0 (niveau d'API 11), vous pouvez également spécifier le délai sous forme de valeur absolue (en microsecondes).
Le délai que vous spécifiez n'est qu'une suggestion. Le système Android et d'autres applications peuvent modifier ce délai. Nous vous recommandons de spécifier le délai le plus long possible, car le système utilise généralement un délai plus court que celui que vous spécifiez (c'est-à-dire que vous devez choisir la fréquence d'échantillonnage la plus lente qui répond toujours aux besoins de votre application). L'utilisation d'un délai plus long impose une charge moins importante au processeur et consomme donc moins d'énergie.
Il n'existe aucune méthode publique permettant de déterminer la fréquence à laquelle le framework de capteurs envoie des événements de capteur à votre application. Toutefois, vous pouvez utiliser les codes temporels associés à chaque événement de capteur pour calculer la fréquence d'échantillonnage sur plusieurs événements. Une fois que vous avez défini le taux d'échantillonnage (délai), vous ne devriez pas avoir à le modifier. Si, pour une raison quelconque, vous devez modifier le délai, vous devrez désenregistrer et réenregistrer l'écouteur de capteur.
Il est également important de noter que cet exemple utilise les méthodes de rappel onResume()
et onPause()
pour enregistrer et annuler l'enregistrement du détecteur d'événements du capteur. Il est recommandé de toujours désactiver les capteurs dont vous n'avez pas besoin, en particulier lorsque votre activité est suspendue. À défaut, la batterie peut se décharger en quelques heures seulement, car certains capteurs ont des besoins énergétiques importants et peuvent consommer rapidement l'énergie de la batterie. Le système ne désactivera pas automatiquement les capteurs lorsque l'écran s'éteindra.
Gérer différentes configurations de capteurs
Android ne spécifie pas de configuration de capteur standard pour les appareils, ce qui signifie que les fabricants d'appareils peuvent intégrer la configuration de capteur de leur choix dans leurs appareils fonctionnant sous Android. Par conséquent, les appareils peuvent inclure différents capteurs dans un large éventail de configurations. Si votre application repose sur un type de capteur spécifique, vous devez vous assurer que le capteur est présent sur un appareil pour que votre application puisse s'exécuter correctement.
Deux options s'offrent à vous pour vous assurer qu'un capteur donné est présent sur un appareil :
- Détectez les capteurs au moment de l'exécution et activez ou désactivez les fonctionnalités de l'application selon les besoins.
- Utilisez les filtres Google Play pour cibler les appareils dotés de configurations de capteurs spécifiques.
Chaque option est décrite dans les sections suivantes.
Détecter les capteurs au moment de l'exécution
Si votre application utilise un type de capteur spécifique, mais ne s'y appuie pas, vous pouvez utiliser le framework de capteur pour détecter le capteur au moment de l'exécution, puis activer ou désactiver les fonctionnalités de l'application selon les besoins. Par exemple, une application de navigation peut utiliser le capteur de température, le capteur de pression, le capteur GPS et le capteur de champ géomagnétique pour afficher la température, la pression barométrique, la position et le cap de la boussole. Si un appareil ne possède pas de capteur de pression, vous pouvez utiliser le framework de capteurs pour détecter l'absence du capteur de pression au moment de l'exécution, puis désactiver la partie de l'UI de votre application qui affiche la pression. Par exemple, le code suivant vérifie si un capteur de pression est présent sur un appareil :
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. }
Utiliser les filtres Google Play pour cibler des configurations de capteurs spécifiques
Si vous publiez votre application sur Google Play, vous pouvez utiliser l'élément <uses-feature>
dans votre fichier manifeste pour filtrer votre application et l'exclure des appareils qui ne disposent pas de la configuration de capteur appropriée. L'élément <uses-feature>
comporte plusieurs descripteurs matériels qui vous permettent de filtrer les applications en fonction de la présence de capteurs spécifiques. Les capteurs que vous pouvez lister incluent : accéléromètre, baromètre, boussole (champ géomagnétique), gyroscope, lumière et proximité. Voici un exemple d'entrée de fichier manifeste qui filtre les applications qui ne disposent pas d'un accéléromètre :
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Si vous ajoutez cet élément et ce descripteur au fichier manifeste de votre application, les utilisateurs ne verront votre application sur Google Play que si leur appareil est équipé d'un accéléromètre.
Vous ne devez définir le descripteur sur android:required="true"
que si votre application repose entièrement sur un capteur spécifique. Si votre application utilise un capteur pour certaines fonctionnalités, mais qu'elle fonctionne quand même sans le capteur, vous devez l'indiquer dans l'élément <uses-feature>
, mais définir le descripteur sur android:required="false"
. Cela permet de s'assurer que les appareils peuvent installer votre application même s'ils ne disposent pas de ce capteur spécifique. Il s'agit également d'une bonne pratique de gestion de projet qui vous aide à suivre les fonctionnalités utilisées par votre application.
N'oubliez pas que si votre application utilise un capteur spécifique, mais qu'elle fonctionne quand même sans ce capteur, vous devez détecter le capteur au moment de l'exécution et désactiver ou activer les fonctionnalités de l'application selon le cas.
Système de coordonnées du capteur
En général, le framework de capteurs utilise un système de coordonnées standard à trois axes pour exprimer les valeurs de données. Pour la plupart des capteurs, le système de coordonnées est défini par rapport à l'écran de l'appareil lorsque celui-ci est tenu dans son orientation par défaut (voir figure 1). Lorsqu'un appareil est tenu dans son orientation par défaut, l'axe X est horizontal et pointe vers la droite, l'axe Y est vertical et pointe vers le haut, et l'axe Z pointe vers l'extérieur de la face de l'écran. Dans ce système, les coordonnées derrière l'écran ont des valeurs Z négatives. Ce système de coordonnées est utilisé par les capteurs suivants :

Figure 1 : Système de coordonnées (relatif à un appareil) utilisé par l'API Sensor.
- Capteur d'accélération
- Capteur de gravité
- Gyroscope
- Capteur d'accélération linéaire
- Capteur de champ géomagnétique
Le point le plus important à comprendre concernant ce système de coordonnées est que les axes ne sont pas inversés lorsque l'orientation de l'écran de l'appareil change. En d'autres termes, le système de coordonnées du capteur ne change jamais lorsque l'appareil se déplace. Ce comportement est identique à celui du système de coordonnées OpenGL.
Il est également important de comprendre que votre application ne doit pas supposer que l'orientation naturelle (par défaut) d'un appareil est le mode Portrait. L'orientation naturelle de nombreuses tablettes est le mode paysage. De plus, le système de coordonnées du capteur est toujours basé sur l'orientation naturelle d'un appareil.
Enfin, si votre application fait correspondre les données du capteur à l'affichage à l'écran, vous devez utiliser la méthode getRotation()
pour déterminer la rotation de l'écran, puis la méthode remapCoordinateSystem()
pour mapper les coordonnées du capteur à celles de l'écran. Vous devez le faire même si votre fichier manifeste spécifie un affichage en mode Portrait uniquement.
Remarque : Certains capteurs et méthodes utilisent un système de coordonnées relatif au repère du monde (par opposition au repère de l'appareil). Ces capteurs et méthodes renvoient des données qui représentent le mouvement ou la position de l'appareil par rapport à la Terre. Pour en savoir plus, consultez les méthodes getOrientation()
et getRotationMatrix()
, ainsi que les sections Capteur d'orientation et Capteur de vecteur de rotation.
Limitation du débit du capteur
Pour protéger les informations potentiellement sensibles sur les utilisateurs, si votre application cible Android 12 (niveau d'API 31) ou version ultérieure, le système limite la fréquence d'actualisation des données de certains capteurs de mouvement et de position. Ces données incluent les valeurs enregistrées par l'accéléromètre, le gyroscope et le capteur de champ géomagnétique de l'appareil.
La limite de fréquence d'actualisation dépend de la façon dont vous accédez aux données des capteurs :
- Si vous appelez la méthode
registerListener()
pour surveiller les événements du capteur, la fréquence d'échantillonnage du capteur est limitée à 200 Hz. Cela s'applique à toutes les variantes surchargées de la méthoderegisterListener()
. - Si vous utilisez la classe
SensorDirectChannel
, le taux d'échantillonnage du capteur est limité àRATE_NORMAL
, ce qui correspond généralement à environ 50 Hz.
Si votre application doit collecter des données de capteur de mouvement à une fréquence plus élevée, vous devez déclarer l'autorisation HIGH_SAMPLING_RATE_SENSORS
, comme indiqué dans l'extrait de code suivant. Sinon, si votre application tente de collecter des données de capteur de mouvement à une fréquence plus élevée sans déclarer cette autorisation, une erreur SecurityException
se produit.
AndroidManifest.xml
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Bonnes pratiques pour accéder aux capteurs et les utiliser
Lorsque vous concevez votre implémentation de capteurs, veillez à suivre les consignes décrites dans cette section. Ces consignes sont des bonnes pratiques recommandées pour toute personne utilisant le framework de capteurs afin d'accéder aux capteurs et d'acquérir des données de capteurs.
Ne collecter les données des capteurs qu'au premier plan
Sur les appareils équipés d'Android 9 (niveau d'API 28) ou d'une version ultérieure, les applications exécutées en arrière-plan sont soumises aux restrictions suivantes :
- Les capteurs qui utilisent le mode de reporting continu, tels que les accéléromètres et les gyroscopes, ne reçoivent pas d'événements.
- Les capteurs qui utilisent les modes de rapport on-change ou one-shot ne reçoivent pas d'événements.
Compte tenu de ces restrictions, il est préférable de détecter les événements de capteur lorsque votre application est au premier plan ou dans le cadre d'un service de premier plan.
Désenregistrer les écouteurs de capteur
Veillez à désinscrire l'écouteur d'un capteur lorsque vous avez fini d'utiliser le capteur ou lorsque l'activité du capteur est suspendue. Si un écouteur de capteur est enregistré et que son activité est suspendue, le capteur continuera à acquérir des données et à utiliser les ressources de la batterie, sauf si vous le désenregistrez. Le code suivant montre comment utiliser la méthode onPause()
pour annuler l'enregistrement d'un écouteur :
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); }
Pour en savoir plus, consultez unregisterListener(SensorEventListener)
.
Tester avec l'émulateur Android
L'émulateur Android inclut un ensemble de commandes de capteur virtuel qui vous permettent de tester des capteurs tels que l'accéléromètre, la température ambiante, le magnétomètre, la proximité, la luminosité, etc.
L'émulateur utilise une connexion avec un appareil Android exécutant l'application SdkControllerSensor. Notez que cette application n'est disponible que sur les appareils exécutant Android 4.0 (niveau d'API 14) ou version ultérieure. (Si l'appareil est équipé d'Android 4.0, la révision 2 doit être installée.) L'application SdkControllerSensor surveille les modifications apportées aux capteurs de l'appareil et les transmet à l'émulateur. L'émulateur est ensuite transformé en fonction des nouvelles valeurs qu'il reçoit des capteurs de votre appareil.
Vous pouvez consulter le code source de l'application SdkControllerSensor à l'emplacement suivant :
$ your-android-sdk-directory/tools/apps/SdkController
Pour transférer des données entre votre appareil et l'émulateur, procédez comme suit :
- Vérifiez que le débogage USB est activé sur votre appareil.
- Connectez votre appareil à votre ordinateur de développement à l'aide d'un câble USB.
- Lancez l'application SdkControllerSensor sur votre appareil.
- Dans l'application, sélectionnez les capteurs que vous souhaitez émuler.
Exécutez la commande
adb
suivante :- Démarrez l'émulateur. Vous devriez maintenant pouvoir appliquer des transformations à l'émulateur en déplaçant votre appareil.
$ adb forward tcp:1968 tcp:1968
Remarque : Si les mouvements que vous effectuez sur votre appareil physique ne transforment pas l'émulateur, essayez d'exécuter à nouveau la commande adb
de l'étape 5.
Pour en savoir plus, consultez le guide Android Emulator.
Ne bloquez pas la méthode onSensorChanged()
Les données des capteurs peuvent changer à un rythme élevé, ce qui signifie que le système peut appeler la méthode onSensorChanged(SensorEvent)
assez souvent. Nous vous recommandons de faire le moins possible dans la méthode onSensorChanged(SensorEvent)
pour ne pas la bloquer. Si votre application nécessite un filtrage ou une réduction des données de capteur, vous devez effectuer cette opération en dehors de la méthode onSensorChanged(SensorEvent)
.
Évitez d'utiliser des méthodes ou des types de capteurs obsolètes
Plusieurs méthodes et constantes ont été abandonnées.
En particulier, le type de capteur TYPE_ORIENTATION
a été abandonné. Pour obtenir des données d'orientation, vous devez utiliser la méthode getOrientation()
. De même, le type de capteur TYPE_TEMPERATURE
a été abandonné. Vous devez utiliser le type de capteur TYPE_AMBIENT_TEMPERATURE
sur les appareils équipés d'Android 4.0.
Vérifier les capteurs avant de les utiliser
Vérifiez toujours qu'un capteur existe sur un appareil avant de tenter d'acquérir des données à partir de celui-ci. Ne partez pas du principe qu'un capteur existe simplement parce qu'il est fréquemment utilisé. Les fabricants d'appareils ne sont pas tenus de fournir de capteurs spécifiques dans leurs appareils.
Choisir soigneusement les délais des capteurs
Lorsque vous enregistrez un capteur avec la méthode registerListener()
, veillez à choisir un taux de diffusion adapté à votre application ou à votre cas d'utilisation. Les capteurs peuvent fournir des données à des taux très élevés. Autoriser le système à envoyer des données supplémentaires dont vous n'avez pas besoin gaspille les ressources système et consomme la batterie.