Sensors API es una interfaz de la plataforma Android para acceder a los sensores de hardware del dispositivo. La API proporciona una forma unificada de obtener datos del acelerómetro, giroscopio, magnetómetro, sensor de luz y otros sensores. Según Google, 2026, más del 95% de los dispositivos Android modernos están equipados con al menos tres tipos de sensores, lo que abre amplias oportunidades para desarrollar aplicaciones sensibles al contexto.
Puntos clave
Sensors API es una interfaz de software de Android Framework que proporciona a los desarrolladores acceso a los sensores de hardware del dispositivo móvil. La API ha sido parte del SDK de Android desde la versión 1.0 y está disponible a través del paquete android.hardware. La interfaz abstrae las diferencias entre las implementaciones de sensores de diferentes fabricantes — Qualcomm, MediaTek, Samsung Exynos — y proporciona un modelo unificado para trabajar con sensores.
La API permite tres operaciones clave: obtener una lista de sensores disponibles, registrar oyentes para recibir datos y gestionar la frecuencia de actualización. SensorManager actúa como el punto de acceso central para todas las operaciones. El sistema notifica a la aplicación a través del callback onSensorChanged, pasando un objeto SensorEvent con un arreglo de valores float.
Durante la existencia de Android, la API ha pasado por varias etapas de desarrollo. La versión 2.3 (Gingerbread) introdujo soporte para Batch Processing — agrupación de eventos de sensores para reducir el consumo de energía. Android 4.0 (Ice Cream Sandwich) agregó los sensores virtuales Gravity y Linear Acceleration. A partir de Android 8.0, el sistema restringió el acceso en segundo plano a los sensores para mejorar la privacidad.
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
Log.d("Sensores", "${sensor.name} — ${sensor.type}")
}
No todos los dispositivos tienen el mismo conjunto de sensores. Una aplicación debe verificar la disponibilidad de un sensor específico antes de registrar un oyente. El Emulador de Android solo admite un conjunto limitado de sensores — acelerómetro y magnetómetro. Probar otros sensores requiere un dispositivo físico. A partir de Android 12, las aplicaciones deben declarar el uso de sensores en el manifiesto.
Android clasifica todos los sensores en tres categorías: Motion, Position y Environment. Los sensores Motion incluyen acelerómetro, giroscopio y podómetro. Los sensores Position incluyen magnetómetro y orientación. Los sensores Environment incluyen luz, presión, temperatura y humedad.
| Categoría | Sensores | Tipo (constante) | Físico/Virtual |
|---|---|---|---|
| Motion | Acelerómetro | TYPE_ACCELEROMETER | Físico |
| Motion | Giroscopio | TYPE_GYROSCOPE | Físico |
| Motion | Podómetro | TYPE_STEP_COUNTER | Físico |
| Motion | Gravity | TYPE_GRAVITY | Virtual |
| Position | Magnetómetro | TYPE_MAGNETIC_FIELD | Físico |
| Position | Rotation Vector | TYPE_ROTATION_VECTOR | Virtual |
| Environment | Luz | TYPE_LIGHT | Físico |
| Environment | Presión | TYPE_PRESSURE | Físico |
El acelerómetro mide la aceleración en m/s² a lo largo de tres ejes — X, Y y Z. Los valores incluyen la gravedad (9.8 m/s² a lo largo del eje Z en reposo). El giroscopio mide la velocidad angular en rad/s — la velocidad de rotación del dispositivo alrededor de cada eje. La combinación de estos dos sensores se utiliza en navegación, juegos y aplicaciones de RA.
class SensorActivity : Activity(), SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
textView.text = "X: $x, Y: $y, Z: $z"
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
El magnetómetro (TYPE_MAGNETIC_FIELD) mide el campo magnético en microteslas (µT) a lo largo de tres ejes. Se utiliza como brújula digital — en combinación con el acelerómetro, determina el azimut del dispositivo. Rotation Vector es un sensor virtual que fusiona datos del giroscopio, acelerómetro y magnetómetro para una determinación precisa de la orientación.
El sensor de luz (TYPE_LIGHT) mide el nivel de luz ambiental en lux (lx). Se utiliza para el ajuste automático del brillo de la pantalla. El sensor de presión (TYPE_PRESSURE) mide la presión atmosférica en hectopascales (hPa) — se usa en aplicaciones de navegación para determinar la altitud sobre el nivel del mar.
Sensors API está construido sobre una arquitectura cliente-servidor. La aplicación actúa como cliente y SensorManager como servicio del sistema Android. Cuando la aplicación registra un oyente a través de registerListener, SensorManager se comunica con HAL (Hardware Abstraction Layer) — un controlador de sensor de bajo nivel que se ejecuta a nivel del kernel de Linux.
El controlador HAL recibe datos brutos del chip de hardware, filtra el ruido y los pasa hacia arriba en la pila — a través de SensorService (proceso del sistema) hasta la aplicación. Los datos se pasan como un objeto SensorEvent que contiene un arreglo de valores float values y una marca de tiempo en nanosegundos. La frecuencia de eventos depende del modo de entrega seleccionado.
Al registrar un oyente, el desarrollador especifica el retardo deseado entre eventos usando las constantes SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) y SENSOR_DELAY_FASTEST (0 ms — frecuencia máxima). La frecuencia real puede diferir — el sistema optimiza el consumo de energía.
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
this,
sensor,
SensorManager.SENSOR_DELAY_GAME
)
A partir de Android 2.3, los sensores admiten el modo por lotes — los eventos se acumulan en un búfer FIFO y se entregan en un solo lote. Esto permite que el procesador permanezca más tiempo en modo de suspensión, reduciendo el consumo de energía hasta en un 60%. El tamaño del búfer depende del chip del sensor y se especifica en el campo Sensor.fifoMaxEventCount.
SensorManager es un servicio del sistema disponible a través de getSystemService(Context.SENSOR_SERVICE). Proporciona métodos para obtener una lista de sensores, obtener un sensor predeterminado específico y registrar/cancelar oyentes. SensorManager es un singleton — una única instancia para toda la aplicación.
Antes de usar un sensor, debe verificar su disponibilidad. El método getDefaultSensor(type) devuelve null si el sensor no está presente en el dispositivo. Obtener null sin verificación provocará una NullPointerException al registrar un oyente. El método getSensorList(type) devuelve una lista de todos los sensores.
fun checkSensorAvailability(type: Int): Boolean {
val sensorManager =
getSystemService(Context.SENSOR_SERVICE) as SensorManager
return sensorManager.getDefaultSensor(type) != null
}
// Uso:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
Log.d("Sensor", "Giroscopio disponible")
}
Un oyente se registra a través de registerListener(listener, sensor, delay). Importante: debe cancelar el oyente en el método onPause() mediante unregisterListener(listener). Si no lo hace, la aplicación continuará recibiendo eventos del sensor, agotando la batería incluso en segundo plano. Android 8+ muestra una advertencia en logcat sobre oyentes no cancelados.
El método onAccuracyChanged(sensor, accuracy) se llama cuando cambia la precisión del sensor. Valores: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW y UNRELIABLE. Al recibir UNRELIABLE, los datos del sensor deben ignorarse hasta que se restablezca la precisión. Por ejemplo, el magnetómetro requiere calibración — agitar el dispositivo en forma de ocho.
Veamos ejemplos prácticos de uso de Sensors API en aplicaciones Android con Kotlin. El primer ejemplo — determinar la orientación de la pantalla usando el acelerómetro. El segundo — leer datos del magnetómetro con calibración. El tercero — un detector de pasos usando el podómetro.
Se utiliza una combinación de acelerómetro y magnetómetro para determinar la orientación. El método SensorManager.getRotationMatrix() calcula la matriz de rotación, y getOrientation() extrae los ángulos pitch, roll y azimuth. Azimuth — el ángulo relativo al norte magnético en radianes.
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)
SensorManager.getRotationMatrix(
rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())
El podómetro (TYPE_STEP_COUNTER) devuelve el número total de pasos realizados por el usuario desde el último reinicio del dispositivo. El sensor funciona a nivel de hardware — está activo incluso cuando la aplicación no se está ejecutando. Para obtener los pasos por sesión, debe guardar el valor inicial y calcular la diferencia.
var initialSteps = 0
var isInitialized = false
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
if (!isInitialized) {
initialSteps = event.values[0].toInt()
isInitialized = true
}
val currentSteps = event.values[0].toInt()
val sessionSteps = currentSteps - initialSteps
Log.d("Pasos", "Pasos por sesión: $sessionSteps")
}
}
El sensor de luz permite adaptar la interfaz a las condiciones ambientales. Con poca luz (menos de 10 lx), puede cambiar al modo oscuro. Con luz solar brillante (más de 10000 lx), puede aumentar el contraste. Se utiliza un promedio móvil de los últimos 5 valores para filtrar el ruido.
Android proporciona varios sensores virtuales que no tienen un equivalente directo de hardware. Un sensor virtual calcula sus lecturas basándose en una combinación de sensores físicos. Esto reduce la carga para el desarrollador — el propio sistema implementa algoritmos de fusión de datos.
El sensor Gravity (TYPE_GRAVITY) extrae el componente gravitacional de las lecturas del acelerómetro usando un filtro de paso bajo. Linear Acceleration (TYPE_LINEAR_ACCELERATION), por el contrario, elimina la gravedad y deja solo la aceleración lineal del dispositivo. La suma de Gravity y Linear Acceleration da las lecturas brutas del acelerómetro.
Rotation Vector — el sensor virtual más complejo. Combina datos del giroscopio (cambios de alta frecuencia), acelerómetro (vector de gravedad) y magnetómetro (orientación relativa al norte). El resultado es un cuaternión que describe la orientación absoluta del dispositivo en el espacio. Se utiliza en aplicaciones de RA y cascos de VR.
Game Rotation Vector — una versión simplificada de Rotation Vector sin usar el magnetómetro. Esto proporciona una menor precisión de azimut, pero una mayor frecuencia de actualización y estabilidad. Se recomienda para juegos donde la baja latencia es importante, no la orientación absoluta relativa al norte.
Los sensores se encuentran entre los componentes del dispositivo que más energía consumen. El acelerómetro y el giroscopio a máxima frecuencia de muestreo pueden agotar la batería en 3–4 horas de funcionamiento continuo. Optimizar el uso de sensores es una tarea crítica para cualquier aplicación que utilice Sensors API.
No use SENSOR_DELAY_FASTEST innecesariamente. Para animaciones de UI, es suficiente SENSOR_DELAY_UI (60 ms). Para detección de orientación de pantalla — SENSOR_DELAY_NORMAL (200 ms). Cuanto mayor sea la frecuencia, más tiempo pasa el procesador en estado activo. La diferencia entre NORMAL y FASTEST es de hasta 10x en consumo de energía.
A partir de Android 8.0 (API 26), las aplicaciones en segundo plano reciben eventos de sensores con frecuencia reducida. En Android 12+, el acceso en segundo plano a sensores Motion y Position requiere el permiso BODY_SENSORS_BACKGROUND. Cancele el oyente cuando la aplicación pase a segundo plano — esto extiende la vida útil de la batería del dispositivo.
Use el procesamiento por lotes a través del método registerListener(listener, sensor, delay, maxReportLatencyUs). El parámetro maxReportLatencyUs establece la latencia máxima de entrega de eventos en microsegundos. Con un valor de 1000000 (1 segundo), los eventos se acumulan en el búfer FIFO del sensor y se entregan una vez por segundo — el procesador se despierta con menos frecuencia.
Preguntas frecuentes
El conjunto mínimo es un acelerómetro y un magnetómetro. Estos dos sensores están presentes en más del 95% de los dispositivos. Giroscopio, sensor de luz y sensor de proximidad — en el 70–80% de los modelos modernos. Otros sensores (presión, temperatura, humedad, podómetro) son menos comunes y dependen de la categoría de precio del dispositivo.
TYPE_ACCELEROMETER devuelve la aceleración total incluida la gravedad (9.8 m/s²). TYPE_LINEAR_ACCELERATION devuelve la aceleración excluyendo la gravedad — solo la aceleración del movimiento del dispositivo. Si el dispositivo está quieto, el acelerómetro mostrará 9.8 m/s² a lo largo del eje Z, mientras que Linear Acceleration mostrará 0 en todos los ejes.
Use getPackageManager().hasSystemFeature() con las constantes apropiadas: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY y otras. Una forma alternativa es llamar a getDefaultSensor(type) y verificar si el resultado es null. El primer método es preferible para la verificación durante la inicialización.
Los datos brutos del sensor contienen ruido. Para suavizarlos, use un filtro de paso bajo: newValue = alpha * rawValue + (1 — alpha) * previousValue. Un coeficiente alpha de 0.1–0.3 proporciona un buen equilibrio entre capacidad de respuesta y suavidad. Para el giroscopio, también se aplica un filtro de paso alto para eliminar la deriva del cero.
Sí, pero con limitaciones. A partir de Android 8.0, la frecuencia de eventos del sensor se reduce para aplicaciones en segundo plano. A partir de Android 12, se requiere el permiso BODY_SENSORS_BACKGROUND para acceder a sensores en segundo plano. Para trabajar en segundo plano, se recomienda usar un Foreground Service con una notificación.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también