Está en la página 1de 11

CURSO DE DESARROLLO DE APLICACIONES ANDROID

Tema 17

Sensores
TEMA 17. SENSORES

Introducción

La mayor parte de los dispositivos con Android instalado incluye diversos tipos de sensores que
son capaces de proveer datos de orientación y de movimiento, así como de diferentes
parámetros medioambientales, con una gran precisión y exactitud.

La plataforma Android soporta tres grandes categorías de sensores:

• Sensores de movimiento, que miden las diversas fuerzas de aceleración y rotación a lo


largo de los tres ejes espaciales. Son los acelerómetros, los sensores de gravedad, los
giróscopos y los sensores rotacionales.
• Sensores de entorno, que miden diversos parámetros medioambientales como la
temperatura ambiente, la presión atmosférica, la cantidad de luz y la humedad. Son
los barómetros, los termómetros, y los fotómetros.
• Sensores de posición, que miden la posición física del dispositivo. Son los sensores de
orientación y los magnetómetros.

A través de la API de Android, se puede acceder a cualquier sensor disponible en el dispositivo


para adquirir los datos en bruto que mide dicho sensor. Existen diversas clases e interfaces que
permiten realizar diversas tareas relacionadas con la gestión de los sensores como, por
ejemplo, determinar qué sensores están disponibles en el dispositivo, cuáles son sus
capacidades individuales (rango de medida, resolución, nombre del fabricante, requisitos de
consumo de energía), adquirir los datos en bruto, definir la frecuencia de obtención de nuevos
datos, y registrar listeners para monitorizar los cambios que sufran los sensores.

La API de Android no solo provee acceso a sensores basados en hardware, físicos, sino que
también provee acceso a sensores basados únicamente en software. Los sensores basados en
hardware son componentes físicos incluidos en el dispositivo que derivan sus datos de
mediciones directas de ciertas propiedades del entorno, como la aceleración o la fuerza del
campo magnético terrestre. Los sensores basados en software derivan sus datos de uno o más
sensores basados en hardware como, por ejemplo, el sensor de aceleración lineal o el sensor
de gravedad.

Como en general cada dispositivo Android incluye unos u otros tipos de sensores, así como
distinto número de sensores de un mismo tipo, es necesario asegurar la existencia de dichos
sensores antes de intentar utilizarlos.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 2


TEMA 17. SENSORES

Tipos de sensores

SENSOR (Android 4.0)


Tipo Hardware
2
Descripción Mide la fuerza de aceleración en m/s en cada uno de los
TYPE_ACCELEROMETER tres ejes del espacio (x, y, z), incluyendo la fuerza de la
gravedad.
Usos Detección de movimiento (agitar, inclinar, etc.).
Tipo Hardware
TYPE_AMBIENT_TEMPERATURE Descripción Mide la temperatura ambiente en grados Celsius (°C).
Usos Monitorización de la temperatura ambiente.
Tipo Hardware o Software
2
Descripción Mide la fuerza de la gravedad en m/s que afecta a cada
TYPE_GRAVITY
uno de los tres ejes del espacio (x, y, z).
Usos Detección de movimiento (agitar, inclinar, etc.).
Tipo Hardware
Descripción Mide la rotación del dispositivo en rad/s a lo largo de
TYPE_GYROSCOPE
cada uno de los ejes del espacio (x, y, z).
Usos Detección de rotación (giros, torques, etc.).
Tipo Hardware
TYPE_LIGHT Descripción Mide el nivel de luz ambiental (iluminancia) en lx (luxes).
Usos Control del brillo de la pantalla.
Tipo Hardware o Software
2
Descripción Mide la fuerza de aceleración en m/s que afecta a cada
uno de los tres ejes del espacio (x, y, z), excluyendo la
TYPE_LINEAR_ACCELERATION
fuerza de la gravedad.
Usos Monitorización de la aceleración en cada uno de los tres
ejes del espacio de forma independiente.
Tipo Hardware
Descripción Mide la fuerza de campo electromagnético ambiental en
TYPE_MAGNETIC_FIELD cada uno de los tres ejes del espacio (x, y, z) en µT
(microTeslas)
Usos Implementación de brújula.
Tipo Software
Descripción Mide los grados de rotación que el dispositivo realiza en
torno a cada uno de los tres ejes del espacio (x, y, z). Se
puede obtener la matriz de inclinación y la matriz de
TYPE_ORIENTATION
rotación utilizando el sensor de gravedad y el sensor de
campo magnético junto con el método
getRotationMatrix().
Usos Detección de la posición del dispositivo.
Tipo Hardware
Descripción Mide la presión ambiental en mbar (milibares) o hPa
TYPE_PRESSURE
(hectoPascales)
Usos Monitorización de cambios en la presión ambiental.
Tipo Hardware
Descripción Mide la proximidad de un objeto a la pantalla del
TYPE_PROXIMITY
dispositivo en cm.
Usos Posición del teléfono durante una llamada.
Tipo Hardware
TYPE_RELATIVE_HUMIDITY Descripción Mide el porcentaje (%) de humedad relativa ambiental.
Usos Monitorización de punto de rocío y humedad relativa.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 3


TEMA 17. SENSORES

Tipo Hardware o Software


Descripción Mide la orientación del dispositivo proveyendo los tres
TYPE_ROTATION_VECTOR
elementos del vector de rotación del dispositivo.
Usos Detección de movimiento y rotación.
Tipo Hardware
Descripción Mide la temperatura del dispositivo en grados Celsius
(°C). Esta implementación del sensor varía en función del
TYPE_TEMPERATURE dispositivo, por lo que este sensor se deberá sustituir por
TYPE_AMBIENT_TEMPERATURE a partir del nivel de
API 14 .
Usos Monitorización de la temperatura.

Framework Sensor

Para obtener los datos de los sensores, se debe acceder al framework que los gestiona. Dicho
framework forma un conjunto de clases contenidas en el paquete android.hardware:

• SensorManager. Clase encargada de crear una instancia de un servicio sensor que


proporciona diversos métodos para acceder a los sensores a los cuales se está
escuchando o para registrar o cancelar el registro de listeners de eventos de los
sensores. Además, proporciona diversas constantes que son usadas para informar
sobre la precisión de los sensores, para establecer la tasa de adquisición de datos o
para calibrar cada sensor.
• Sensor. Clase usada para crear instancias de un sensor específico. Proporciona varios
métodos que permiten determinar cuáles son las capacidades del sensor.
• SensorEvent. Clase utilizada por el sistema para crear un objeto que encapsula un
información de un evento de un sensor. La información que se incluye en el evento es
el tipo de sensor, los datos en bruto del mismo, la precisión de los datos, y la fecha de
obtención de los mismos.
• SensorEventListener. Interfaz que permite la creación de dos métodos callback para
recibir notificaciones (eventos de sensores) cuando los valores medidos o la precisión
de las medidas de los sensores cambian.

En general, las aplicaciones que utilicen sensores deberán primero identificar qué sensores
están disponibles 1, y cuáles son sus capacidades, para a continuación monitorizar los eventos
enviados desde los sensores.

Cada vez que existe un cambio en uno de los parámetros que esté midiendo un sensor, se
lanzará un evento, el cual proporcionará cuatro bloques de información: nombre del sensor,
momento del evento, precisión del evento y datos en bruto de los parámetros medidos (que
hicieron que se lanzara el evento).

1
El número y tipo de sensores no solo depende del dispositivo sino también de la versión de Android que esté
instalada. En Android 2.3 no existen ni el sensor de temperatura ni el de humedad. En Android 2.2 y versiones
inferiores, no existen, además, los sensores de gravedad, de aceleración lineal, de presión, de rotación, ni el
giróscopo.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 4


TEMA 17. SENSORES

Identificación de sensores y de sus capacidades

Android proporciona un conjunto de clases con métodos que permiten determinar en tiempo
de ejecución qué sensores tiene un dispositivo, y cuáles son sus capacidades, máximo rango,
resolución y requisitos de consumo de energía.

Para identificar qué sensores tiene un dispositivo, será necesario obtener una referencia al
servicio que gestiona los sensores invocando al método de contexto
getSystemService(Context.SENSOR_SERVICE), el cual devolverá una instancia de
SensorManager. Se podrá entonces obtener el listado de sensores invocando
getSensorList(), pasando como parámetro el tipo de listado (todos los sensores o sensores
de un tipo determinado):

private SensorManager mSensorManager;



mSensorManager =
(SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> myDeviceSensors =
mSensorManager.getSensorList(Sensor.TYPE_ALL);

Se puede determinar si un dispositivo posee al menos un sensor de un tipo determinado


invocando al método getDefaultSensor() y pasando como parámetro el tipo de sensor
específico. Si dicho método devuelve null, el dispositivo no tendrá ningún sensor de dicho
tipo. En otro caso, devolverá el Sensor de ese tipo, asignado por defecto.

Por ejemplo, para comprobar si el dispositivo tiene acelerómetro, se implementará un código


similar al siguiente:

private boolean mHasAccelerometer;



if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
// El dispositivo tiene acelerómetro.
mHasAccelerometer = true;
} else {
// El dispositivo no tiene acelerómetro.
mHasAccelerometer = false;
}

Una vez obtenido un Sensor determinado, se puede averiguar su rango de medida y su


resolución a través de sus métodos getMaximumRange() y getResolution(). También se
puede saber cuáles son los requisitos de consumo energético del sensor a través del método
getPower() y cuál es el mínimo intervalo de tiempo (en microsegundos) entre dos medidas
consecutivas del sensor, con el método getMinDelay(). Cualquier sensor que devuelva un
valor distinto de cero a través de este método, es un sensor de medida continua. Este tipo de

CURSO DE DESARROLLO DE APLICACIONES ANDROID 5


TEMA 17. SENSORES

sensores miden en intervalos regulares y fueron introducidos en Android 2.3 (nivel de API 9).
Un sensor devuelve cero a través de este método si solo mide cambios de estado en el
parámetro que mide (como por ejemplo en el caso de ciertos sensores de proximidad).

El método getMinDelay() es también útil para averiguar si un sensor es capaz o no de


adquirir los datos con la velocidad requerida en la aplicación (por ejemplo, en el caso del
sensor de aceleración en determinados juegos), para así habilitarlo o deshabilitarlo.

Otros métodos dan más información del sensor como, por ejemplo, su tipo, su nombre o el
fabricante y la versión del mismo. La información del fabricante y versión del sensor es útil
para poder diferenciar funcionalidades en los dispositivos ya que un sensor de un tipo
concreto puede tener mejores capacidades que otro de ese mismo tipo pero de otro
fabricante o versión.

Se deberá evitar el uso de sensores y métodos del framework de sensores declarados


obsoletos (deprecated). Concretamente, los tipos de sensores TYPE_ORIENTATION y
TYPE_TEMPERATURE han sido declarados obsoletos. Se deberá usar, respectivamente, el
método SensorManager.getOrientation() o el tipo TYPE_AMBIENT_TEMPERATURE (a partir
de Android 4.0).

CURSO DE DESARROLLO DE APLICACIONES ANDROID 6


TEMA 17. SENSORES

Monitorización de eventos de sensores

Para monitorizar los datos en bruto de los sensores es necesario implementar dos métodos
callback expuestos en la interfaz SensorEventListener:

• onSensorChanged(). Método invocado por el sistema cuando el sensor obtiene una


nueva medida. Recibe como parámetro un objeto de tipo SensorEvent que contiene
la información de los nuevos datos obtenidos por el sensor, el momento en el que han
sido obtenidos y la precisión de dichos datos.
• onAccuracyChanged(). Método invocado por el sistema cuando la precisión del
sensor cambia. Recibe como parámetros una referencia del Sensor así como la nueva
precisión del sensor. Las diferentes precisiones están representadas por las cuatro
constantes: SENSOR_STATUS_ACCURACY_LOW, SENSOR_STATUS_ACCURACY_MEDIUM,
SENSOR_STATUS_ACCURACY_HIGH, SENSOR_STATUS_ACCURACY_UNRELIABLE. Este
último valor implica que la precisión del sensor no es fiable, y que necesita ser
calibrado de nuevo.

El siguiente código muestra cómo obtener datos de un sensor tipo acelerómetro, para
mostrarlos en una TextView.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 7


TEMA 17. SENSORES

public class SensorActivityExample extends Activity implements


SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private TextView mTextViewSensorData;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sensor);

mSensorManager =
(SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer =
mSensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER);
mTextViewSensorData =
(TextView) findViewById(R.id.textViewSensorData);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// La precisión del sensor ha cambiado
}

@Override
public void onSensorChanged(SensorEvent event) {

// Hay sensores que devuelven un solo valor en el evento,


// como el sensor de temperatura o el de luz.
// En cambio, muchos otros devuelven tres valores, uno para cada
// eje del espacio (x, y, z), como por ejemplo el acelerómetro o
// el magnetómetro
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];

mTextViewSensorData
.setText("(" + x + ", " + y + ", " + z + ")");
}

@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}

CURSO DE DESARROLLO DE APLICACIONES ANDROID 8


TEMA 17. SENSORES

En el ejemplo, cuando se registra el listener, se especifica un retraso normal


(SENSOR_DELAY_NORMAL) en el envío del evento desde el momento en el que el sensor genera
una nueva muestra de datos (una medida). Este parámetro controla el ritmo al cual se envían
eventos del sensor al método callback onSensorChanged(). El delay por defecto es de 200
microsegundos y es adecuado, por ejemplo, para monitorizar cambios de orientación de
pantalla. Se pueden especificar otros delays: SENSOR_DELAY_GAME (20 microsegundos),
SENSOR_DELAY_UI (60 microsegundos), o SENSOR_DELAY_FASTEST (0 microsegundos). A
partir del nivel de API 11 (Android 3.0), se puede especificar el delay como valor en
microsegundos.

Este delay, no obstante, puede ser modificado por el propio sistema o por otras aplicaciones,
las cuales deberán especificar el delay más largo posible (la tasa de muestreo más lenta
posible) que satisfaga sus necesidades, de modo que se minimice la carga de proceso en la
CPU así como el consumo energético global del dispositivo.

Debido a que no hay garantías de que los eventos se envíen a la aplicación exactamente con el
delay especificado, se deberán usar las marcas de tiempo asociadas a cada SensorEvent para
promediar sobre varios eventos la tasa de muestreo real de los datos del sensor. El delay
especificado no puede ser modificado a no ser que se elimine la suscripción del listener para, a
continuación, registrarlo de nuevo.

Para optimizar recursos, se deberá registrar el listener en el método callback onResume() y se


deberá eliminar la suscripción en el método callback onPause(), ya que el sistema no
deshabilita los sensores cuando se apaga la pantalla del dispositivo. Si no se elimina la
suscripción del listener, el sensor seguirá obteniendo datos, lo cual consumirá la batería del
dispositivo.

Como las tasas de muestreo de datos de sensores son elevadas, el sistema invoca el método
onSensorChanged() con bastante frecuencia, por lo que este método deberá consumir la
mínima cantidad de tiempo posible. Cualquier cálculo o filtrado de los datos deberá realizarse
fuera de este método para evitar que sea bloqueado.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 9


TEMA 17. SENSORES

Gestión óptima de sensores en diferentes dispositivos

Debido a que no existe un estándar en la configuración de los sensores de los diferentes


dispositivos de diferentes fabricantes, cada aplicación deberá asegurar la existencia de los
sensores que necesite, o bien en tiempo de ejecución, o bien utilizando filtros de Google Play
(a través del elemento <uses-feature>, en el manifiesto de la aplicación).

En caso de que la aplicación utilice algún sensor específico como funcionalidad opcional, esta
podrá deshabilitarse en tiempo de ejecución si el sensor no existe en dicho dispositivo.

En cambio, si la aplicación requiere la existencia de cierto sensor de forma obligatoria, se


podrá declarar un filtro en el manifiesto de forma que la aplicación no se muestre en Google
Play en caso de que el dispositivo no tenga el sensor requerido:

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

Aunque no sea necesario, es aconsejable añadir android:required="false" para aquellos


sensores que aportan funcionalidades opcionales en la aplicación de forma que se mantenga
así un control completo de todos los sensores que utiliza la misma.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 10


TEMA 17. SENSORES

Sistemas de coordenadas

El framework de sensores utiliza un sistema de tres coordenadas que representan los tres ejes
del espacio, (x, y, z), para expresar los valores de los sensores de aceleración, gravedad,
giróscopo, aceleración lineal y campo magnético. Cuando un dispositivo es sostenido en su
posición natural, el eje X será horizontal (sentido creciente hacia la derecha), el eje Y será
vertical (sentido creciente ascendente) y el eje Z será perpendicular a la pantalla (sentido
creciente según aumenta la distancia al dispositivo) 2.

Es importante tener en cuenta que cuando cambia la orientación del dispositivo, la orientación
de los ejes( el sistema de coordenadas), no cambia 3. Es decir, el eje X siempre apunta hacia el
Este, el eje Y hacia el Norte y el eje Z es el azimut.

También es importante cuando se procesen los datos de los sensores no asumir que la
orientación natural de un dispositivo es vertical, como ocurre en el caso de las tablets, donde
la orientación natural es horizontal. Por lo tanto, si la aplicación va a ajustar los datos del
sensor al display de la pantalla, se deberá usar el método Display.getRotation() para
obtener la orientación de la pantalla, y entonces utilizar el método
SensorManager.remapCoordinateSystem() para mapear las coordenadas del sensor con las
de la pantalla. Este proceso deberá realizarse incluso si en el manifiesto de la aplicación se ha
especificado display portrait al añadir, a cada elemento <activity > deseado, el atributo
android:screenOrientation="portrait".

2
Salvo en el caso del sensor de orientación y el sensor de rotación, que utilizan el sistema de referencia mundial.
3
Al igual que ocurre con el sistema de coordenadas de OpenGL.

CURSO DE DESARROLLO DE APLICACIONES ANDROID 11

También podría gustarte