En esta entrada veremos unos de los componentes fundamentales que podemos encontrar en cualquier dispositivo Android relativamente reciente y se trata de un sensor que permite medir la aceleración del dispositivo: el acelerómetro.
El acelerómetro en Android se mide en base a los tres ejes conocidos (X,Y y Z); cada uno de ellos puede ser accedido a través de la clase SensorManager.
Método Moderno con Jetpack Compose
Con la llegada de Jetpack Compose, la forma de construir interfaces de usuario en Android ha cambiado significativamente. Aunque la lógica para acceder al sensor del acelerómetro es la misma (usando SensorManager), la forma en que gestionamos el estado y actualizamos la UI es diferente.
Ya no es necesario implementar SensorEventListener directamente en una Activity. En su lugar, podemos crear un composable que se encargue de registrar y escuchar los cambios del sensor.
La forma moderna de agregar librerías es usando un gestor de dependencias como Gradle. Las referencias a las librerías ya no se añaden manualmente, sino que se declaran en un fichero de configuración. Tu fichero build.gradle.kts (o build.gradle) del módulo de la app debería incluir las dependencias de Compose:
dependencies {
def composeBom = platform("androidx.compose:compose-bom:2024.01.00")
implementation composeBom
androidTestImplementation composeBom
implementation "androidx.activity:activity-compose:1.8.2"
implementation "androidx.compose.material3:material3"
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.ui:ui-tooling-preview"
debugImplementation "androidx.compose.ui:ui-tooling"
}
A continuación, un ejemplo de cómo leer los datos del acelerómetro en un Composable:
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
@Composable
fun AccelerometerData(): Triple <Float, Float, Float> {
val context = LocalContext.current
var sensorData by remember { mutableStateOf(Triple(0f, 0f, 0f)) }
DisposableEffect(Unit) {
val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
val sensorEventListener = object : SensorEventListener {
override fun onSensorChanged(event: SensorEvent?) {
if (event?.sensor?.type == Sensor.TYPE_ACCELEROMETER) {
sensorData = Triple(event.values[0], event.values[1], event.values[2])
}
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
// No es necesario para este ejemplo
}
}
sensorManager.registerListener(
sensorEventListener,
accelerometer,
SensorManager.SENSOR_DELAY_NORMAL
)
onDispose {
sensorManager.unregisterListener(sensorEventListener)
}
}
return sensorData
}
// En tu UI puedes usarlo así:
@Composable
fun MyScreen() {
val (x, y, z) = AccelerometerData()
Text(text = "X: $x, Y: $y, Z: $z")
}
En este ejemplo:
- Usamos
LocalContext.currentpara obtener el contexto actual dentro de un Composable. rememberymutableStateOfse usan para guardar el estado de los valores del sensor. Cuando este estado cambia, Compose automáticamente redibuja la UI.DisposableEffectes un efecto lateral de Compose que nos permite registrar elSensorEventListenercuando el composable entra en la composición y desregistrarlo cuando sale, evitando fugas de memoria.
Este enfoque es más declarativo y se integra mejor con el ciclo de vida de los componentes de Compose, representando la forma moderna de trabajar con sensores en Android.
Nota sobre el enfoque Legacy
El siguiente método describe la forma tradicional (Legacy) de interactuar con el acelerómetro en Android usando Vistas (XML y Activities). Si estás empezando un nuevo proyecto, te recomendamos usar Jetpack Compose, el framework de UI moderno de Android, que se describe más abajo.
Empezando con la clase de SensorManager en Android (Método Legacy)
Debemos de implementar la clase de SensorEventListener en nuestra actividad:
public class MainActivity extends Activity implements SensorEventListenerUna vez que implementamos la interfaz anterior debemos de sobrecargar los métodos:
@Override public void onSensorChanged(SensorEvent event) { } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }Solicitando acceso al acelerómetro
Lo siguiente que debemos hacer es solicitar acceso al acelerómetro del dispositivo; y esto lo hacemos a través del objeto SensorManager de la siguiente manera:
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);Obtenemos el servicio del sistema a través del objeto getSystemService pasando como parámetro el nombre del servicio al que queremos acceder.
Obteniendo el acelerómetro del sistema
De la lista de sensores de vuelta en la consulta anterior, verificamos si hay algun sensor de tipo acelerómetro disponible; para ello se emplea la siguiente línea de código:
sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).size()Registrando el evento "Escuchador" o Listener del acelerómetro
Una vez que hayamos verificado que el dispositivo cuenta con al menos un sensor de tipo acelerómetro podemos registrar el evento listener o escuchador:
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_FASTEST)
Pasamos como parámetro una instancia de la actividad, el acelerómetro y la tasa de refrescamiento, la cual puede ser:
- SENSOR_DELAY_FASTEST
- SENSOR_DELAY_NORMAL
- SENSOR_DELAY_GAME
- SENSOR_DELAY_UI
Lo único que varía entre ellas es la tasa de refrescamiento del acelerómetro.
Registrando el evento "Escuchador" o Listener
El método onSensorChanged se activa cada vez que el sistema detecta un cambio en la aceleración del dispositivo:
@Override public void onSensorChanged(SensorEvent event) { sensor = ""; sensor = "x: " + event.values[0] + " y: " + event.values[1] + " z: " + event.values[2]; }Con el parámetro SensorEvent podemos tener entre varios datos, las coordenadas que el sistema usa en las rotaciones a través de los ejes X,Y y Z como vimos en el código anterior.
Puedes encontrar una aplicación funcional que ejemplifica el funcionamiento de los códigos vistos anteriormente en nuestro repositorio de GIT:
Captura de pantalla de la aplicación:

Acepto recibir anuncios de interes sobre este Blog.
En esta entrada veremos unos de los componentes fundamentales en todo dispositivo Android y se trata de un sensor que permite medir la aceleración del dispositivo: el acelerómetro.