Sviluppo di applicazioni per i sensori di telefoni e tablet Android* basati sul processore Intel® Atom™

Sviluppo di applicazioni per i sensori di telefoni e tablet Android* basati sul processore Intel® Atom™


Questa guida offre agli sviluppatori di applicazioni un'introduzione al framework dei sensori Android e tratta di come usare alcuni sensori che sono generalmente disponibili nei telefoni e nei tablet basati sul processore Intel® Atom™. Tra gli altri saranno trattati i sensori di movimento, di posizione e dell'ambiente. Questa guida parla anche dei servizi di localizzazione basati su GPS, sebbene il framework Android non classifichi strettamente il GPS come un sensore. Il contenuto esposto in questa guida si basa su Android 4.2, Jelly Bean.

Sensori di telefoni e tablet Android* basati sul processore Intel® Atom™


I telefoni e i tablet Android basati sui processori Intel Atom sono in grado di supportare una vasta gamma di sensori hardware. Questi sensori sono utilizzati per rilevare i cambiamenti di movimento e posizione e per riferire i parametri ambientali dell'ambiente. Lo schema a blocchi della Figura 1 mostra una possibile configurazione di sensori su un tipico dispositivo Android basato sul processore Intel Atom.


Figura 1.  Sensori di un sistema Android basato sul processore Intel® Atom™

Sulla base dei dati che riportano, i sensori Android possono essere classificati nelle classi e nei tipi indicati nella Tabella 1.

Sensori di movimento Accelerometro
(TYPE_ACCELEROMETER)
Misura le accelerazioni di un dispositivo in m/s2 Rilevazione del movimento
Giroscopio
(TYPE_GYROSCOPE)
Misura la velocità di rotazione di un dispositivo Rilevazione della rotazione
Sensori di posizione Magnetometro
(TYPE_MAGNETIC_FIELD)
Misura la forza del campo geomagnetico terrestre in µT Bussola
Prossimità
(TYPE_PROXIMITY)
Misura la vicinanza di un oggetto in cm Rilevamento di oggetti circostanti
GPS
 (non è un tipo di sensore android.hardware)
Ottiene la posizione geografica accurata del dispositivo Rilevamento accurato della posizione geografica
Sensori dell'ambiente ALS
(TYPE_LIGHT)
Misura il livello di luce ambientale in lx Controllo automatico della luminosità dello schermo
Barometro Misura la pressione atmosferica dell'ambiente in mbar Rilevamento dell'altitudine

Tabella 1.  Tipi di sensori supportati dalla piattaforma Android
 

Framework dei sensori Android


Il framework dei sensori Android fornisce meccanismi per accedere ai sensori e ai dati dei sensori, ad eccezione del GPS, tramite i servizi di localizzazione Android. Ne discuteremo più avanti in questo articolo. Il framework dei sensori fa parte del pacchetto android.hardware. La Tabella 2 elenca le principali classi e interfacce del framework dei sensori.

Nome Tipo Descrizione
SensorManager Classe Utilizzata per creare un'istanza del servizio del sensore. Fornisce diversi metodi per accedere ai sensori, registrare e deregistrare i listener di eventi dei sensori e così via.
Sensore Classe Utilizzata per creare un'istanza di un sensore specifico.
SensorEvent Classe Utilizzata dal sistema per pubblicare i dati del sensore. Comprende i valori dei dati non elaborati del sensore, il tipo di sensore, l'accuratezza dei dati, la data e l'ora.
SensorEventListener Interfaccia Fornisce i metodi di callback per ricevere le notifiche di SensorManager quando i dati del sensore o la precisione del sensore cambiano.

Tabella 2. Il framework di sensori della piattaforma Android

Ottenere la configurazione del sensore

I produttori dei dispositivi decidono i sensori da rendere disponibili sul dispositivo. È necessario scoprire quali sensori sono disponibili in fase di esecuzione effettuando una chiamata al metodo getSensorList() del SensorManager del framework di sensori usando il parametro “Sensor.TYPE_ALL”. L'esempio di codice 1 mostra un elenco dei sensori disponibili e le informazioni relative al fornitore, alla potenza e alla precisione di ciascun sensore.

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;
    }
}

Esempio di codice 1. Frammento che mostra l'elenco dei sensori **

Sistema di coordinate dei sensori

Il framework dei sensori riporta i dati dei sensori usando un sistema standard di coordinate su tre assi, in cui i valori di X, Y e Z sono rispettivamente rappresentati da values[0], values[1] e values[2] dell'oggetto SensorEvent.

Alcuni sensori, come i sensori di luminosità, temperatura, prossimità e pressione, restituiscono solo valori singoli. Per questi sensori sono utilizzati solo i valori values[0] dell'oggetto SensorEvent.

Altri sensori riportano i dati nel sistema standard di coordinate a tre assi. I sensori di questo tipo sono:

  • Accelerometro
  • Sensore della gravità
  • Giroscopio
  • Sensore del campo geomagnetico

Il sistema di coordinate a tre assi del sensore è definito in relazione allo schermo del dispositivo secondo l'orientamento naturale (predefinito) del dispositivo. L'orientamento predefinito di un telefono è quello verticale, mentre l'orientamento naturale di un tablet è orizzontale. Quando il dispositivo è mantenuto nel suo orientamento naturale, l'asse x è orizzontale e punta verso destra, l'asse y è verticale e punta verso l'alto e l'asse z punta verso l'esterno del lato anteriore dello schermo. La Figura 2 mostra il sistema di coordinate del sensore per un telefono e la Figura 3 per un tablet.


Figura 2. Sistema di coordinate del sensore per un telefono


Figura 3.  Sistema di coordinate del sensore per un tablet

Il punto più importante per quanto riguarda il sistema di coordinate del sensore è che il sistema di coordinate del sensore non cambia quando il dispositivo si muove o cambia il suo orientamento.

Monitoraggio degli eventi del sensore

Il framework dei sensori riporta i dati dei sensori con gli oggetti SensorEvent. Una classe può monitorare i dati di uno specifico sensore implementando l'interfaccia SensorEventListener e registrando in SensorManager il sensore specifico. Il framework dei sensori comunica alla classe i cambiamenti di stato dei sensori tramite i seguenti due metodi di callback SensorEventListener implementati dalla classe:

 

onAccuracyChanged()

 

e

 

onSensorChanged()

 

L'esempio di codice 2 implementa il SensorDialog utilizzato nell'esempio SensorInfoFragment che abbiamo trattato nella sezione "Ottenere la configurazione del sensore".

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)||
            (event.sensor.getType() == Sensor.TYPE_PRESSURE)) {
            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());
    }
}

Esempio di codice 2. Finestra di dialogo che mostra i valori dei sensori**

Sensori di movimento

I sensori di movimento vengono utilizzati per monitorare il movimento del dispositivo, come ad esempio scuotimenti, rotazioni, oscillazioni o inclinazioni. L'accelerometro e il giroscopio sono due sensori di movimento disponibili su molti dispositivi tablet e telefoni.

I sensori di movimento segnalano i dati usando il sistema di coordinate del sensore, in cui i tre valori nell'oggetto SensorEvent, values[0], values[1] e values[2], rappresentano rispettivamente i valori delle assi x, y e z.

Per capire i sensori di movimento e usarne i dati in un'applicazione, è necessario applicare alcune formule di fisica legate alla forza, alla massa, all'accelerazione, le leggi del moto di Newton e il rapporto nel tempo tra alcune di queste entità. Per ulteriori informazioni su queste formule e relazioni, fare riferimento ai libri di testo di fisica o a fonti di pubblico dominio.

Accelerometro

L'accelerometro misura l'accelerazione applicata al dispositivo e le sue proprietà sono riassunte nella Tabella 3.

 
Sensore Tipo Dati
SensorEvent (m/s2)
Descrizione
Accelerometro TYPE_ACCELEROMETER values[0]
values[1]
values[2]
Accelerazione lungo l'asse x
Accelerazione lungo l'asse y
Accelerazione lungo l'asse z

Tabella 3. L'accelerometro

Il concetto di accelerometro deriva dalla seconda legge del moto di Newton:

a = F/m

L'accelerazione di un oggetto è il risultato della forza esterna netta applicata all'oggetto. Le forze esterne includono quella esercitata su tutti gli oggetti della terra, vale a dire la gravità. È proporzionale alla forza F applicata all'oggetto e inversamente proporzionale alla massa m dell'oggetto.

Nel nostro codice, anziché utilizzare direttamente l'equazione di cui sopra, siamo più interessati al risultato che l'accelerazione ha sulla velocità e sulla posizione del dispositivo in un determinato periodo di tempo. La seguente equazione descrive la relazione tra la velocità v1 di un oggetto, la sua velocità originale v0, l'accelerazione a e il tempo t:

v1 = v0 + at

Per calcolare lo spostamento s della posizione dell'oggetto usiamo la seguente equazione:

s = v0t + (1/2)at2

In molti casi si comincia con la condizione v0 uguale a 0 (prima che il dispositivo inizi a muoversi), che semplifica l'equazione nel modo seguente:

s = at2/2

La forza di gravità, rappresentata con il simbolo g sottopone tutti gli oggetti della terra ad accelerazione gravitazionale. Indipendentemente dalla massa dell'oggetto, il valore di g dipende solo dalla latitudine della posizione dell'oggetto ed è compreso tra 9,78 e 9,82 (m/s2). Adottiamo un valore standard convenzionale di g:

g = 9.80665 (m/s2)

Poiché l'accelerometro restituisce i valori utilizzando il sistema di coordinate di un dispositivo multidimensionale, nel nostro codice possiamo calcolare le distanze lungo gli assi x, y e z utilizzando le seguenti equazioni:

Sx = AxT2/2
Sy=AyT2/2
Sz=AzT2/2

Dove Sx, Sy e Sz sono rispettivamente gli spostamenti sull'asse x, sull'asse y e sull'asse z, mentre Ax, Ay e Az sono rispettivamente le accelerazioni sull'asse x, sull'asse y e sull'asse z. T è il tempo del periodo di misurazione.

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);
    …
}

Esempio di codice 3. Istanza di un accelerometro**

A volte non usiamo i valori dei dati di tutte e tre le dimensioni. Altre volte potremmo anche avere bisogno di prendere in considerazione l'orientamento del dispositivo. Ad esempio, per un'applicazione labirinto, usiamo solo l'accelerazione gravitazionale dell'asse x e dell'asse y per calcolare la direzione del movimento e la distanza della pallina in base all'orientamento del dispositivo. La logica è descritta nel seguente frammento di codice (esempio di codice 4).

@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
        …
    }
}

Esempio di codice 4. Considerare l'orientamento del dispositivo quando si utilizzano i dati dell'accelerometro in un gioco di labirinto**

Giroscopio


Il giroscopio calcola la velocità di rotazione del dispositivo intorno agli assi x, y e z, come mostrato nella Tabella 4. I valori dei dati del giroscopio possono essere positivi o negativi. Si supponga di guardare l'origine da una posizione lungo la metà positiva dell'asse, se la rotazione è in senso antiorario attorno all'asse, il valore è positivo, se la rotazione attorno all'asse è in senso orario, il valore è negativo. Possiamo anche determinare la direzione di un valore del giroscopio utilizzando la "regola della mano destra", illustrata nella Figura 4.


Figura 4.  Uso della “regola della mano destra” per decidere il senso di rotazione positivo

Sensore Tipo Dati
SensorEvent (rad/s)
Descrizione
Giroscopio TYPE_GYROSCOPE values[0]
values[1]
values[2]
Velocità di rotazione attorno all'asse x
Velocità di rotazione attorno all'asse y
Velocità di rotazione attorno all'asse z

Tabella 4. Il giroscopio

L'esempio di codice 5 mostra come creare un'istanza di 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);
    …
}

Esempio di codice 5. Istanza di giroscopio**

Sensori di posizione

Molti tablet Android supportano due sensori di posizione: il magnetometro e i sensori di prossimità. Il magnetometro misura le forze del campo magnetico terrestre lungo gli assi x, y e z, mentre il sensore di prossimità rileva la distanza del dispositivo da un altro oggetto.

Magnetometro

L'uso più importante del magnetometro nei sistemi Android (descritto nella Tabella 5) è quello di implementare la bussola.

Sensore Tipo Dati
SensorEvent (µT)
Descrizione
Magnetometro TYPE_MAGNETIC_FIELD values[0]
values[1]
values[2]
Intensità del campo magnetico terrestre lungo l'asse x
Intensità del campo magnetico terrestre lungo l'asse y
Intensità del campo magnetico terrestre lungo l'asse z

Tabella 5. Il magnetometro

L'esempio di codice 6 mostra come creare un'istanza di magnetometro.

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);
    …
}

Esempio di codice 6. Istanza di magnetometro**

Prossimità

Il sensore di prossimità fornisce la distanza tra il dispositivo e un altro oggetto. Il dispositivo può utilizzare il sensore per rilevare se il dispositivo viene tenuto vicino all'utente (vedere la Tabella 6), determinare se l'utente sta facendo una telefonata e quindi spegnere lo schermo durante la telefonata.

Tabella 6: Il sensore di prossimità
Sensore Tipo Dati
SensorEvent
Descrizione
Prossimità TYPE_PROXIMITY values[0] Distanza da un oggetto in cm. Alcuni sensori di prossimità riportano solo un valore booleano per indicare se l'oggetto è abbastanza vicino.

Nell'esempio di codice 7 viene illustrato come creare un'istanza di un sensore di prossimità.

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);
    …
}

Esempio di codice 7. Istanza di un sensore di prossimità**

Sensori dell'ambiente

I sensori dell'ambiente rilevano e riportano parametri ambientali del dispositivo, quali la luce, la temperatura, la pressione o l'umidità. Il sensore della luce ambientale (ALS) e il sensore della pressione (barometro) sono disponibili su molti tablet Android.

Sensore della luce ambientale

Il sensore della luce ambientale, descritto nella Tabella 7, viene utilizzato dal sistema per rilevare l'illuminazione dell'ambiente circostante e di conseguenza regolare automaticamente la luminosità dello schermo.

Tabella 7: Il sensore della luce ambientale
Sensore Tipo Dati
SensorEvent (lx)
Descrizione
ALS TYPE_LIGHT values[0] L'illuminazione intorno al dispositivo

L'esempio di codice 8 mostra come creare un'istanza di ALS.

    …	
    private Sensor mALS;
    private SensorManager mSensorManager;

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

Esempio di codice 8. Istanza di un sensore della luce ambientale**

Barometro

Le applicazioni possono utilizzare il sensore della pressione atmosferica (barometro), descritto nella Tabella 8, per calcolare l'altitudine della posizione corrente del dispositivo.

Tabella 8: Il sensore della pressione atmosferica
Sensore Tipo Dati
SensorEvent (lx)
Descrizione
Barometro TYPE_PRESSURE values[0] La pressione atmosferica dell'ambiente in mbar

L'esempio di codice 9 mostra come creare un'istanza di barometro.

    …	
    private Sensor mBarometer;
    private SensorManager mSensorManager;

    …	
        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
        mBarometer = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
    …

Esempio di codice 9.  Istanza di barometro**

Linee guida per le prestazioni e l'ottimizzazione dei sensori

Seguire queste procedure ottimali per utilizzare i sensori nelle applicazioni:

  • Controllare sempre la disponibilità del sensore specifico prima di utilizzarlo
    La piattaforma Android non richiede che il dispositivo includa o escluda sensori specifici. Prima di utilizzare un sensore nell'applicazione, occorre sempre prima verificare se il sensore è effettivamente disponibile.
  • Deregistrare sempre i listener dei sensori
    Se l'attività che implementa il listener del sensore diventa invisibile o la finestra di dialogo si ferma, deregistrare il listener del sensore. Lo si può fare usando il metodo onPause() dell'attività o il metodo onStop() della finestra di dialogo. In caso contrario, il sensore continuerà ad acquisire dati scaricando di conseguenza la batteria.
  • Non bloccare il metodo onSensorChanged()
    Il metodo onSensorChanged() viene spesso chiamato dal sistema per riportare i dati del sensore. La logica inserita in questo metodo dovrebbe essere il più possibile ridotta al minimo. I calcoli complicati eseguiti utilizzando i dati del sensore devono essere spostati al di fuori di questo metodo.
  • Testare sempre sui dispositivi reali le applicazioni con sensori
    Tutti i sensori descritti in questa sezione sono sensori hardware. L'emulatore di Android potrebbe non essere in grado di simulare le funzioni e le prestazioni di un particolare sensore.

GPS e localizzazione


GPS (Global Positioning System) è un sistema satellitare che fornisce informazioni accurate di geolocalizzazione in tutto il mondo. Il GPS è disponibile in molti telefoni Android e tablet. Sotto molti aspetti il GPS si comporta come un sensore di posizione. È in grado di fornire dati di posizione accurati per le applicazioni in esecuzione sul dispositivo. Nella piattaforma Android il GPS non è gestito direttamente dal framework dei sensori. Il servizio di localizzazione Android invece accede ai dati del GPS e li trasferisce a un'applicazione tramite le chiamate del listener della posizione.

Questa sezione descrive il GPS e i servizi di localizzazione solo dal punto di vista del sensore hardware. Le strategie di localizzazione complete offerte da Android 4.2 e dai telefoni e tablet Android basati sul processore Intel Atom sono un argomento molto più vasto che esula dall'ambito della presente sezione.

Servizi di localizzazione Android

L'utilizzo del GPS non è l'unico modo per ottenere informazioni sulla posizione di un dispositivo Android. Il sistema può anche utilizzare la connessione Wi-Fi*, le reti cellulari o altre reti wireless per ottenere la posizione corrente del dispositivo. Il GPS e le reti wireless (tra cui le reti Wi-Fi e le reti cellulari) agiscono come “fornitori della posizione” per i servizi di localizzazione Android. La Tabella 9 elenca le principali classi e interfacce utilizzate per accedere ai servizi di localizzazione Android.

Tabella 9: Il servizio di localizzazione della piattaforma Android
Nome Tipo Descrizione
LocationManager Classe Utilizzata per accedere ai servizi di localizzazione. Fornisce i vari metodi per la richiesta di aggiornamenti periodici della posizione di un'applicazione o per l'invio di avvisi di prossimità
LocationProvider Classe astratta La super classe astratta per i provider di localizzazione
Location Classe Utilizzata dai provider di localizzazione per incapsulare dati geografici
LocationListener Interfaccia Utilizzata per ricevere le notifiche di localizzazione dal LocationManager

Ottenere aggiornamenti sulla posizione GPS

Per ricevere gli aggiornamenti sulla posizione GPS l'applicazione implementa diversi metodi di callback definiti nell'interfaccia LocationListener, in modo simile al meccanismo che utilizza il framework dei sensori per accedere ai dati del sensore. LocationManager invia all'applicazione le notifiche degli aggiornamenti GPS attraverso questi callback (secondo la regola “Non chiamateci, vi chiameremo noi”).

Per accedere ai dati di posizione GPS nell'applicazione è necessario richiedere il permesso di accesso alla posizione precisa nel file manifesto di Android (esempio di codice 10).

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

Esempio di codice 10. Richiesta del permesso di accesso alla posizione precisa nel file manifesto**

L'esempio di codice 11 mostra come ottenere gli aggiornamenti GPS e visualizzare le coordinate della latitudine e della longitudine come testo di una finestra di dialogo.

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());
		
    }
}

Esempio di codice 11.  Una finestra di dialogo che visualizza i dati di posizione GPS**

Linee guida per le prestazioni e l'ottimizzazione del GPS e della posizione

Il GPS fornisce le informazioni più accurate sulla posizione del dispositivo. Trattandosi tuttavia di una funzionalità hardware, consuma energia supplementare. Il GPS impiega anche del tempo per ottenere la prima posizione fissa. Ecco alcune linee guida da seguire durante lo sviluppo di applicazioni GPS in grado di rilevare la posizione:

  • Considerare tutti i provider di localizzazione disponibili
    Oltre a GPS_PROVIDER, vi è NETWORK_PROVIDER. Se le applicazioni hanno bisogno solo di dati di localizzazione geografica non puntuali, si può prendere in considerazione di utilizzare NETWORK_PROVIDER.
  • Utilizzare le posizioni memorizzate nella cache
    Il GPS impiega del tempo per ottenere la prima posizione fissa. Quando l'applicazione è in attesa che il GPS ottenga un aggiornamento preciso della posizione, è possibile usare le posizioni fornite dal metodo getlastKnownLocation() di LocationManager per svolgere parte del lavoro.
  • Ridurre al minimo la frequenza e la durata delle richieste di aggiornamento della posizione
    Richiedere l'aggiornamento della posizione solo quando è necessario e prontamente deregistrare la richiesta dal location manager una volta che non c'è più bisogno di ottenere gli aggiornamenti della posizione.

Riepilogo


La piattaforma Android fornisce agli sviluppatori le API per accedere ai sensori integrati nei dispositivi. Questi sensori sono in grado di fornire dati grezzi sul movimento, sulla posizione e sulle condizioni ambientali correnti del dispositivo con elevata precisione e accuratezza. Nello sviluppo di applicazioni per i sensori, è necessario seguire le pratiche ottimali per migliorare le prestazioni e l'efficienza energetica.

Informazioni sull'autore

Miao Wei è un ingegnere informatico del gruppo software e servizi presso Intel. Attualmente sta lavorando a progetti di abilitazione della scalabilità del processore Intel® Atom™.



 

 

 

Copyright © 2013 Intel Corporation. Tutti i diritti riservati.
*Altri marchi e denominazioni potrebbero essere proprietà di terzi.

**Questo codice sorgente di esempio è rilasciato in base al Contratto di licenza per il codice sorgente di esempio Intel