Android Barometer Logger acquisizione dei dati del sensore

Gli smartphone sono pieni di sensori hardware, come accelerometri, sensori di luce, giroscopi e così via. Scopri come raccogliere dati da questi sensori implementando un registratore barometrico.

In una continuazione dall'ultimo tutorial, Picking App Components, questa volta implementeremo il codice per leggere i dati del sensore barometrico su base regolare. Imparerai a leggere i dati del sensore e come pianificare gli eventi ricorrenti, quindi l'applicazione e il relativo servizio non devono rimanere in esecuzione.


Iniziare

Questo tutorial presume che tu abbia una conoscenza di base di Android e Java, che tu abbia tutti gli strumenti Android installati e funzionanti e che tu ti sia comodo con il caricamento e il test delle applicazioni su un dispositivo Android. Useremo il sensore hardware del barometro in questa applicazione. Se non si dispone di un dispositivo con questo sensore, è possibile sostituirlo con un altro sensore simile a scopo di test, ma i risultati o l'utilità potrebbero non essere equivalenti.


Parte A: Sensori di lettura

I sensori hardware sono accessibili tramite la classe SensorManager. Attraverso un'istanza di questa classe un'applicazione può interrogare vari oggetti Sensor che rappresentano l'hardware sottostante. Usando questi, un'applicazione può quindi iniziare ad ascoltare i dati provenienti dall'hardware del sensore.


Passaggio 1: individuazione del sensore barometrico

Innanzitutto, ottieni un'istanza della classe SensorManager, in questo modo:

 SensorManager sensorManager = (SensorManager) getSystemService (SENSOR_SERVICE);

Quindi, cercare il sensore Sensor.TYPE_PRESSURE, che è il sensore barometrico:

 Sensore sensore = sensorManager.getDefaultSensor (Sensor.TYPE_PRESSURE);

L'utilizzo della classe SensorManager e dei sensori di lettura non richiede autorizzazioni speciali.


Passaggio 2: registrazione per eventi sensore

Ora puoi registrarti per ricevere eventi dal sensore. Per fare ciò, è necessario implementare un SensorEventListener e comunicarlo alla classe SensorManager.

Ad esempio, ecco la struttura per un'implementazione di un SensorEventListener:

 class MyListener implementa SensorEventListener @Override public void onAccuracyChanged (Sensore sensore, precisione int) // TODO @Override public void onSensorChanged (Evento SensorEvent) // TODO

Quindi registrati per gli eventi dicendo al SensorManager del tuo ascoltatore:

 sensorManager.registerListener (myListenerInstance, sensor, SensorManager.SENSOR_DELAY_NORMAL);

È possibile registrarsi per ricevere gli aggiornamenti degli eventi a tariffe diverse. Più veloce è il tasso, più frequenti sono gli aggiornamenti, ma anche più veloce sarà il consumo della batteria del dispositivo. Qui usiamo il tasso di default. Controlla il valore restituito dalla chiamata registerListener () per vedere se ha avuto successo o meno. Se è vero, il sensore è disponibile e l'ascolto è iniziato. Se falso, il sensore potrebbe non essere disponibile (per qualsiasi motivo).


Passaggio 3: lettura degli eventi

La classe per ricevere eventi sensore è generica per tutti i sensori tramite la classe SensorEvent. Come tale, il campo valore SensorEvent è un array per gestire più dati rispetto al nostro singolo sensore barometrico numerico. Ci interessa solo il primo valore dell'array e il timestamp:

 @Override public void onSensorChanged (evento SensorEvent) long timestamp = event.timestamp; float value = event.values ​​[0]; // fai qualcosa con i valori

Passaggio 3: arresto dell'ascolto del sensore

Infine, per interrompere l'ascolto del sensore, basta semplicemente annullarlo:

 sensorManager.unregisterListener (myListenerInstance);

È necessario registrarsi solo quando l'applicazione è pronta e necessita dei dati del sensore, quindi annullare la registrazione non appena non è più necessaria. Questo aiuta a usare le risorse del dispositivo come la batteria con saggezza.


Parte B: in esecuzione in background

Probabilmente non sei interessato a lasciare l'app sempre in esecuzione per verificare i valori del sensore. Invece, crea un servizio e fai partire regolarmente il servizio utilizzando un allarme ripetuto tramite AlarmManager.


Passaggio 1: implementazione del servizio

Un servizio su Android è un modo per far funzionare il codice dell'applicazione che non è legato ad una particolare attività e non ha bisogno di una propria interfaccia utente. Come un'attività, il codice in un servizio viene eseguito sul thread principale, pertanto è necessario eseguire normali tecniche di elaborazione in background per operazioni lunghe. Un Servizio può essere utilizzato tramite Intent o tramite binding e effettuando chiamate a metodi remoti. Il tipo di servizio che stiamo implementando è il migliore tramite la gestione dell'Intento.

Il nucleo di una classe di servizio ha due metodi da implementare, il metodo onStartCommand () e il metodo onBind (). Poiché non gestiamo l'associazione, gestiremo semplicemente onBind (). Ecco il nucleo del nostro servizio, inclusa l'implementazione di SensorEventListener:

 public class BaroLoggerService extends Service implementa SensorEventListener String statico finale privata DEBUG_TAG = "BaroLoggerService"; sensorManager privato sensorManager = null; sensore sensore privato = null; @Override public int onStartCommand (Intent intent, int flags, int startId) sensorManager = (SensorManager) getSystemService (SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor (Sensor.TYPE_PRESSURE); sensorManager.registerListener (this, sensor, SensorManager.SENSOR_DELAY_NORMAL); return START_STICKY;  @Override public IBinder onBind (Intent intent) return null;  @Override public void onAccuracyChanged (Sensore sensore, precisione int) // non fare nulla @Override pubblico void onSensorChanged (evento SensorEvent) // cattura i valori e timestamp // ... // interrompe il sensore e il servizio sensorManager.unregisterListener ( Questo); stopSelf (); 

Passaggio 2: registrazione dei dati in background

La scrittura di dati su disco è un'operazione di blocco e deve essere eseguita su un thread in background. Un modo semplice per farlo è attraverso un AsyncTask. All'interno del Servizio, possiamo aggiungere un AsyncTask e passarlo a SensorEvent per la gestione in questo modo:

 @Override public void onSensorChanged (evento SensorEvent) // cattura i valori e timestamp - off il nuovo thread SensorEventLoggerTask (). Execute (event); // interrompe il servizio stopSelf ();  classe privata SensorEventLoggerTask estende AsyncTask @Override protetto Void doInBackground (eventi SensorEvent ...) SensorEvent event = events [0]; // registra il valore

Passaggio 3: avvio di un servizio

Un servizio viene normalmente avviato tramite il metodo Context startService (). Ad esempio, il seguente lavoro funzionerebbe da una classe di attività:

 Intent intent = new Intent (getApplicationContext (), BaroLoggerService.class); StartService (intento);

Questo non è quello che vogliamo però. Desideriamo che il servizio venga eseguito solo occasionalmente, anche se l'applicazione non è in esecuzione e anche se il dispositivo è in modalità sospensione. La classe AlarmManager ci consente di farlo.


Passaggio 4: Pianificazione di un servizio ricorrente

La classe AlarmManager consente di pianificare gli eventi in modo ricorrente. Permette anche una pianificazione efficiente di molti eventi diversi, non solo il tuo, il che è un buon modo per ridurre l'uso della batteria.

Ecco il codice, che puoi inserire in un'attività sotto un gestore di pulsanti, ad esempio, per attivare il servizio da ripetere una volta all'ora:

 AlarmManager scheduler = (AlarmManager) getSystemService (Context.ALARM_SERVICE); Intent intent = new Intent (getApplicationContext (), BaroLoggerService.class); PendingIntent scheduledIntent = PendingIntent.getService (getApplicationContext (), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); scheduler.setInexactRepeating (AlarmManager.RTC_WAKEUP, System.currentTimeMillis (), AlarmManager.INTERVAL_HOUR, scheduledIntent);

Usiamo il metodo setInexactRepeating () con un intervallo definito in modo specifico, INTERVAL_HOUR, per sfruttare il sistema risvegliando molto più del nostro lavoro. Inoltre, utilizziamo l'opzione RTC_WAKEUP per indicare che vogliamo che il dispositivo venga svegliato per questo allarme, piuttosto che attendere finché non si riattiva per qualche altro motivo.

Inoltre, a scopo di test, abbiamo utilizzato un intervallo di un minuto, quindi non è stato necessario attendere diverse ore per raccogliere più punti dati.

Spegni l'allarme con una chiamata al metodo cancel () usando lo stesso intento:

 AlarmManager scheduler = (AlarmManager) getSystemService (Context.ALARM_SERVICE); Intento intenzionale = nuovo intento (questo, BaroLoggerService.class); PendingIntent scheduledIntent = PendingIntent.getService (getApplicationContext (), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); scheduler.cancel (scheduledIntent);

Puoi effettuare queste chiamate nel modo che preferisci. Abbiamo creato un paio di controlli pulsante che hanno chiamato metodi nella nostra attività con queste chiamate.


Conclusione

In questo tutorial, hai imparato a controllare regolarmente un valore del sensore in background utilizzando gli oggetti SensorManager, Service e AlarmManager. La serie continuerà con ulteriori informazioni sulla memorizzazione e la visualizzazione dei dati.

Come sfida, implementa questo codice da solo. Prova altri tipi di sensori supportati dal tuo dispositivo. Supporta TYPE_AMBIENT_TEMPERATURE? TYPE_RELATIVE_HUMIDITY? TYPE_LIGHT? Sarebbe utile registrare la posizione delle misure? Sii creativo e dicci cosa ti viene in mente nei commenti!


Riguardo agli Autori

Gli sviluppatori mobili Lauren Darcey e Shane Conder hanno coautore diversi libri sullo sviluppo di Android: un libro di programmazione approfondito intitolato Sviluppo di applicazioni wireless Android (ora nella sua terza edizione come set di due volumi) e Sams ti insegna a sviluppare applicazioni Android in 24 ore. Quando non scrivono, passano il loro tempo a sviluppare software mobile presso la loro azienda ea fornire servizi di consulenza. Possono essere contattati via email a [email protected], tramite il loro blog su androidbook.blogspot.com e su Twitter @androidwireless.

Hai bisogno di più aiuto nella scrittura di app per Android? Consulta i nostri ultimi libri e risorse!