Intel Learning Series para desarrolladores para Android*, n.º 4: Sensores de tabletas Android

1. Sensores en tabletas Android con procesador Intel® Atom™

Las tabletas basadas en procesadores Intel Atom admiten una amplia variedad de sensores de hardware. Estos sensores se usan para detectar el movimiento y los cambios de posición, e informar los parámetros de entorno del ambiente. El diagrama de bloques de la Figura 1 muestra una posible configuración de sensores en una tableta Android basada en procesador Intel Atom típica.

Sobre la base de los datos que informan, podemos clasificar los sensores en las clases y tipos que se muestran más abajo, en la Tabla 4.1.

Tabla 4.1    Tipos de sensores que admite la plataforma Android

Sensores de posición
Sensores de posición
Acelerómetro (TYPE_ACCELEROMETER) Mide las aceleraciones del dispositivo en m/s2 Detección de movimiento
Giroscopio (TYPE_GYROSCOPE) Mide la velocidad de rotación del dispositivo Detección de rotación
Magnetómetro (TYPE_MAGNETIC_FIELD) Mide la intensidad del campo geomagnético de la Tierra en µT Brújula
Proximidad (TYPE_PROXIMITY) Mide la proximidad de los objetos en cm Detección de objeto cercano
GPS (no es un tipo de sensor de android.hardware) Determina la ubicación geográfica precisa del dispositivo Detección precisa de ubicación geográfica
Sensores de entorno Sensor de luz ambiente (TYPE_LIGHT) Mide el nivel de luz ambiente en lx Control automático de brillo de la pantalla

Marco de trabajo de sensores en Android

El marco de trabajo de sensores en Android proporciona mecanismos que permiten acceder a los sensores y sus datos, con la excepción del GPS, al que se accede mediante los servicios de localización de Android. Esto lo analizaremos más adelante en este mismo capítulo. El marco de trabajo de sensores forma parte del paquete android.hardware. En la Tabla 4.2 se incluye una lista de las clases e interfaces principales en las que consiste el marco de trabajo de sensores.

Tabla 4.2    Marco de trabajo de sensores en la plataforma Android

Nombre Tipo Descripción
SensorManager Clase Se usa para crear una instancia del servicio de sensor. Proporciona diferentes métodos para acceder a los sensores, registrar y cancelar el registro de procesos de escucha (listeners) de eventos de sensor, etc.
Sensor Clase Se usa para crear una instancia de un sensor específico.
SensorEvent Clase El sistema la usa para publicar datos de sensores. Incluye los valores de datos de sensor sin procesar, la precisión de los datos y una marca de tiempo.
SensorEventListener Interfaz Proporciona métodos de devolución de llamada (callback) para recibir notificaciones de SensorManager cuando han cambiado los datos del sensor o la precisión del sensor.

2.1 Cómo obtener la configuración del sensor

Es decisión exclusiva del fabricante qué sensores estarán disponibles en el dispositivo. Es posible usar el marco de trabajo de sensores para descubrir cuáles son los sensores disponibles en el tiempo de ejecución; pare eso se debe invocar el método getSensorList() de SensorManager con el parámetro “Sensor.TYPE_ALL”. El Ejemplo de código 1 muestra en un fragmento una lista de sensores disponibles y el vendedor, la potencia y la precisión de la información de cada sensor.

package com.intel.deviceinfo;      
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; 	 
import android.app.Fragment;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter; 
	 
public class SensorInfoFragment extends Fragment {  
    private View mContentView;  
    private ListView mSensorInfoList;     
    SimpleAdapter mSensorInfoListAdapter;
    private List<Sensor> mSensorList; 
 
    private SensorManager mSensorManager;  
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }
    @Override
    public void onPause() 
    { 
        super.onPause();
    }
    @Override
    public void onResume() 
    {
        super.onResume();
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.content_sensorinfo_main, null);
        mContentView.setDrawingCacheEnabled(false);
        mSensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
        mSensorInfoList = (ListView)mContentView.findViewById(R.id.listSensorInfo);
        mSensorInfoList.setOnItemClickListener( new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int index, long arg3) {
                // with the index, figure out what sensor was pressed
                Sensor sensor = mSensorList.get(index);
                // pass the sensor to the dialog.
                SensorDialog dialog = new SensorDialog(getActivity(), sensor);
                dialog.setContentView(R.layout.sensor_display);
                dialog.setTitle("Sensor Data");
                dialog.show();
            }
        });            
        return mContentView;
    }      
    void updateContent(int category, int position) {
        mSensorInfoListAdapter = new SimpleAdapter(getActivity(), 
          getData() , android.R.layout.simple_list_item_2,
          new String[] {
              "NAME",
              "VALUE"
          },
          new int[] { android.R.id.text1, android.R.id.text2 });
      mSensorInfoList.setAdapter(mSensorInfoListAdapter);
    }
    protected void addItem(List<Map<String, String>> data, String name, String value)   {
        Map<String, String> temp = new HashMap<String, String>();
        temp.put("NAME", name);
        temp.put("VALUE", value);
        data.add(temp);
    }  
    private List<? extends Map<String, ?>> getData() {
        List<Map<String, String>> myData = new ArrayList<Map<String, String>>();
        mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
        for (Sensor sensor : mSensorList ) {
            addItem(myData, sensor.getName(),  "Vendor: " + sensor.getVendor() + ", min. delay: " + sensor.getMinDelay() +", power while in use: " + sensor.getPower() + "mA, maximum range: " + sensor.getMaximumRange() + ", resolution: " + sensor.getResolution());
        }
        return myData;
    }
}

Ejemplo de código 1: Fragmento que muestra la lista de sensores**. Fuente: Intel Corporation, 2012

2.2 Sistema de coordenadas de sensores

El marco de trabajo de sensores comunica datos de sensores mediante el uso de un sistema de coordenadas estándar de 3 ejes, en el cual X, Y y Z están representadas por values[0], values[1] y values[2], respectivamente, en el objeto SensorEvent.

0 0 1 95 544 intel 4 1 638 14.0

Sensores tales como el de luz, el de temperatura y el de proximidad devuelven un solo valor. Para estos sensores sólo se usa values[0] en el objeto SensorEvent.

Otros sensores comunican datos en el sistema de coordenadas estándar de 3 ejes. La siguiente es una lista de esos sensores:

  • Acelerómetro
  • Sensor de gravedad
  • Giroscopio
  • Sensor de campo geomagnético

El sistema de coordenadas de sensores de 3 ejes se define con relación a la pantalla del dispositivo en su orientación natural (predeterminada). En el caso de las tabletas, la orientación natural es por lo general la horizontal, mientras que para los teléfonos es la vertical. Cuando se sostiene un dispositivo en su orientación natural, el eje x es horizontal y apunta a la derecha, el eje y es vertical y apunta hacia arriba y el eje z apunta hacia fuera de la pantalla. La Figura 4.2 muestra el sistema de coordenadas de sensores para una tableta.


Figura 4.2. Sistema de coordenadas de sensores
Fuente: Intel Corporation, 2012

La cuestión más importante que se debe tener en cuenta es que el sistema de coordenadas del sensor nunca cambia cuando el dispositivo se mueve o se modifica su orientación.

2.3 Eventos de sensor de monitorización

El marco de trabajo de sensores informa datos a los objetos SensorEvent. Para monitorizar los datos de un sensor específico, una clase puede implementar la interfaz SensorEventListener y registrarse en el SensorManager del sensor. El marco de trabajo informa a la clase acerca de los cambios de estado del sensor por medio de los siguientes dos métodos de devolución de llamada de SensorEventListener implementados por la clase:

onAccuracyChanged()
y
onSensorChanged()

En el Ejemplo de código 2 se implementa el SensorDialog utilizado en el ejemplo de SensorInfoFragment que vimos en la sección “Cómo obtener la configuración del sensor”.

package com.intel.deviceinfo;
  
import android.app.Dialog;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
  
public class SensorDialog extends Dialog implements SensorEventListener {
    Sensor mSensor;
    TextView mDataTxt;
    private SensorManager mSensorManager; 
       
  
    public SensorDialog(Context ctx, Sensor sensor) {
        this(ctx);
        mSensor = sensor;
    }
       
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDataTxt = (TextView) findViewById(R.id.sensorDataTxt);
        mDataTxt.setText("...");
        setTitle(mSensor.getName());
    }
       
    @Override
    protected void onStart() {
        super.onStart();
        mSensorManager.registerListener(this, mSensor,  SensorManager.SENSOR_DELAY_FASTEST);
    }
             
    @Override
    protected void onStop() {
        super.onStop();
        mSensorManager.unregisterListener(this, mSensor);
    }
  
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
  
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() != mSensor.getType()) {
            return;
        }
        StringBuilder dataStrBuilder = new StringBuilder();
        if ((event.sensor.getType() == Sensor.TYPE_LIGHT)||
            (event.sensor.getType() == Sensor.TYPE_TEMPERATURE)) {
            dataStrBuilder.append(String.format("Data: %.3fn", event.values[0]));
        }
        else{         
            dataStrBuilder.append( 
                String.format("Data: %.3f, %.3f, %.3fn", 
                event.values[0], event.values[1], event.values[2] ));
        }
        mDataTxt.setText(dataStrBuilder.toString());
    }
}

Ejemplo de código 2: Diálogo que muestra los valores del sensor**

2.4 Sensores de movimiento

Los sensores de movimiento se usan para monitorizar el movimiento del dispositivo, ya sea agitación, giro, balanceo o inclinación. El acelerómetro y el giroscopio son dos sensores de movimiento de los cuales disponen muchas tabletas y teléfonos.

Los sensores de movimiento comunican datos en el sistema de coordenadas de sensores, en el cual los tres valores del objeto SensorEvent, values[0], values[1] y values[2], representan valores para los ejes x, y y z, respectivamente.

Para entender los sensores de movimiento y aplicar los datos en una aplicación, necesitamos usar algunas fórmulas físicas relacionadas con la fuerza, la masa, la aceleración, las leyes del movimiento de Newton y la relación entre varias de estas entidades a lo largo del tiempo. Aquel que desee conocer más acerca de estas fórmulas y relaciones puede consultar libros de texto de física o materiales de dominio público.

El acelerómetro mide la aceleración que se aplica al dispositivo.

Tabla 4.3    El acelerómetro        Fuente: Intel Corporation, 2012

Sensor Tipo Datos de SensorEvent (m/s2) Descripción
Acelerómetro TYPE_ACCELEROMETER values[0] Aceleración en el eje x
values[1] Aceleración en el eje y
values[2] Aceleración en el eje z

El concepto del acelerómetro se deriva de la segunda ley del movimiento de Newton:
a = F/m

La aceleración de un objeto es el resultado de la fuerza neta que se aplica al objeto. Entre las fuerzas externas se incluye la que se aplica a todos los objetos de la Tierra: la gravedad. Es directamente proporcional a la fuerza neta F que se aplica al objeto e inversamente proporcional a la masa m del objeto.

En nuestro código, en lugar de usar en forma directa la ecuación de arriba, por lo general nos interesa el resultado que produce la aceleración en la velocidad y la posición del dispositivo durante un período de tiempo. La siguiente ecuación describe la relación entre la velocidad v1 de un objeto, su velocidad original v0, la aceleración a y el tiempo t:
v1 = v0 + at

Para calcular el desplazamiento s del objeto, usamos la ecuación siguiente:
s = v0t + (1/2)at2

En muchos casos, comenzamos con la condición v0 igual a 0 (antes de que el dispositivo comience a moverse), lo que simplifica la ecuación. Así queda:
s = at2/2

Debido a la gravedad, la aceleración gravitacional, que se representa con el símbolo g, se aplica a todo objeto que se encuentre en la Tierra. Esta magnitud es independiente de la masa del objeto. Sólo depende de la altura del objeto respecto del nivel del mar. Su valor varía entre 9,78 y 9,82 (m/s2). Adoptamos el valor estándar convencional de g:
g = 9,80665 (m/s2)

Como el acelerómetro devuelve los valores según un sistema de coordenadas multidimensional, en nuestro código podemos calcular las distancias a lo largo de los ejes x, y y z con las siguientes ecuaciones.

Sx = AxT2/2

Sy=AyT2/2

Sz=AzT2/2

Donde Sx, Sy y Sz son los desplazamientos sobre el eje x, el eje y y el eje z, respectivamente, y Ax, Ay y Az son las aceleraciones sobre los ejes x, y y z, respectivamente. T es el tiempo del período medido.

En el Ejemplo de código 3 se muestra cómo crear una instancia de acelerómetro.

public class SensorDialog extends Dialog implements SensorEventListener {
    ... 
    private Sensor mSensor;
    private SensorManager mSensorManager; 
       
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    ...
}

Ejemplo de código 3: Creación de una instancia de acelerómetro (**)
Fuente: Intel Corporation, 2012

A veces no usamos los valores de las tres dimensiones. También puede ocurrir que necesitemos tomar en cuenta la orientación del dispositivo. Por ejemplo, cuando desarrollamos una aplicación para un laberinto, sólo usamos la aceleración gravitacional en los ejes x e y para calcular las distancias y las direcciones de movimiento de la bola a partir de la orientación del dispositivo. El siguiente fragmento de código (Ejemplo de código 4) describe la lógica.

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
        return;
    } 
float accelX, accelY;
...
//detect the current rotation currentRotation from its “natural orientation”
//using the WindowManager
    switch (currentRotation) {
        case Surface.ROTATION_0:
            accelX = event.values[0];
            accelY = event.values[1];
            break;
        case Surface.ROTATION_90:
            accelX = -event.values[0];
            accelY = event.values[1];
            break;
        case Surface.ROTATION_180:
            accelX = -event.values[0];
            accelY = -event.values[1];
            break;
        case Surface.ROTATION_270:
            accelX = event.values[0];
            accelY = -event.values[1];
            break;
    }
    //calculate the ball’s moving distances along x, and y using accelX, accelY and the time delta
        ...
    }
}

Ejemplo de código 4: Consideración de la orientación del dispositivo cuando se usan datos del acelerómetro en un juego de laberinto**
Fuente: Intel Corporation, 2012

El giroscopio mide la velocidad de rotación del dispositivo alrededor de los ejes x, y y z, como se muestra en la Tabla 4.4. Los valores de datos del giroscopio pueden ser positivos o negativos. Si se mira el origen desde una posición en el semieje positivo y si la rotación alrededor del eje es en sentido contrario al de las agujas del reloj, el valor es positivo; si la rotación es en el sentido de las agujas del reloj, el valor es negativo. También podemos determinar el sentido de los valores del giroscopio con la “regla de la mano derecha”, que se ilustra en la Figura 4.3.


Tabla 4.4.    El giroscopio        Fuente: Intel Corporation, 2012

Sensor Tipo Datos de SensorEvent (rad/s) Descripción
Giroscopio TYPE_GYROSCOPE values[0] Velocidad de rotación alrededor del eje x
values[1] Velocidad de rotación alrededor del eje y
values[2] Velocidad de rotación alrededor del eje z<

En el Ejemplo de código 5 se muestra cómo crear una instancia de giroscopio.

public class SensorDialog extends Dialog implements SensorEventListener {
    ... 
    private Sensor mGyro;
    private SensorManager mSensorManager; 
       
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mGyro = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
    ...
}

Ejemplo de código 5: Creación de una instancia de giroscopio**
Fuente: Intel Corporation, 2012

2.5 Sensores de posición

Muchas tabletas Android admiten dos sensores de posición: el magnetómetro y el sensor de proximidad. El magnetómetro mide las intensidades del campo magnético terrestre a lo largo de los ejes x, y y z, mientras que el sensor de proximidad detecta la distancia del dispositivo a otro objeto.

2.5.1 Magnetómetro

El uso más importante que da el sistema Android al magnetómetro (que se describe en la Tabla 4.5) es la implementación de la brújula.

Tabla 4.5    El magnetómetro        Fuente: Intel Corporation, 2012

Sensor Tipo Datos de SensorEvent (µT) Descripción
Magnetómetro TYPE_MAGNETIC_FIELD values[0] Intensidad del campo magnético terrestre a lo largo del eje x
values[1] Intensidad del campo magnético terrestre a lo largo del eje y
values[2] Intensidad del campo magnético terrestre a lo largo del eje z

En el Ejemplo de código 6 se muestra cómo crear una instancia de magnetómetro.

public class SensorDialog extends Dialog implements SensorEventListener {
    ... 
    private Sensor mMagnetometer;
    private SensorManager mSensorManager; 
       
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    ...
}

Ejemplo de código 6: Creación de una instancia de magnetómetro**
Fuente: Intel Corporation, 2012

2.5.2 Proximidad

El sensor de proximidad proporciona la distancia entre el dispositivo y otro objeto. El dispositivo lo puede usar para detectar si está siendo sostenido cerca del usuario (ver Tabla 4.6) y así determinar si el usuario está haciendo o recibiendo llamadas telefónicas.

Tabla 4.6    El sensor de proximidad        Fuente: Intel Corporation, 2012

Sensor Tipo Datos de SensorEvent Descripción
Proximidad TYPE_PROXIMITY values[0] Distancia en cm respecto de un objeto. Algunos sensores de proximidad sólo informan un valor booleano para indicar si el objeto está suficientemente cerca.

En el Ejemplo de código 7 se muestra cómo crear una instancia de sensor de proximidad.

public class SensorDialog extends Dialog implements SensorEventListener {
    ... 
    private Sensor mProximity;
    private SensorManager mSensorManager; 
       
    public SensorDialog(Context context) {
        super(context);
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    ...
}

Ejemplo de código 7: Creación de una instancia de sensor de proximidad**
Fuente: Intel Corporation, 2012

2.6 Sensores de entorno

Los sensores de entorno detectan e informan los parámetros de entorno del ambiente en el que se encuentra el dispositivo. La disponibilidad de cada sensor en particular depende sólo del fabricante del dispositivo. El sensor de luz ambiente (ALS) está disponible en muchas tabletas Android.

2.6.1 Sensor de luz ambiente (ALS)

El sistema usa el sensor de luz ambiente, que se describe en la Tabla 4.7, para detectar la iluminación del entorno y ajustar automáticamente el brillo de la pantalla según lo detectado.

Tabla 4.7    El sensor de luz ambiente        Fuente: Intel Corporation, 2012

Sensor Tipo Datos de SensorEvent (lx) Descripción
Sensor de luz ambiente TYPE_LIGHT values[0] Iluminación cerca del dispositivo

En el Ejemplo de código 8 se muestra cómo crear una instancia del sensor de luz ambiente.

    ... 
    private Sensor mALS;
    private SensorManager mSensorManager; 
  
    ... 
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mALS = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    ...

Ejemplo de código 8: Creación de una instancia de sensor de luz ambiente**
Fuente: Intel Corporation, 2012

2.7 Pautas de optimización y rendimiento de sensores

Para usar sensores en sus aplicaciones, es aconsejable que siga las siguientes pautas:

  • Antes de usar un sensor específico, siempre compruebe que esté disponible
    La plataforma Android no exige la inclusión o exclusión de sensores específicos en el dispositivo. Los sensores que se incluyen es algo que decide el fabricante del dispositivo en forma exclusiva. Antes de usar un sensor en su aplicación, siempre compruebe primero que esté disponible.
  • Siempre cancele el registro de los procesos de escucha del sensor
    Si la actividad que implementa el proceso de escucha del sensor se vuelve invisible, o si el diálogo se detiene, cancele el registro del proceso de escucha del sensor. Se puede hacer con el método onPause() de la actividad o el método onStop() del diálogo. Si no cumple con esta pauta, el sensor continuará adquiriendo datos y, como consecuencia, agotará la batería.
  • No bloquee el método onSensorChanged()
    El sistema llama con frecuencia al método onSensorChanged() para informar datos de sensor. Debe haber la menor cantidad de lógica posible dentro de este método. Los cálculos complicados con datos del sensor se deben mover hacia fuera de este método.
  • Siempre pruebe en dispositivos reales las aplicaciones que usen sensores
    Todos los sensores que se describen en esta sección son de tipo hardware. Es posible que el emulador de Android no sea suficiente para simular las funciones y el rendimiento de los sensores.

3 GPS y ubicación

El Sistema de Posicionamiento Global (Global Positioning System, GPS) es un sistema satelital que proporciona información precisa de ubicación geográfica en todo el mundo. Está disponible en una gran variedad de tabletas Android. En muchos aspectos, se comporta como un sensor de posición. Puede proporcionar datos precisos de ubicación para las aplicaciones que se ejecutan en el dispositivo. En la plataforma Android, el marco de trabajo de sensores no maneja el GPS de manera directa. Lo que ocurre, en cambio, es que el servicio de localización Android accede a los datos del GPS y los transfiere a las aplicaciones a través de las devoluciones de llamada de los procesos de escucha de ubicación.

3.1 Servicios de localización de Android

Usar el GPS no es la única manera de obtener la información de ubicación en los dispositivos Android. El sistema también puede utilizar Wi-Fi*, redes celulares y otras redes inalámbricas para hacerse con la ubicación actual del dispositivo. El GPS y las redes inalámbricas (incluidas las Wi-Fi y las celulares) actúan como “proveedores de ubicación” para los servicios de localización de Android. En la Tabla 4.8 se incluye una lista de las clases e interfaces principales que se usan para acceder a los servicios de localización de Android:

Tabla 4.8    El servicio de localización de la plataforma Android        Fuente: Intel Corporation, 2012

Nombre Tipo Descripción
LocationManager Clase Se usa para acceder a los servicios de localización. Proporciona diversos métodos para solicitar actualizaciones periódicas de ubicación para una aplicación, o para enviar alertas de proximidad.
LocationProvider Clase abstracta Es la supercalse abstracta para proveedores de ubicación.
Location Clase Los proveedores de ubicación la utilizan para encapsular datos geográficos.
LocationListener Interfaz Se usa para recibir notificaciones de LocationManager.

3.2 Cómo obtener actualizaciones de ubicación por GPS

 

De manera similar al mecanismo de usar el marco de trabajo de sensores para acceder a datos de sensores, la aplicación implementa varios métodos de devolución de llamada definidos en la interfaz LocationListener para recibir actualizaciones de ubicación por GPS. LocationManager envía notificaciones de actualización de GPS a la aplicación por medio de estas devoluciones de llamada (la regla “No nos llame, nosotros lo llamaremos”).

Para acceder a los datos de ubicación GPS de la aplicación, es necesario que solicite el permiso de acceso a ubicación precisa en su archivo de manifiesto de Android (Ejemplo de código 9).

<manifest ...>
...
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"...  
</manifest>

Ejemplo de código 9: Cómo solicitar el permiso de acceso a ubicación precisa en el archivo de manifiesto**
Fuente: Intel Corporation, 2012

En el Ejemplo de código 10 se muestra cómo obtener actualizaciones del GPS y mostrar las coordenadas de latitud y longitud en una vista de texto de diálogo.

package com.intel.deviceinfo;
  
import android.app.Dialog;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
  
public class GpsDialog extends Dialog implements LocationListener {
    TextView mDataTxt;
    private LocationManager mLocationManager;
       
    public GpsDialog(Context context) {
        super(context);
        mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    }
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
             mDataTxt = (TextView) findViewById(R.id.sensorDataTxt);
          mDataTxt.setText("...");
             
        setTitle("Gps Data");
    }
       
    @Override
    protected void onStart() {
        super.onStart();
        mLocationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 0, 0, this);
    }
             
    @Override
    protected void onStop() {
        super.onStop();
        mLocationManager.removeUpdates(this);
    }
  
    @Override
    public void onStatusChanged(String provider, int status, 
        Bundle extras) {
    }
  
    @Override
    public void onProviderEnabled(String provider) {
    }
  
    @Override
    public void onProviderDisabled(String provider) {
    }
  
    @Override
    public void onLocationChanged(Location location) {
        StringBuilder dataStrBuilder = new StringBuilder();
        dataStrBuilder.append(String.format("Latitude: %.3f,   Logitude%.3fn", location.getLatitude(), location.getLongitude()));
        mDataTxt.setText(dataStrBuilder.toString());
             
    }
}

Ejemplo de código 10: Diálogo que muestra los datos de ubicación del GPS**
Fuente: Intel Corporation, 2012

3.3 Pautas de optimización y rendimiento del GPS y la localización

El GPS proporciona la información de ubicación más exacta del dispositivo. Sin embargo, al ser una prestación de hardware, consume energía adicional. Por otra parte, al GPS le lleva tiempo obtener sus primeros datos de ubicación. Las siguientes son algunas pautas que se deben seguir al desarrollar aplicaciones que utilicen el GPS y datos de ubicación:

  • Considere todos los proveedores posibles
    Además de GPS_PROVIDER, está NETWORK_PROVIDER. Si sus aplicaciones sólo necesitan los datos de ubicación aproximada, puede considerar el uso de NETWORK_PROVIDER.
  • Use las ubicaciones guardadas en el caché
    Al GPS le lleva tiempo obtener sus primeros datos de ubicación. Cuando la aplicación está esperando que el GPS obtenga una actualización de ubicación precisa, puede usar primero las ubicaciones que proporciona el método LocationManager’s getlastKnownLocation() para realizar parte del trabajo.
  • Reduzca al mínimo la frecuencia y la duración de las solicitudes de actualización de ubicación
    Debe solicitar la solicitud de ubicación sólo cuando sea necesario y cancelar el registro del administrador de ubicación cuando ya no necesite las actualizaciones.

4. Resumen

La plataforma Android proporciona interfaces de programación de aplicaciones (API) para que los desarrolladores accedan a los sensores integrados de los dispositivos. Estos sensores son capaces de proporcionar datos sin procesar acerca del movimiento, la posición y las condiciones de entorno del ambiente actuales del dispositivo con gran precisión. Al desarrollar aplicaciones que usen sensores, debe seguir los procedimientos recomendados para mejorar el rendimiento y aumentar la eficiencia.


Aviso de optimización

Los compiladores de Intel pueden o no optimizar al mismo grado para microprocesadores que no sean de Intel en el caso de optimizaciones que no sean específicas para los microprocesadores de Intel. Entre estas optimizaciones se encuentran las de los conjuntos de instrucciones SSE2, SSE3 y SSE3, y otras. Intel no garantiza la disponibilidad, la funcionalidad ni la eficacia de ninguna optimización en microprocesadores no fabricados por Intel.

Las optimizaciones de este producto que dependen de microprocesadores se crearon para utilizarlas con microprocesadores de Intel. Ciertas optimizaciones no específicas para la microarquitectura de Intel se reservan para los microprocesadores de Intel. Consulte las guías para el usuario y de referencia correspondientes si desea obtener más información relacionada con los conjuntos de instrucciones específicos cubiertos por este aviso.

Notice revision #20110804