La mayoría de los dispositivos con Android tienen sensores integrados que miden movimiento, orientación, y diversas condiciones ambientales. Estos sensores son capaces de proporcionar datos sin procesar con alta precisión y exactitud, y son útiles si deseas supervisar el movimiento tridimensional del dispositivo o de la imagen o quieres supervisar los cambios en el entorno ambiente cerca de un dispositivo. Por ejemplo, un El juego podría hacer un seguimiento de las lecturas del sensor de gravedad de un dispositivo para inferir gestos complejos del usuario. y movimientos, como inclinación, agitación, rotación o balanceo. Del mismo modo, una aplicación meteorológica podría usar una sensor de temperatura y de humedad del dispositivo para calcular e informar el punto de condensación o un podría usar el sensor de campos geomagnéticos y el acelerómetro para informar la presencia de una brújula la carga de trabajo.
Consulta los siguientes recursos relacionados:
La plataforma de Android admite tres amplias categorías de sensores:
- Sensores de movimiento
Estos sensores miden las fuerzas de aceleración y las fuerzas de rotación en tres ejes. Esta incluye acelerómetros, sensores de gravedad, giroscopios y vectores de rotación sensores.
- Sensores ambientales
Estos sensores miden varios parámetros ambientales, como la temperatura del aire en el ambiente la presión, la iluminación y la humedad. Esta categoría incluye barómetros, fotómetros y termómetros.
- Sensores de posición
Estos sensores miden la posición física de un dispositivo. Esta categoría incluye de orientación y magnetómetros.
Puedes acceder a los sensores disponibles en el dispositivo y adquirir datos sin procesar del sensor a través del del marco de trabajo del sensor. El marco de trabajo del sensor proporciona varias clases e interfaces que ayudan a realizar un amplio y una variedad de tareas relacionadas con los sensores. Por ejemplo, puedes usar el marco de trabajo del sensor para las siguientes tareas:
- Determina qué sensores están disponibles en un dispositivo.
- Determinar las capacidades de un sensor individual, como su rango máximo, fabricante, potencia los requisitos y la resolución.
- Adquiere datos sin procesar del sensor y define la velocidad mínima con la que adquirirás los datos del sensor.
- Registra y cancela el registro de oyentes de objetos de escucha de eventos que supervisan los cambios del sensor.
En este tema, se proporciona una descripción general de los sensores que están disponibles en la plataforma de Android. También se proporciona una introducción al marco de trabajo del sensor.
Introducción a los sensores
El marco de trabajo del sensor de Android permite acceder a muchos tipos de sensores. Algunos de estos sensores son se basan en hardware y otros se basan en software. Los sensores basados en hardware son componentes físicos construidos en un teléfono celular o tablet. Obtienen sus datos midiendo directamente propiedades, como la aceleración, la fuerza del campo geomagnético o el cambio angular. Basado en software los sensores no son dispositivos físicos, aunque imitan sensores basados en hardware. Sensores basados en software sus datos de uno o más sensores basados en hardware y, a veces, se denominan o sensores sintéticos. El sensor de aceleración lineal y el sensor de gravedad son ejemplos de basados en software. En la tabla 1, se resumen los sensores que son compatibles con Android plataforma.
Solo unos pocos dispositivos con Android tienen todos los tipos de sensores. Por ejemplo, la mayoría de los teléfonos celulares y las tabletas tienen un acelerómetro y un magnetómetro, pero menos dispositivos tienen barómetros o termómetros. Además, un dispositivo puede tener más de un sensor de un tipo determinado. Para ejemplo, un dispositivo puede tener dos sensores de gravedad, cada uno con un rango diferente.
Sensor | Tipo | Descripción | Usos habituales |
---|---|---|---|
TYPE_ACCELEROMETER |
Hardware | Mide en m/s2 la fuerza de aceleración que se aplica a un dispositivo en los tres ejes físicos (x, y, y z), incluida la fuerza de gravedad. | Detección de movimiento (agitación, inclinación, etc.). |
TYPE_AMBIENT_TEMPERATURE |
Hardware | Mide la temperatura ambiente de la habitación en grados Celsius (°C). Consulta la siguiente nota. | Supervisión de la temperatura del aire. |
TYPE_GRAVITY |
Software o hardware | Mide en m/s2 la fuerza de gravedad que se aplica a un dispositivo en todas tres ejes físicos (x, y, z). | Detección de movimiento (agitación, inclinación, etc.). |
TYPE_GYROSCOPE |
Hardware | Mide en rad/s la velocidad de rotación de un dispositivo alrededor de cada uno de los tres. ejes físicos (x, y, z). | Detección de rotación (agitación, giro, etc.). |
TYPE_LIGHT |
Hardware | Mide el nivel de luz ambiental (iluminación) en lx. | Control del brillo de la pantalla. |
TYPE_LINEAR_ACCELERATION |
Software o hardware | Mide la fuerza de aceleración en m/s2 que es se aplica a un dispositivo en los tres ejes físicos (x, y, y z), sin incluir la fuerza de gravedad. | Supervisión de la aceleración a lo largo de un solo eje. |
TYPE_MAGNETIC_FIELD |
Hardware | Mide el campo geomagnético ambiental de los tres ejes físicos (x, y, z) en μT. | Creación de una brújula. |
TYPE_ORIENTATION |
Software | Mide los grados de rotación de un dispositivo alrededor de los tres ejes físicos (x, y, z).
A partir del nivel de API 3, puedes obtener la matriz de inclinación y la matriz de rotación para
un dispositivo que usa el sensor de gravedad y el sensor de campo geomagnético junto con
getRotationMatrix()
. |
Determinación de la posición del dispositivo. |
TYPE_PRESSURE |
Hardware | Mide la presión del aire del ambiente en hPa o mbar. | Supervisa los cambios de la presión del aire. |
TYPE_PROXIMITY |
Hardware | Mide en cm la proximidad de un objeto en relación con la pantalla de visualización de un dispositivo. Este sensor suele usarse para determinar si un teléfono celular se está sosteniendo el oído de una persona. | Posición del teléfono durante una llamada. |
TYPE_RELATIVE_HUMIDITY |
Hardware | Mide en valor de porcentaje (%) la humedad relativa del ambiente. | Supervisa el punto de condensación, la humedad absoluta y la humedad relativa. |
TYPE_ROTATION_VECTOR |
Software o hardware | Mide la orientación de un dispositivo al proporcionar los tres elementos de la vector de rotación. | Detección de movimiento y detección de rotación. |
TYPE_TEMPERATURE |
Hardware | Mide la temperatura del dispositivo en grados Celsius (°C). Este sensor
varía según el dispositivo y
este sensor se reemplazó por el sensor TYPE_AMBIENT_TEMPERATURE en
Nivel de API 14 |
Supervisión de temperaturas. |
Marco de trabajo del sensor
Puedes acceder a estos sensores y adquirir datos del sensor sin procesar con el marco de trabajo del sensor de Android.
El framework del sensor es parte del paquete android.hardware
e incluye lo siguiente:
clases e interfaces:
SensorManager
- Puedes usar esta clase para crear una instancia del servicio del sensor. Esta clase proporciona varios métodos para acceder a sensores y enumerarlos, registrar y cancelar el registro de eventos de sensores objetos de escucha y adquirir información de orientación. Esta clase también proporciona varias constantes del sensor que se usan para informar la precisión de los sensores, establecer tasas de adquisición de datos y calibrar sensores.
Sensor
- Puedes usar esta clase para crear una instancia de un sensor específico. Esta clase proporciona varias que te permiten determinar la capacidad de un sensor.
SensorEvent
- El sistema usa esta clase para crear un objeto de evento de sensor, que proporciona información sobre un sensor de estado. Un objeto de evento de sensor incluye la siguiente información: los datos sin procesar del sensor, el tipo de sensor que generó el evento, la exactitud de los datos y la marca de tiempo del evento.
SensorEventListener
- Puedes usar esta interfaz para crear dos métodos de devolución de llamada que reciban notificaciones (sensor eventos) cuando cambian los valores del sensor o la precisión del sensor.
En una aplicación típica, estas API relacionadas con sensores se usan para realizar dos tareas básicas:
- Identificación de sensores y capacidades de sensores
Identificar los sensores y las capacidades de los sensores en el tiempo de ejecución es útil si tu aplicación tiene funciones que dependen de capacidades o tipos de sensores específicos. Por ejemplo, es posible que quieras identificar todos los sensores que están presentes en un dispositivo e inhabilitar las funciones de la aplicación que dependen de sensores que no están presentes. Del mismo modo, quizás quieras identificar todos los sensores de un tipo determinado para que puedas elegir la implementación del sensor que tenga el rendimiento óptimo para tu aplicación.
- Supervisa los eventos del sensor
La supervisión de los eventos del sensor es la manera en la que adquieres los datos sin procesar del sensor. Un evento de sensor se produce cada vez un sensor detecta un cambio en los parámetros que está midiendo. Un evento de sensor te proporciona con cuatro datos: el nombre del sensor que activó el evento, el marca de tiempo del evento, la exactitud del evento y los datos sin procesar del sensor que activaron el evento.
Disponibilidad del sensor
Si bien la disponibilidad del sensor varía de un dispositivo a otro, también puede variar entre los dispositivos Android versiones. Esto se debe a que los sensores de Android se introdujeron en el transcurso de varias de la plataforma. Por ejemplo, muchos sensores se introdujeron en Android 1.5 (nivel de API 3), pero algunos no se implementaron y no pudieron usarse hasta Android 2.3 (nivel de API 9). Del mismo modo, se introdujeron varios sensores en Android 2.3 (nivel de API 9) y Android 4.0 (nivel de API 14). Dos sensores dejaron de estar disponibles y fueron reemplazados por sensores más nuevos y mejores.
En la tabla 2, se resume la disponibilidad de los sensores en cada una de las plataformas. Solo cuatro plataformas se enumeran porque esas son las plataformas que involucraron cambios en los sensores. Los sensores que son siguen disponibles en plataformas posteriores (siempre y cuando está presente en un dispositivo), lo que cumple con la política de compatibilidad con versiones posteriores de Android.
Sensor | Android 4.0 (API nivel 14) |
Android 2.3 (API nivel 9) |
Android 2.2 (API nivel 8) |
Android 1.5 (API nivel 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
Sí | Sí | Sí | Sí |
TYPE_AMBIENT_TEMPERATURE |
Sí | n/a | n/a | N/A |
TYPE_GRAVITY |
Sí | Sí | n/a | N/A |
TYPE_GYROSCOPE |
Sí | Sí | n/a1 | n/a1 |
TYPE_LIGHT |
Sí | Sí | Sí | Sí |
TYPE_LINEAR_ACCELERATION |
Sí | Sí | n/a | N/A |
TYPE_MAGNETIC_FIELD |
Sí | Sí | Sí | Sí |
TYPE_ORIENTATION |
Sí2 | Sí2 | Sí2 | Sí |
TYPE_PRESSURE |
Sí | Sí | n/a1 | n/a1 |
TYPE_PROXIMITY |
Sí | Sí | Sí | Sí |
TYPE_RELATIVE_HUMIDITY |
Sí | n/a | n/a | N/A |
TYPE_ROTATION_VECTOR |
Sí | Sí | n/a | N/A |
TYPE_TEMPERATURE |
Sí2 | Sí | Sí | Sí |
1 Este tipo de sensor se agregó en Android 1.5 (nivel de API 3) pero no estuvo disponible para Android 2.3 (nivel de API 9).
2 Este sensor está disponible, pero se ha obsoleto.
Identificación de sensores y capacidades de sensores
El framework del sensor de Android brinda varios métodos que te permiten determinar con facilidad tiempo de ejecución qué sensores están en un dispositivo. La API también proporciona métodos que te permiten determinar la capacidades de cada sensor, como su rango máximo, su resolución y su potencia y los requisitos de cumplimiento.
Para identificar los sensores que están en un dispositivo, primero debes obtener una referencia al sensor
servicio. Para ello, crea una instancia de la clase SensorManager
de la siguiente manera:
llamando al método getSystemService()
y pasando
en el argumento SENSOR_SERVICE
. Por ejemplo:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Luego, puedes obtener una lista de todos los sensores de un dispositivo llamando al
getSensorList()
y el uso de la constante TYPE_ALL
. Por ejemplo:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Si deseas enumerar todos los sensores de un tipo determinado, puedes usar otra constante en lugar de
TYPE_ALL
, como TYPE_GYROSCOPE
,
TYPE_LINEAR_ACCELERATION
o
TYPE_GRAVITY
También puedes determinar si un tipo específico de sensor existe en un dispositivo usando el método getDefaultSensor()
y pasando el tipo.
constante para un sensor específico. Si un dispositivo tiene más de un sensor de un tipo determinado, uno de los
sensores deben designarse como el sensor predeterminado. Si no existe un sensor predeterminado para un
de sensor, la llamada al método muestra un valor nulo, lo que significa que el dispositivo no tiene ese tipo de
sensor. Por ejemplo, en el siguiente código, se comprueba si hay un magnetómetro en un dispositivo:
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. }
Nota: Android no requiere que los fabricantes de dispositivos creen tipos específicos de sensores en sus dispositivos con Android, por lo que pueden tener una amplia gama de configuraciones de sensores.
Además de enumerar los sensores que están en un dispositivo, puedes usar los métodos públicos de la
Sensor
para determinar las capacidades y los atributos de una
sensores. Esto es útil si quieres que tu aplicación se comporte de forma diferente según los sensores o
de sensores están disponibles en un dispositivo. Por ejemplo, puedes usar getResolution()
y getMaximumRange()
.
para obtener la resolución de un sensor y el rango máximo de medición. También puedes usar
getPower()
para obtener los requisitos de alimentación de un sensor.
Dos de los métodos públicos son particularmente útiles si deseas optimizar tu aplicación para
sensores de distintos fabricantes
o diferentes versiones de un sensor. Por ejemplo, si tu aplicación
para supervisar gestos del usuario como inclinación y agitación, puedes crear un conjunto de
reglas y optimizaciones para dispositivos más nuevos que tienen un sensor de gravedad específico de un proveedor y otro
de filtros de datos y optimizaciones para dispositivos que no tienen sensor de gravedad y tienen
solo un acelerómetro. En la siguiente muestra de código, se indica cómo puedes usar los métodos getVendor()
y getVersion()
para hacer lo siguiente:
esto. En esta muestra, buscamos un sensor de gravedad que indique a Google LLC como proveedor y
tiene un número de versión de 3. Si ese sensor no está presente en el dispositivo, intentamos usar el
acelerómetro.
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. } }
Otro método útil es el método getMinDelay()
,
que muestra el intervalo de tiempo mínimo (en microsegundos) que un sensor puede usar para detectar datos Cualquier sensor
que muestra un valor distinto de cero para el getMinDelay()
es un método de transmisión
sensor. Los sensores de transmisión detectan datos a intervalos regulares y se introdujeron en Android 2.3 (API
nivel 9). Si un sensor muestra cero cuando llamas al método getMinDelay()
, significa que el valor
no es de transmisión porque informa datos solo cuando hay un cambio en la
los parámetros que detecta.
El método getMinDelay()
es útil porque te permite
a determinar la tasa máxima
en la que un sensor puede adquirir datos. Si ciertas funciones de tu aplicación requieren una alta cantidad de datos
de adquisición de datos o un sensor de transmisión, puedes usar este método para determinar si un sensor
cumpla con esos requisitos y, luego, habilitará o inhabilitará las funciones relevantes en tu aplicación
según corresponda.
Precaución: La tasa máxima de adquisición de datos de un sensor no es necesariamente la velocidad a la que el marco de trabajo del sensor entrega los datos del sensor a tu aplicación. El el framework del sensor informa los datos a través de los eventos del sensor, y varios factores influyen en la velocidad a la que tu aplicación recibe eventos de sensores. Para obtener más información, consulta Cómo supervisar los eventos del sensor.
Cómo supervisar los eventos del sensor
Para supervisar los datos sin procesar del sensor, debes implementar dos métodos de devolución de llamada expuestos a través de
la interfaz SensorEventListener
: onAccuracyChanged()
y onSensorChanged()
El sistema Android llama
estos métodos en las siguientes situaciones:
- La precisión de un sensor cambia.
En este caso, el sistema invoca el método
onAccuracyChanged()
, lo que proporciona una referencia al objetoSensor
que cambió y al nueva precisión del sensor. La exactitud se representa con una de las cuatro constantes de estado:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, oSENSOR_STATUS_UNRELIABLE
. - Un sensor informa un valor nuevo.
En este caso, el sistema invoca el método
onSensorChanged()
, que te proporciona Un objetoSensorEvent
Un objetoSensorEvent
contiene información sobre los nuevos datos del sensor, como la precisión de los datos, la de datos que generó los datos, la marca de tiempo en la que se generaron y el nuevo datos que registró el sensor.
En el siguiente código, se muestra cómo usar el método onSensorChanged()
para supervisar datos de
el sensor de luz. En este ejemplo, se muestran los datos sin procesar del sensor en un TextView
.
es decir,
definido en el archivo main.xml como 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); } }
En este ejemplo, el retraso de los datos predeterminado (SENSOR_DELAY_NORMAL
) se especifica cuando se invoca el método registerListener()
. Los datos
El retraso (o tasa de muestreo) controla el intervalo en el que se envían los eventos del sensor a tu aplicación.
con el método de devolución de llamada onSensorChanged()
. Predeterminado
el retraso de datos es adecuado para la supervisión
cambia la orientación de la pantalla con un retraso de 200,000 microsegundos. Puedes especificar
las demoras en los datos, como SENSOR_DELAY_GAME
(20,000 microsegundos
retraso), SENSOR_DELAY_UI
(retraso de 60,000 microsegundos) o SENSOR_DELAY_FASTEST
(retraso de 0 microsegundos). A partir de Android 3.0 (API
nivel 11), también puedes especificar el retraso como un valor absoluto (en microsegundos).
El retraso que especificas es solo un retraso sugerido. El sistema Android y otras aplicaciones puede alterar este retraso. Como práctica recomendada, debes especificar el mayor retraso posible el sistema suele utilizar un retraso menor que el especificado (es decir, debes elegir la la tasa de muestreo más lenta que aún satisface las necesidades de tu aplicación). El uso de un retraso mayor impone una carga menor en el procesador y, por lo tanto, usa menos energía.
No existe un método público para determinar la velocidad a la que el marco de trabajo del sensor envía contenido. eventos de sensores a tu aplicación; pero puedes usar las marcas de tiempo asociadas sensor para calcular la tasa de muestreo de varios eventos. No deberías tener que cambiar la tasa de muestreo (retraso) una vez que la definas. Si por alguna razón necesitas cambiar el retraso, debes cancelar el registro y volver a registrar el objeto de escucha del sensor.
También es importante tener en cuenta que este ejemplo usa onResume()
y
Métodos de devolución de llamada onPause()
para registrar y cancelar el registro del evento del sensor
objeto de escucha. Como práctica recomendada, siempre debes
inhabilitar los sensores que no necesitas, en especial
se pausó la actividad. De lo contrario, es posible que la batería se agote en unas horas, ya que algunos sensores
tienen requisitos de energía considerables y pueden agotar la batería rápidamente. El sistema
no inhabilitará los sensores automáticamente cuando se apague la pantalla.
Cómo controlar diferentes configuraciones del sensor
Android no especifica una configuración de sensor estándar para dispositivos, lo que significa que los fabricantes de dispositivos pueden incorporar cualquier configuración de sensor que deseen a su Dispositivos con Android. Como resultado, los dispositivos pueden incluir una variedad de sensores en una amplia gama de configuraciones. Si tu aplicación depende de un tipo específico de sensor, debes asegurarte de que el en un dispositivo para que la app pueda ejecutarse correctamente.
Tienes dos opciones para garantizar que un sensor determinado esté presente en un dispositivo:
- Detecta sensores en el tiempo de ejecución y habilita o inhabilita las características de la aplicación según corresponda.
- Usa los filtros de Google Play para apuntar a dispositivos con configuraciones de sensor específicas.
En las siguientes secciones, se analiza cada una de las opciones.
Detecta los sensores en el tiempo de ejecución
Si tu aplicación usa un tipo específico de sensor, pero no depende de él, puedes usar el marco de trabajo del sensor para detectar el sensor en el tiempo de ejecución y luego inhabilitar o habilitar las funciones de la aplicación según corresponda. Por ejemplo, una aplicación de navegación podría usar el sensor de temperatura, sensor de presión, sensor GPS y sensor de campo geomagnético para mostrar la temperatura, los sensores barométricos presión, ubicación y dirección de la brújula. Si un dispositivo no tiene sensor de presión, puedes usar para detectar la ausencia del sensor de presión en el tiempo de ejecución y, luego, inhabilitar el de la IU de tu aplicación que muestra la presión. Por ejemplo, las siguientes verificaciones de código si un dispositivo tiene un sensor de presión:
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. }
Usa los filtros de Google Play para orientar configuraciones específicas de sensores
Si estás publicando tu aplicación en Google Play, puedes usar la
<uses-feature>
en tu archivo de manifiesto para filtrar tu aplicación y excluir dispositivos que no
tener la configuración del sensor adecuada para tu aplicación. El
El elemento <uses-feature>
tiene varios descriptores de hardware que te permiten filtrar
aplicaciones basadas en la presencia de sensores específicos. Entre los sensores que puedes enumerar, se incluyen los siguientes:
acelerómetro, barómetro, brújula (campo geomagnético), giroscopio, luz y proximidad. El
A continuación, se muestra un ejemplo de una entrada de manifiesto que filtra las apps que no tienen acelerómetro:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Si agregas este elemento y descriptor al manifiesto de tu aplicación, los usuarios verán tu en Google Play solo si su dispositivo cuenta con un acelerómetro.
Debes establecer el descriptor en android:required="true"
solo si tu aplicación
depende completamente de un sensor específico. Si tu aplicación usa un sensor para alguna funcionalidad, pero
todavía se ejecuta sin el sensor, deberías indicar el sensor en el <uses-feature>
pero establece el descriptor en android:required="false"
. Esto ayuda a garantizar que
Los dispositivos pueden instalar tu app incluso si no tienen ese sensor en particular. Este también es un
práctica recomendada de gestión de proyectos que te ayude a realizar un seguimiento de las funciones que usa tu aplicación.
Ten en cuenta que, si tu aplicación usa un sensor en particular, pero aún se ejecuta sin el sensor,
debes detectar el sensor en el tiempo de ejecución e inhabilitar o habilitar las funciones de la aplicación
lo que sea apropiado.
Sistema de coordenadas del sensor
En general, el marco de trabajo del sensor utiliza un sistema de coordenadas estándar de 3 ejes para expresar valores de datos. Para la mayoría de los sensores, el sistema de coordenadas se define en relación con la pantalla del dispositivo cuando este se mantiene en su orientación predeterminada (consulta la figura 1). Cuando un dispositivo se mantiene en su orientación predeterminada, el eje X es horizontal y apunta hacia la derecha, el eje Y es vertical y apunta hacia arriba, y el eje Z apunta hacia el exterior de la cara de la pantalla. En este sistema, las coordenadas detrás de la pantalla tienen valores Z negativos. Los siguientes sensores utilizan este sistema de coordenadas:
El punto más importante que hay que entender sobre este sistema de coordenadas es que los ejes se intercambia cuando cambia la orientación de la pantalla, es decir, el sistema de coordenadas del sensor nunca cambia cuando el dispositivo se mueve. Este comportamiento es el mismo que el de OpenGL de coordenadas.
Otro punto a entender es que tu aplicación no debe suponer que el estado La orientación (predeterminada) es vertical. La orientación natural de muchos dispositivos tablet es horizontal. Y el sistema de coordenadas del sensor siempre se basa en la orientación natural de un dispositivo.
Por último, si tu aplicación hace coincidir los datos del sensor con la visualización en pantalla, debes usar el
getRotation()
para determinar la rotación de la pantalla y, luego, usa el
Método remapCoordinateSystem()
para asignar
de las coordenadas del sensor
a las de la pantalla. Debes hacer esto incluso si el manifiesto especifica
pantalla solo vertical.
Nota: Algunos sensores y métodos usan un sistema de coordenadas que
en relación con el marco de referencia del mundo (a diferencia del marco de referencia del dispositivo). Estos
los sensores y métodos devuelven datos que representan el movimiento del dispositivo o su posición relativa al
la Tierra. Para obtener más información, consulta el método getOrientation()
, el método getRotationMatrix()
y la orientación
Sensor y Vector de rotación
Sensor.
Límite de frecuencia del sensor
Para proteger información potencialmente sensible sobre los usuarios si tu app se segmenta En Android 12 (nivel de API 31) o versiones posteriores, el sistema establece un límite en la actualización velocidad de datos de ciertos sensores de movimiento y de posición. Estos datos incluye valores registrados por la configuración acelerómetro, giroscopio y campo geomagnético sensor.
El límite de frecuencia de actualización depende de la manera en que accedes a los datos del sensor:
- Si llamas al
registerListener()
para supervisar los eventos del sensor, la tasa de muestreo del sensor es limitado a 200 Hz. Esto se aplica a todas las variantes sobrecargadas de laregisterListener()
. - Si usas la clase
SensorDirectChannel
, la tasa de muestreo del sensor se limita aRATE_NORMAL
, que suele ser, aproximadamente, 50 Hz.
Si tu app necesita recopilar datos del sensor de movimiento con una frecuencia mayor, debes
declarar
HIGH_SAMPLING_RATE_SENSORS
permiso, como se muestra en el siguiente fragmento de código. De lo contrario, si la app intenta
para recopilar datos del sensor de movimiento
a una velocidad mayor sin declarar este permiso
se produce una SecurityException
.
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Prácticas recomendadas para acceder a los sensores y usarlos
Cuando diseñes la implementación del sensor, asegúrate de seguir las pautas que se analizan en esta sección. Estos lineamientos son prácticas recomendadas para cualquier persona que use el sensor para acceder a sensores y adquirir datos de sensores.
Recopila solo datos de los sensores en segundo plano
En dispositivos con Android 9 (nivel de API 28) o versiones posteriores, las apps que se ejecutan en la en segundo plano tienen las siguientes restricciones:
- Los sensores que usan continuo modo de generación de informes, como acelerómetros y giroscopios, no reciban eventos.
- Los sensores que usan en caso de cambio o una sola vez los modos de generación de informes no reciben eventos.
Dadas estas restricciones, es mejor detectar los eventos de sensores cuando tu aplicación está en primer plano o como parte de una servicio en primer plano.
Cancela el registro de los objetos de escucha de los sensores
Asegúrate de cancelar el registro de los objetos de escucha del sensor cuando termines de usar el sensor o cuando este
se detiene la actividad. Si se registra un objeto de escucha del sensor y se pausa su actividad, el sensor
seguirá adquiriendo datos y usando recursos de la batería, a menos que canceles el registro del sensor. Lo siguiente
El código muestra cómo usar el método onPause()
para cancelar el registro de un objeto de escucha:
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); }
Para obtener más detalles, consulta la información de unregisterListener(SensorEventListener)
.
Haz una prueba con Android Emulator
Android Emulator incluye un conjunto de controles de sensores virtuales que permiten probar sensores, como el acelerómetro, la temperatura ambiente, el magnetómetro, proximidad, luz, etc.
El emulador usa una conexión con un dispositivo Android que ejecuta la SdkControllerSensor . Ten en cuenta que esta app solo está disponible en dispositivos con Android 4.0 (API nivel 14) o una versión posterior. (Si el dispositivo ejecuta Android 4.0, debe tener Se instaló la revisión 2). La aplicación SdkControllerSensor supervisa los cambios en los sensores en el dispositivo y los transmite al emulador. El emulador es luego se transforma en función de los nuevos valores que recibe de los sensores de tu dispositivo.
Puedes ver el código fuente de la app SdkControllerSensor en la siguiente ubicación:
$ your-android-sdk-directory/tools/apps/SdkController
Para transferir datos entre tu dispositivo y el emulador, sigue estos pasos: pasos:
- Comprueba que el USB esté habilitada la depuración en tu dispositivo.
- Conecta el dispositivo a la máquina de desarrollo con un cable USB.
- Inicia la app SdkControllerSensor en tu dispositivo.
- En la app, selecciona los sensores que quieras emular.
Ejecuta el siguiente comando
adb
:- Inicia el emulador. Ahora deberías poder aplicar transformaciones el emulador moviendo el dispositivo.
$ adb forward tcp:1968 tcp:1968
Nota: Si los movimientos que hagas en tu
dispositivo físico no transforman el emulador, intenta ejecutar el
adb
del paso 5 nuevamente.
Para obtener más información, consulta el artículo Android Guía del emulador
No bloquees el método onSensorChanged()
Los datos del sensor pueden cambiar a una velocidad alta, lo que significa que es posible que el sistema llame al método onSensorChanged(SensorEvent)
con bastante frecuencia. Como práctica recomendada,
debe hacer lo menos posible dentro del método onSensorChanged(SensorEvent)
para no bloquearlo. Si el
aplicación requiere que realices algún filtrado de datos o reduzcas los datos de sensores, debes realizar
que funcionan fuera del método onSensorChanged(SensorEvent)
.
Evita usar métodos o tipos de sensores obsoletos
Varios métodos y constantes ya no están disponibles.
En particular, el objeto TYPE_ORIENTATION
sensor de datos quedó obsoleto. Para obtener datos de orientación, debes utilizar el método getOrientation()
en su lugar. Del mismo modo, el
El tipo de sensor TYPE_TEMPERATURE
dejó de estar disponible. Deberías usar
el tipo de sensor TYPE_AMBIENT_TEMPERATURE
en los dispositivos
que ejecutan Android 4.0.
Comprueba los sensores antes de usarlos
Siempre comprueba que existe un sensor en un dispositivo antes de intentar obtener datos de él. Lo que no debes hacer suponer que un sensor existe simplemente porque es un sensor de uso frecuente. Los fabricantes de dispositivos son no están obligados a proporcionar sensores particulares en sus dispositivos.
Elige los retrasos del sensor con cuidado
Cuando registres un sensor con el método registerListener()
, asegúrate de elegir un ritmo de entrega adecuado para tu
aplicación o caso de uso. Los sensores pueden proporcionar datos a ritmos muy rápidos. Permitir que el sistema envíe
datos adicionales que no necesitas desperdician recursos del sistema y consumen energía de la batería.