Creazione di app con sensori ambientali

Scopri come utilizzare i sensori ambiente Android per rilevare le informazioni sull'ambiente dell'utente, tra cui temperatura ambiente, pressione, umidità e luce.

Il sistema Android supporta una gamma di sensori del dispositivo, alcuni implementati nell'hardware e altri nel software. I sensori ambientali sono tutte caratteristiche hardware che forniscono l'accesso alle informazioni relative a temperatura ambiente, pressione, umidità e luce. Questi sensori restituiscono valori come segue: la temperatura viene misurata in gradi Celsius, la pressione atmosferica in millibar hPa, l'umidità relativa dell'aria ambiente come valore percentuale e la luce ambientale in unità SI lux. In questo tutorial, eseguiremo il processo di base per l'utilizzo di questi quattro sensori ambientali principali. Non useremo il sensore di temperatura del dispositivo, poiché ora è deprecato a partire da Android 4.0.

Ci sono molte possibili applicazioni per questi sensori, come barometri e termometri. Potresti aver già incontrato app di questo tipo in Google Play, ma vale la pena notare che potrebbero non necessariamente implementare le loro funzioni utilizzando Sensori ambientali. Ad esempio, le app meteo utilizzano spesso i dati sulla posizione recuperati sul Web per determinare le informazioni sull'ambiente in base a dove ti trovi.

Poiché questi sensori sono forniti tramite l'hardware degli utenti, il supporto varia tra dispositivi e produttori. Al momento della scrittura, pochissimi smartphone o tablet Android supportano tutti i sensori ambientali, ma molti dei modelli più recenti supportano uno o più di essi. È fondamentale verificare se l'utente ha dei sensori particolari e evitare di usare funzionalità che dipendono totalmente da essi. L'unica eccezione è se assicuri che solo gli utenti con l'hardware richiesto possano scaricare la tua applicazione - puoi farlo usando i filtri per un'app come elencata nel Google Play Store.


Passaggio 1: crea un nuovo progetto Android

Crea un nuovo progetto Android in Eclipse e assegnagli un nome a tua scelta. Lascia che Eclipse crei un'attività principale, poiché questa è l'unica classe di cui avremo bisogno. Per il codice utilizzato in questo tutorial, stiamo prendendo di mira il livello API Android 14 (Android 4.0 - Ice Cream Sandwich), ma puoi scegliere come target una versione più recente, se lo desideri. Non è necessario apportare modifiche al file Manifest. La tua classe di attività principale dovrebbe avere la seguente struttura iniziale, con il nome della tua classe scelta:

 public class EnvironmentCheckerActivity estende l'attività / ** chiamata quando l'attività viene creata per la prima volta. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); 

Stiamo implementando un paio di interfacce, quindi estendi la riga di dichiarazione della classe di apertura come segue:

 public class EnvironmentCheckerActivity estende Activity implements OnClickListener, SensorEventListener 

Il listener dei clic è per l'interazione dell'utente e il listener di eventi del sensore serve a ricevere i dati dai sensori del dispositivo. Eclipse avrebbe dovuto fornire istruzioni di importazione per le classi Activity e Bundle, ma è necessario aggiungere anche quanto segue all'elenco:

 importare android.content.Context; importare android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; importare android.hardware.SensorManager; importa android.view.View; import android.view.View.OnClickListener; importa android.widget.Button; import android.widget.TextView; importare android.widget.Toast;

Aggiungeremo il codice alla classe in seguito.


Passaggio 2: progettazione dell'interazione dell'utente

Al fine di dimostrare il processo di base per l'utilizzo dei sensori ambientali, costruiremo una semplice interfaccia utente. L'app mostrerà un elenco di quattro pulsanti, uno per ciascuno dei sensori che useremo. Quando l'utente seleziona un pulsante, l'app tenterà di recuperare le informazioni appropriate e presentarle in una visualizzazione di testo. Per prima cosa, definiamo alcune stringhe di testo che useremo all'interno dell'interfaccia. Apri il file "res / values ​​/ strings.xml" e modificalo per contenere quanto segue:

  Scegli tra le opzioni per controllare il tuo ambiente Checker dell'ambiente Temperatura ambiente Luce Pressione Umidità relativa - 

Questi rappresentano il titolo, il testo introduttivo, le etichette dei pulsanti e un segnaposto per le viste di testo. Utilizzeremo un paio di risorse disegnabili per il design, ma puoi ometterle se lo desideri. Per utilizzarli, in ciascuna delle cartelle dei file drawable della tua app, dovrai creare due file aggiuntivi, "back.xml" e "btn.xml" (seleziona a turno ciascuna cartella drawable e scegli "File"> "Nuovo"> " File ", quindi immettere il nome del file). Per il file "back.xml", inserisci il seguente codice:

   

Per il file "btn.xml", inserisci quanto segue:

     

Il back drawable è per lo sfondo Activity e il drawable "btn" è per gli sfondi del pulsante. Sentiti libero di modificare questi disegni in qualsiasi modo desideri - assicurati di copiarli in ogni cartella drawable nella tua app.

Ora apri il file di layout "main.xml" dell'app (res / layout / main.xml). Inserisci una vista di scorrimento e un layout lineare come segue:

    

All'interno del layout lineare, aggiungi l'introduzione, quindi una vista pulsante e testo per ciascuno dei quattro sensori:

  

Ogni coppia di pulsanti e visualizzazione di testo è praticamente identica, con attributi ID per identificarli nel codice Java. Naturalmente, se lo desideri, puoi modificare qualsiasi elemento del design. Il layout si riferisce alle risorse estraibili e alle stringhe.


Passaggio 3: gestire l'interazione dell'utente

Apri la classe di attività principale della tua app. Nella parte superiore della dichiarazione della classe, prima del metodo "onCreate", aggiungi le seguenti variabili di istanza:

 Pulsante privato ambientBtn, lightBtn, pressureBtn, umiditàBtn; TextView privato valore ambiente, valore luce, valore pressione, valore umidità;

Questi rappresentano i pulsanti e le viste di testo che abbiamo creato nel layout. Utilizzeremo un array per tenere traccia degli elementi di visualizzazione del testo, poiché questi aggiorneranno con le informazioni quando i sensori lo restituiranno, quindi aggiungi la seguente variabile di matrice successiva:

 TextView privato [] valueFields = new TextView [4];

Ora aggiungi queste costanti per fare riferimento a ciascun tipo di sensore:

 private final int AMBIENT = 0; private final int LIGHT = 1; private final int PRESSURE = 2; private final int HUMIDITY = 3;

All'interno del metodo "onCreate", dopo la riga in cui è impostata la visualizzazione del contenuto, recuperare un riferimento a ciascun pulsante utilizzando gli attributi ID inclusi nel layout, come segue:

 ambientBtn = (Button) findViewById (R.id.ambient_btn); lightBtn = (Button) findViewById (R.id.light_btn); pressureBtn = (Button) findViewById (R.id.pressure_btn); moistureBtn = (Button) findViewById (R.id.humidity_btn);

Ora imposta ciascuno di questi per utilizzare la classe Attività come listener dei clic:

 ambientBtn.setOnClickListener (questo); lightBtn.setOnClickListener (questo); pressureBtn.setOnClickListener (questo); humidityBtn.setOnClickListener (questo);

Quando questi pulsanti vengono premuti, verrà eseguito il metodo Activity "onClick". Successivamente, recupera gli elementi di visualizzazione del testo e aggiungi un riferimento a ciascuno nell'array dichiarato, utilizzando le costanti per specificare ciascun indice:

 ambientValue = (TextView) findViewById (R.id.ambient_text); valueFields [AMBIENTE] = ambientValue; lightValue = (TextView) findViewById (R.id.light_text); valueFields [LIGHT] = lightValue; pressureValue = (TextView) findViewById (R.id.pressure_text); valueFields [PRESSIONE] = pressureValue; humidityValue = (TextView) findViewById (R.id.humidity_text); valueFields [UMIDITA] = humidityValue;

Ora dobbiamo fornire il metodo "onClick", aggiungendolo alla classe dopo il metodo "onCreate":

 public void onClick (Visualizza v) 

All'interno del metodo, abbiamo bisogno di determinare quale pulsante è stato cliccato usando un condizionale:

 if (v.getId () == R.id.ambient_btn) // temperatura ambiente else if (v.getId () == R.id.light_btn) // light else if (v.getId () == R.id.pressure_btn) // pressure else if (v.getId () == R.id.humidity_btn) // umidità

All'interno di ognuno di questi cercheremo di recuperare i dati relativi all'ambiente.


Passaggio 4: installazione del sensore ambientale

Nella parte superiore della classe, aggiungi un paio di variabili per il processo di rilevamento dell'ambiente:

 sensorManager privato senseManage; Sensore privato envSense;

Tornando al metodo "onCreate", dopo il codice esistente, aggiungere quanto segue per creare un'istanza della classe Sensor Manager:

 senseManage = (SensorManager) getSystemService (Context.SENSOR_SERVICE);

Abbiamo bisogno del Sensor Manager per tutti i processi di rilevamento ambientale. Lo usiamo per recuperare sensori specifici. All'interno dell'istruzione "if" del metodo "onClick" per la temperatura ambiente, tentare di recuperare il sensore della temperatura ambiente come segue:

 envSense = senseManage.getDefaultSensor (Sensor.TYPE_AMBIENT_TEMPERATURE);

Ora dobbiamo occuparci dei casi in cui il sensore non fornisce il sensore dal dispositivo dell'utente, quindi aggiungi il seguente test:

 if (envSense == null) Toast.makeText (this.getApplicationContext (), "Mi dispiace - il tuo dispositivo non ha un sensore di temperatura ambiente!", Toast.LENGTH_SHORT) .show ();

Abbiamo semplicemente emesso un messaggio di errore. Se il sensore è presente, è necessario registrarsi per ricevere i dati restituiti, quindi aggiungere quanto segue dopo questa istruzione "if":

 else senseManage.registerListener (this, envSense, SensorManager.SENSOR_DELAY_NORMAL);

Ora esegui lo stesso processo per ciascuno dei pulsanti nel metodo "onClick". Per il pulsante luce (nella sua istruzione "if" all'interno di "onClick"):

 envSense = senseManage.getDefaultSensor (Sensor.TYPE_LIGHT); if (envSense == null) Toast.makeText (this.getApplicationContext (), "Mi dispiace - il tuo dispositivo non ha un sensore di luce!", Toast.LENGTH_SHORT) .show (); else senseManage.registerListener (this, envSense, SensorManager.SENSOR_DELAY_NORMAL);

Si noti che qui stiamo richiedendo il sensore "TYPE_LIGHT" e stiamo adattando il messaggio di errore al tipo di sensore. Per il pulsante di pressione:

 envSense = senseManage.getDefaultSensor (Sensor.TYPE_PRESSURE); if (envSense == null) Toast.makeText (this.getApplicationContext (), "Mi dispiace - il tuo dispositivo non ha un sensore di pressione!", Toast.LENGTH_SHORT) .show (); else senseManage.registerListener (this, envSense, SensorManager.SENSOR_DELAY_NORMAL);

Infine, nella frase "if" per il pulsante umidità:

 envSense = senseManage.getDefaultSensor (Sensor.TYPE_RELATIVE_HUMIDITY); if (envSense == null) Toast.makeText (this.getApplicationContext (), "Mi dispiace - il tuo dispositivo non ha un sensore di umidità!", Toast.LENGTH_SHORT) .show (); else senseManage.registerListener (this, envSense, SensorManager.SENSOR_DELAY_NORMAL);

Passaggio 5: recupero dei dati di precisione

Oltre a restituire i dati sull'ambiente richiesti, il sensore restituirà anche i dati di accuratezza. Aggiungi il seguente metodo alla tua classe, che è richiesto quando si implementa l'interfaccia Listener di eventi sensore:

 @Override pubblico finale vuoto onAccuracyChanged (Sensore sensore, precisione int) 

All'interno del metodo, inizia a creare un messaggio relativo all'accuratezza:

 String accuracyMsg = "";

Useremo un'istruzione switch sul parametro intero di accuratezza passato:

 switch (precisione) case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: accuracyMsg = "Il sensore ha un'elevata precisione"; rompere; case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: accuracyMsg = "Il sensore ha una precisione media"; rompere; case SensorManager.SENSOR_STATUS_ACCURACY_LOW: accuracyMsg = "Il sensore ha bassa accuratezza"; rompere; case SensorManager.SENSOR_STATUS_UNRELIABLE: accuracyMsg = "Il sensore ha una precisione inaffidabile"; rompere; default: break; 

Adeguiamo il messaggio al livello di accuratezza del sensore, utilizzando la classe Sensor Manager. Emette la precisione quando viene ricevuto come segue, ma dopo l'istruzione switch:

 Toast accuracyToast = Toast.makeText (this.getApplicationContext (), accuracyMsg, Toast.LENGTH_SHORT); accuracyToast.show ();

All'interno del metodo "onAccuracyChanged" è anche possibile determinare il tipo di sensore dal parametro passato, se necessario.


Passaggio 6: recuperare i dati del sensore

Ora possiamo finalmente recuperare i dati restituiti dai sensori utilizzando un Evento sensore - lo facciamo nel metodo "onSensorChanged", che è anche richiesto per implementare l'interfaccia:

 @Override pubblico finale vuoto onSensorChanged (evento SensorEvent) 

L'evento sensore restituisce i suoi dati in modi diversi a seconda del tipo di sensore. Per tutti e quattro i tipi che stiamo utilizzando, viene recuperato allo stesso modo, dal primo elemento di un array di valori in virgola mobile. Aggiungi il seguente all'interno del metodo:

 float sensorValue = event.values ​​[0];

Ora stiamo per costruire una stringa di testo che include questi dati e scriverla nella relativa vista di testo che l'utente può vedere. Per prima cosa, creiamo una variabile di visualizzazione del testo e assegniamo un valore predefinito (questo valore verrà sovrascritto, includendolo per mantenere felice Eclipse):

 TextView currValue = ambientValue;

Successivamente, dichiariamo la stringa:

 Stringa;

Il contenuto della stringa dipende dal tipo di sensore, quindi scopriamo quale è:

 int currType = event.sensor.getType ();

Ora possiamo usare un'istruzione switch su questo valore:

 switch (currType) case Sensor.TYPE_AMBIENT_TEMPERATURE: envInfo = sensorValue + "gradi Celsius"; currValue = valueFields [AMBIENTE]; rompere; caso Sensor.TYPE_LIGHT: envInfo = sensorValue + "SI lux units"; currValue = valueFields [LIGHT]; rompere; case Sensor.TYPE_PRESSURE: envInfo = sensorValue + "hPa (millibar)"; currValue = valueFields [PRESSIONE]; rompere; caso Sensor.TYPE_RELATIVE_HUMIDITY: envInfo = sensorValue + "percentuale di umidità"; currValue = valueFields [UMIDITA]; rompere; default: break; 

In ogni caso, costruiamo la stringa informativa utilizzando il valore del sensore recuperato e un estratto di testo relativo al tipo. Impostiamo anche la vista del testo sull'elemento dell'interfaccia utente pertinente utilizzando l'array e le costanti. Dopo l'istruzione switch, invia le informazioni:

 currValue.setText (envInfo);

Ora resetta la variabile del sensore e interrompi l'ascolto degli aggiornamenti per evitare l'utilizzo non necessario della batteria:

 envSense = null; senseManage.unregisterListener (questo);

Infine, non vogliamo che l'app utilizzi risorse non necessarie quando è in pausa, quindi aggiungi questo metodo alla classe:

 @Override protected void onPause () super.onPause (); senseManage.unregisterListener (questo); 

Step 7: Provalo

Questa è l'app di dimostrazione completa! Non ha senso eseguire questa app sull'emulatore Android predefinito, perché non fornisce sensori ambientali. Tuttavia, è possibile eseguirlo su un dispositivo reale o utilizzare lo strumento Simulatore sensore, che consente di simulare determinati aspetti dell'ambiente. Di seguito è riportato uno screenshot dell'app in esecuzione sul Samsung Galaxy S III subito dopo il recupero dei dati di luce e pressione:

Qui è per gli altri due sensori, che non sono supportati:


Conclusione

I sensori ambientali sono una caratteristica eccitante ma ancora in via di sviluppo della piattaforma Android. Tuttavia, è un po 'presto per concentrarsi su di loro. Se si desidera esplorare l'utilizzo di questi sensori in modi più avanzati, consultare la sezione Guida per gli sviluppatori sul calcolo del punto di rugiada e dei livelli di umidità assoluta in base all'umidità relativa e alla temperatura ambiente. A parte questo, cerca di essere paziente!