La maggior parte dei dispositivi Android è dotata di sensori integrati che misurano il movimento, l'orientamento e in diverse condizioni ambientali. Questi sensori sono in grado di fornire dati non elaborati con precisione e accuratezza ed è utile se vuoi monitorare i movimenti tridimensionali del dispositivo o o monitorare i cambiamenti nell'ambiente circostante in prossimità di un dispositivo. Ad esempio, un il gioco potrebbe monitorare le letture del sensore di gravità di un dispositivo per dedurre gesti dell'utente complessi e movimenti come inclinazione, scuotimento, rotazione o swing. Allo stesso modo, un'applicazione meteo potrebbe utilizzare il sensore di temperatura e di umidità del dispositivo per calcolare e registrare il punto di rugiada o il percorso applicazione potrebbe utilizzare il sensore del campo geomagnetico e l'accelerometro per segnalare una bussola l'orientamento.
Consulta le seguenti risorse correlate:
La piattaforma Android supporta tre ampie categorie di sensori:
- Sensori di movimento
Questi sensori misurano le forze di accelerazione e di rotazione su tre assi. Questo comprende accelerometri, sensori di gravità, giroscopi e vettori di rotazione i sensori.
- Sensori ambientali
Questi sensori misurano vari parametri ambientali, come la temperatura dell'aria ambiente e pressione, illuminazione e umidità. Questa categoria include barometri, fotometri e termometri.
- Sensori di posizione
Questi sensori misurano la posizione fisica di un dispositivo. Questa categoria include sensori di orientamento e magnetometri.
Puoi accedere ai sensori disponibili sul dispositivo e acquisire dati non elaborati dei sensori utilizzando il dispositivo Android nella struttura dei sensori. Il framework dei sensori offre diverse classi e interfacce che consentono di eseguire una serie di attività legate ai sensori. Ad esempio, puoi utilizzare la struttura dei sensori per:
- Determina quali sensori sono disponibili su un dispositivo.
- Determinare le capacità di un singolo sensore, ad esempio la portata massima, il produttore, la potenza i requisiti e la risoluzione.
- Acquisisci dati non elaborati dei sensori e definisci la velocità minima alla quale acquisisci dati dei sensori.
- Registra e annulla la registrazione dei listener di eventi dei sensori che monitorano le variazioni dei sensori.
Questo argomento fornisce una panoramica dei sensori disponibili sulla piattaforma Android. Fornisce anche un'introduzione alla struttura dei sensori.
Introduzione ai sensori
Il framework dei sensori Android ti consente di accedere a molti tipi di sensori. Alcuni di questi sensori basate su hardware, mentre altre sono basate su software. I sensori basati su hardware sono componenti fisici in uno smartphone o tablet. Trattengono i dati misurando direttamente specifici come accelerazione, intensità del campo geomagnetico o variazione angolare. Basato su software I sensori non sono dispositivi fisici, anche se imitano i sensori basati su hardware. Sensori basati su software ricavano i dati da uno o più sensori basati sull'hardware e a volte sono chiamati o sensori sintetici. Il sensore di accelerazione lineare e il sensore di gravità sono esempi di basati su software. La tabella 1 riassume i sensori supportati da Android completamente gestita.
Pochi dispositivi Android dispongono di sensori di ogni tipo. Ad esempio, la maggior parte dei telefoni e tablet dispongono di un accelerometro e un magnetometro, ma meno dispositivi hanno barometri o termometri. Inoltre, un dispositivo può avere più di un sensore di un determinato tipo. Per Ad esempio, un dispositivo può avere due sensori di gravità, ognuno con una portata diversa.
Sensore | Tipo | Descrizione | Utilizzi comuni |
---|---|---|---|
TYPE_ACCELEROMETER |
Hardware | Misura la forza di accelerazione in m/s2 applicata a un dispositivo su tutti e tre gli assi fisici (x, y e z), inclusa la forza di gravità. | Rilevamento dei movimenti (scosse, inclinazione e così via). |
TYPE_AMBIENT_TEMPERATURE |
Hardware | Misura la temperatura ambientale in una stanza in gradi Celsius (°C). Vedi nota di seguito. | Monitoraggio della temperatura dell'aria. |
TYPE_GRAVITY |
Software o hardware | Misura la forza di gravità in m/s2 applicata a un dispositivo su tre assi fisici (x, y, z). | Rilevamento dei movimenti (scosse, inclinazione e così via). |
TYPE_GYROSCOPE |
Hardware | Misura la velocità di rotazione di un dispositivo in rad/s intorno a ognuno dei tre assi fisici (x, y e z). | Rilevamento della rotazione (rotazione, rotazione e così via). |
TYPE_LIGHT |
Hardware | Misura il livello di luce ambientale (illuminazione) in lx. | Controllo della luminosità dello schermo. |
TYPE_LINEAR_ACCELERATION |
Software o hardware | Misura la forza di accelerazione in m/s2 che è applicata a un dispositivo su tutti e tre gli assi fisici (x, y e z), esclusa la forza di gravità. | Monitoraggio dell'accelerazione lungo un singolo asse. |
TYPE_MAGNETIC_FIELD |
Hardware | Misura il campo geomagnetico ambientale per tutti e tre gli assi fisici (x, y, z) in μT. | Creazione di una bussola. |
TYPE_ORIENTATION |
Software | Misura i gradi di rotazione effettuati da un dispositivo attorno a tutti e tre gli assi fisici (x, y, z).
A partire dal livello API 3 è possibile ottenere la matrice di inclinazione e la matrice di rotazione per
di un dispositivo utilizzando il sensore di gravità e il sensore del campo geomagnetico insieme
getRotationMatrix()
. |
Determinazione della posizione del dispositivo. |
TYPE_PRESSURE |
Hardware | Misura la pressione dell'aria ambiente in hPa o mbar. | Monitoraggio delle variazioni della pressione atmosferica. |
TYPE_PROXIMITY |
Hardware | Misura la vicinanza di un oggetto in cm rispetto alla schermata di un dispositivo. Questo sensore viene tipicamente utilizzato per determinare se lo smartphone viene tenuto in posizione all'orecchio di una persona. | Posizione dello smartphone durante una chiamata. |
TYPE_RELATIVE_HUMIDITY |
Hardware | Misura l'umidità relativa dell'ambiente in percentuale (%). | Monitoraggio del punto di rugiada, dell'umidità assoluta e dell'umidità relativa. |
TYPE_ROTATION_VECTOR |
Software o hardware | Misura l'orientamento di un dispositivo fornendo i tre elementi del vettore di rotazione. | Rilevamento dei movimenti e della rotazione. |
TYPE_TEMPERATURE |
Hardware | Misura la temperatura del dispositivo in gradi Celsius (°C). Questo sensore
l'implementazione varia da un dispositivo all'altro
questo sensore è stato sostituito con il sensore TYPE_AMBIENT_TEMPERATURE in
Livello API 14 |
Monitoraggio delle temperature. |
Struttura del sensore
Puoi accedere a questi sensori e acquisire dati non elaborati dei sensori utilizzando il framework dei sensori di Android.
Il framework dei sensori fa parte del pacchetto android.hardware
e include quanto segue
classi e interfacce:
SensorManager
- Puoi usare questa lezione per creare un'istanza del servizio dei sensori. Questo corso fornisce vari metodi per accedere ed elencare i sensori, registrare e annullare la registrazione degli eventi dei sensori ascoltatori e l'acquisizione di informazioni sull'orientamento. Questa classe fornisce anche diverse costanti utilizzate per segnalare la precisione dei sensori, impostare le frequenze di acquisizione dei dati e calibrare i sensori.
Sensor
- Puoi usare questa lezione per creare un'istanza di un sensore specifico. Questo corso offre vari metodi che consentono di determinare le capacità di un sensore.
SensorEvent
- Il sistema usa questa classe per creare un oggetto evento sensore, che fornisce informazioni su un un evento del sensore. Un oggetto evento del sensore include le seguenti informazioni: i dati non elaborati del sensore, tipo di sensore che ha generato l'evento, l'accuratezza dei dati e il timestamp del .
SensorEventListener
- Puoi utilizzare questa interfaccia per creare due metodi di callback che ricevono notifiche (sensore eventi) quando i valori dei sensori cambiano o la precisione di questi ultimi.
In un'applicazione tipica, vengono usate queste API relative ai sensori per eseguire due attività di base:
- Identificare i sensori e le funzionalità dei sensori
L'identificazione dei sensori e delle relative funzionalità in fase di runtime è utile se l'applicazione ha che si basano su funzionalità o tipi di sensori specifici. Ad esempio, potresti voler identificare tutti i sensori presenti su un dispositivo e disattivare tutte le funzionalità dell'applicazione che si basano su sensori non presenti. Allo stesso modo, ti consigliamo di identificare tutti i sensori di un determinato tipo, per consentirti di scegliere l'implementazione del sensore con le prestazioni ottimali per la tua applicazione.
- Monitorare gli eventi dei sensori
Il monitoraggio degli eventi dei sensori è il modo in cui acquisisci i dati non elaborati dei sensori. Ogni volta si verifica un evento del sensore Un sensore rileva una variazione dei parametri che sta misurando. Un evento del sensore ti fornisce con quattro informazioni: il nome del sensore che ha attivato l'evento, il timestamp relativo all'evento, l'accuratezza dell'evento e i dati non elaborati dei sensori che hanno attivato l'evento.
Disponibilità dei sensori
Anche se la disponibilità dei sensori varia da dispositivo a dispositivo, può variare anche tra Android e versioni successive. Questo perché i sensori Android sono stati introdotti nel corso di di Google Cloud. Ad esempio, in Android 1.5 (livello API 3) sono stati introdotti molti sensori, ma alcuni non erano state implementate e non erano disponibili per l'uso fino ad Android 2.3 (livello API 9). Analogamente, diversi sensori sono stati introdotti in Android 2.3 (livello API 9) e Android 4.0 (livello API 14). Due. sensori sono stati ritirati e sostituiti con sensori più recenti e migliori.
La Tabella 2 riassume la disponibilità di ciascun sensore piattaforma per piattaforma. Solo quattro piattaforme sono elencate perché sono quelle che hanno comportato i cambiamenti dei sensori. Sensori che elencate come deprecate sono ancora disponibili su piattaforme successive (a condizione che i su un dispositivo), in linea con i criteri di compatibilità avanzata di Android.
Sensore | Android 4.0 (livello API 14) |
Android 2.3 (livello API 9) |
Android 2.2 (livello API 8) |
Android 1.5 (livello API 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
Sì | Sì | Sì | Sì |
TYPE_AMBIENT_TEMPERATURE |
Sì | n/a | n/d | n/a |
TYPE_GRAVITY |
Sì | Sì | n/a | n/a |
TYPE_GYROSCOPE |
Sì | Sì | N/D1 | N/D1 |
TYPE_LIGHT |
Sì | Sì | Sì | Sì |
TYPE_LINEAR_ACCELERATION |
Sì | Sì | n/a | n/a |
TYPE_MAGNETIC_FIELD |
Sì | Sì | Sì | Sì |
TYPE_ORIENTATION |
Sì2 | Sì2 | Sì2 | Sì |
TYPE_PRESSURE |
Sì | Sì | N/D1 | N/D1 |
TYPE_PROXIMITY |
Sì | Sì | Sì | Sì |
TYPE_RELATIVE_HUMIDITY |
Sì | n/a | n/d | n/a |
TYPE_ROTATION_VECTOR |
Sì | Sì | n/a | n/a |
TYPE_TEMPERATURE |
Sì2 | Sì | Sì | Sì |
1 Questo tipo di sensore è stato aggiunto ad Android 1.5 (livello API 3), ma non era disponibile per l'uso fino ad Android 2.3 (livello API 9).
2 Questo sensore è disponibile, ma è stato ritirato.
Identificazione dei sensori e delle loro funzionalità
La struttura dei sensori Android offre diversi metodi che ti consentono di stabilire runtime quali sensori sono presenti su un dispositivo. L'API fornisce anche metodi che ti consentono di determinare capacità di ciascun sensore, come la portata massima, la risoluzione e la potenza i tuoi requisiti.
Per identificare i sensori presenti su un dispositivo, devi prima ottenere un riferimento al sensore
completamente gestito di Google Cloud. Per farlo, devi creare un'istanza della classe SensorManager
chiamando il metodo getSystemService()
e passando
nell'argomento SENSOR_SERVICE
. Ad esempio:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Dopodiché puoi visualizzare un elenco di tutti i sensori di un dispositivo chiamando il
getSensorList()
e utilizzando la costante TYPE_ALL
. Ad esempio:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Se vuoi elencare tutti i sensori di un determinato tipo, puoi utilizzare un'altra costante anziché
TYPE_ALL
, ad esempio TYPE_GYROSCOPE
,
TYPE_LINEAR_ACCELERATION
, oppure
TYPE_GRAVITY
.
Puoi anche determinare se su un dispositivo è presente un tipo specifico di sensore utilizzando il metodo getDefaultSensor()
e passando il tipo
costante per un sensore specifico. Se un dispositivo è dotato di più sensori di uno stesso tipo, uno dei
devono essere designati come sensori predefiniti. Se non esiste un sensore predefinito per un determinato
tipo di sensore, la chiamata al metodo restituisce un valore nullo, il che significa che il dispositivo non ha quel tipo di
sensore. Ad esempio, il seguente codice verifica se sul dispositivo è presente un magnetometro:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) { // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){ // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Nota:Android non richiede ai produttori di dispositivi di creare determinati tipi di sensori nei loro dispositivi Android, in modo che i dispositivi possano avere un'ampia gamma configurazioni dei sensori.
Oltre a elencare i sensori presenti su un dispositivo, puoi usare i metodi pubblici del
Classe Sensor
per determinare le capacità e gli attributi dei singoli
i sensori. Ciò è utile se vuoi che l'applicazione si comporti in modo diverso in base ai sensori o
funzionalità dei sensori sono disponibili
su un dispositivo. Ad esempio, puoi utilizzare getResolution()
e getMaximumRange()
metodi per ottenere la risoluzione di un sensore e il raggio massimo di misurazione. Puoi utilizzare anche
getPower()
metodo per ottenere i requisiti di alimentazione di un sensore.
Due dei metodi pubblici sono particolarmente utili se vuoi ottimizzare la tua applicazione
sensori di produttori diversi o versioni diverse di un sensore. Ad esempio, se la tua applicazione
non devi monitorare i gesti dell'utente, come l'inclinazione o lo scuotimento, potresti creare un
regole e ottimizzazioni per i dispositivi più recenti dotati di sensore di gravità di un fornitore specifico e un altro
insieme di regole di filtraggio dei dati e ottimizzazioni per i dispositivi privi di sensore di gravità e
solo un accelerometro. Il seguente esempio di codice mostra come eseguire questa operazione con i metodi getVendor()
e getVersion()
questo. In questo esempio, stiamo cercando un sensore di gravità che indichi Google LLC come fornitore e
il cui numero di versione è 3. Se quel particolare sensore non è presente sul dispositivo, tenteremo di utilizzare
sull'accelerometro.
Kotlin
private lateinit var sensorManager: SensorManager private var mSensor: Sensor? = null ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) { val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY) // Use the version 3 gravity sensor. mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 } } if (mSensor == null) { // Use the accelerometer. mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } else { // Sorry, there are no accelerometers on your device. // You can't play this game. null } }
Java
private SensorManager sensorManager; private Sensor mSensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensor = null; if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){ List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); for(int i=0; i<gravSensors.size(); i++) { if ((gravSensors.get(i).getVendor().contains("Google LLC")) && (gravSensors.get(i).getVersion() == 3)){ // Use the version 3 gravity sensor. mSensor = gravSensors.get(i); } } } if (mSensor == null){ // Use the accelerometer. if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){ mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } else{ // Sorry, there are no accelerometers on your device. // You can't play this game. } }
Un altro metodo utile è getMinDelay()
,
che restituisce l'intervallo di tempo minimo (in microsecondi) che un sensore può utilizzare per rilevare i dati. Qualsiasi sensore
che restituisce un valore diverso da zero per l'attributo getMinDelay()
è un flusso di dati
sensore. I sensori di streaming rilevano i dati a intervalli regolari e sono stati introdotti in Android 2.3 (API
livello 9). Se un sensore restituisce uno zero quando chiami il metodo getMinDelay()
, significa che
non è un sensore di flusso perché riporta i dati solo quando c'è una modifica della
i parametri che sta rilevando.
Il metodo getMinDelay()
è utile perché consente
viene stabilito il numero massimo di pod
a cui un sensore può acquisire dati. Se alcune funzionalità della tua applicazione richiedono un volume di dati elevato
o un sensore di streaming, puoi usare questo metodo per determinare se un sensore
soddisfa questi requisiti e attiva o disattiva le funzionalità pertinenti nella tua applicazione
di conseguenza.
Attenzione:la frequenza massima di acquisizione dei dati di un sensore non è necessariamente la velocità con cui il framework dei sensori invia i dati dei sensori all'applicazione. La framework dei sensori riporta i dati attraverso gli eventi dei sensori e diversi fattori influenzano la velocità con cui l'applicazione riceve gli eventi dei sensori. Per ulteriori informazioni, consulta la sezione Monitoraggio degli eventi dei sensori.
Monitoraggio degli eventi dei sensori
Per monitorare i dati non elaborati dei sensori devi implementare due metodi di callback esposti
l'interfaccia di SensorEventListener
: onAccuracyChanged()
e onSensorChanged()
. Il sistema Android chiama
questi metodi ogni volta che si verifica quanto segue:
- La precisione di un sensore cambia.
In questo caso il sistema richiama il metodo
onAccuracyChanged()
, fornendo con un riferimento all'oggettoSensor
che è stato modificato e nuova precisione del sensore. La precisione è rappresentata da una delle quattro costanti di stato:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, oSENSOR_STATUS_UNRELIABLE
. - Un sensore segnala un nuovo valore.
In questo caso il sistema richiama il metodo
onSensorChanged()
, fornendoti un oggettoSensorEvent
. Un oggettoSensorEvent
contiene informazioni sui nuovi dati dei sensori, tra cui: l'accuratezza dei dati, il sensore che ha generato i dati, il timestamp in cui sono stati generati i dati e il nuovo registrati dal sensore.
Il seguente codice mostra come utilizzare il metodo onSensorChanged()
per monitorare i dati da
il sensore di luce. Questo esempio mostra i dati non elaborati del sensore in un TextView
ovvero
definita nel file main.xml come sensor_data
.
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); } }
In questo esempio, il ritardo dei dati predefinito (SENSOR_DELAY_NORMAL
) viene specificato quando viene richiamato il metodo registerListener()
. I dati
il ritardo (o frequenza di campionamento) controlla l'intervallo con cui gli eventi del sensore vengono inviati all'applicazione
tramite il metodo di callback onSensorChanged()
. Il valore predefinito
il ritardo dei dati è adatto per il monitoraggio
l'orientamento dello schermo tipico cambia e utilizza un ritardo di 200.000 microsecondi. Puoi specificare altre
ritardi nei dati, ad esempio SENSOR_DELAY_GAME
(20.000 microsecondi
), SENSOR_DELAY_UI
(ritardo di 60.000 microsecondi) o SENSOR_DELAY_FASTEST
(ritardo di 0 microsecondi). A partire da Android 3.0 (API)
livello 11) puoi anche specificare il ritardo come valore assoluto (in microsecondi).
Il ritardo specificato è solo un ritardo suggerito. Il sistema Android e altre applicazioni possono alterare questo ritardo. Come best practice, devi specificare il ritardo maggiore possibile il sistema utilizza generalmente un ritardo inferiore a quello specificato (ovvero, devi scegliere il parametro la frequenza di campionamento più lenta che comunque soddisfa le esigenze della tua applicazione). L'utilizzo di un ritardo maggiore impone meno carico sul processore e quindi consuma meno.
Non esiste un metodo pubblico per determinare la frequenza di invio del framework dei sensori eventi dei sensori alla tua applicazione; ma puoi usare i timestamp associati a ogni dell'evento dei sensori per calcolare la frequenza di campionamento per diversi eventi. Non devi modificare e la frequenza di campionamento (ritardo) impostata. Se, per qualche motivo, avessi la necessità di modificare il ritardo, annullare la registrazione e registrare di nuovo il listener del sensore.
È importante notare inoltre che in questo esempio vengono utilizzati i valori onResume()
e
onPause()
metodi di callback per registrare e annullare la registrazione dell'evento del sensore
e ascolto. Come best practice, dovresti sempre disattivare i sensori di cui non hai bisogno, soprattutto quando
l'attività è in pausa. In caso contrario, la batteria potrebbe esaurirsi nel giro di poche ore a causa del fatto che alcuni sensori
hanno requisiti di alimentazione notevoli e possono consumare rapidamente la batteria. Il sistema
non disattiva automaticamente i sensori allo spegnimento dello schermo.
Gestione di diverse configurazioni dei sensori
Android non specifica una configurazione standard dei sensori per i dispositivi Ciò significa che i produttori di dispositivi possono integrare la configurazione del sensore che desiderano Dispositivi con tecnologia Android. Di conseguenza, i dispositivi possono includere una di sensori in un'ampia gamma di configurazioni. Se la tua applicazione si basa su un tipo specifico di sensore, devi assicurarti che sensore è presente su un dispositivo per consentire il corretto funzionamento dell'app.
Esistono due opzioni per garantire la presenza di un determinato sensore su un dispositivo:
- Rileva i sensori in fase di runtime e attiva o disattiva le funzionalità dell'applicazione in base alle esigenze.
- Usa i filtri di Google Play per scegliere come target dispositivi con configurazioni specifiche dei sensori.
Ciascuna opzione viene discussa nelle sezioni seguenti.
Rilevamento dei sensori in fase di esecuzione
Se la tua applicazione utilizza un tipo specifico di sensore, ma non lo utilizza, puoi utilizzare framework dei sensori per rilevare il sensore in fase di esecuzione e poi disabilitare o abilitare le funzionalità dell'applicazione in base alle necessità. Ad esempio, un'applicazione di navigazione potrebbe usare il sensore di temperatura, sensore di pressione, sensore GPS e sensore di campo geomagnetico per visualizzare la temperatura, barometrico pressione, posizione e orientamento della bussola. Se un dispositivo non dispone di un sensore di pressione, puoi utilizzare per rilevare l'assenza del sensore di pressione in fase di esecuzione, quindi disattivare parte dell'interfaccia utente dell'applicazione che mostra la pressione. Ad esempio, il seguente codice controlla se è presente un sensore di pressione su un dispositivo:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) { // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){ // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Usare i filtri di Google Play per scegliere configurazioni specifiche dei sensori come target
Se pubblichi la tua applicazione su Google Play puoi utilizzare la
L'elemento <uses-feature>
nel file manifest per filtrare l'applicazione in base ai dispositivi che non lo utilizzano.
la configurazione del sensore adatta alla tua applicazione. La
L'elemento <uses-feature>
ha diversi descrittori hardware che ti consentono di filtrare
alle applicazioni basate sulla presenza di sensori specifici. I sensori che puoi elencare includono:
accelerometro, barometro, bussola (campo geomagnetico), giroscopio, luce e prossimità. La
Di seguito è riportato un esempio di voce del file manifest che filtra le app prive di accelerometro:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Se aggiungi questo elemento e descrittore al file manifest dell'applicazione, gli utenti vedranno il tuo su Google Play solo se il dispositivo dispone di un accelerometro.
Devi impostare il descrittore su android:required="true"
solo se la tua applicazione
si basa interamente su un sensore specifico. Se la tua applicazione usa un sensore per alcune funzionalità, ma
funziona ancora senza il sensore, dovresti elencare il sensore nella <uses-feature>
ma imposta il descrittore su android:required="false"
. Questo aiuta a garantire che
i dispositivi possono installare la tua app anche se non sono dotati di quel particolare sensore. Questo è anche un
best practice per la gestione dei progetti, che ti aiuta a tenere traccia delle funzionalità utilizzate dalla tua applicazione.
Tieni presente che se la tua applicazione utilizza un determinato sensore, ma funziona ancora senza il sensore,
devi rilevare il sensore in fase di esecuzione e disabilitare o abilitare le funzionalità dell'applicazione
appropriato.
Sistema di coordinate del sensore
In generale, la struttura dei sensori utilizza un sistema di coordinate standard a 3 assi per esprimere i valori dei dati. Per la maggior parte dei sensori, il sistema di coordinate è definito in base allo schermo del dispositivo quando quest'ultimo viene mantenuto nell'orientamento predefinito (vedi figura 1). Quando un dispositivo viene mantenuto nell'orientamento predefinito, l'asse X è orizzontale e punta a destra, l'asse Y è verticale e punta verso l'alto e l'asse Z rivolto verso l'esterno della faccia dello schermo. In questo sistema, le coordinate dietro lo schermo hanno valori Z negativi. Questo sistema di coordinate viene utilizzato dai seguenti sensori:
- Accelerazione sensore
- Gravità sensore
- Giroscopio
- Accelerazione lineare sensore
- Campo geomagnetico sensore
Il punto più importante da comprendere in merito a questo sistema di coordinate è che gli assi non sono scambiato quando l'orientamento dello schermo del dispositivo cambia, ovvero il sistema di coordinate del sensore non cambia mai mentre il dispositivo si muove. Si tratta dello stesso comportamento della finestra OpenGL sistema di coordinate di rete.
Un altro punto da capire è che la tua applicazione non deve presupporre che l'aspetto naturale (predefinito) l'orientamento è verticale. L'orientamento naturale di molti tablet è orizzontale. e il sistema di coordinate del sensore si basa sempre sull'orientamento naturale di un dispositivo.
Infine, se l'applicazione associa i dati dei sensori al display sullo schermo, devi utilizzare
getRotation()
per determinare la rotazione dello schermo, quindi usa il
remapCoordinateSystem()
metodo da mappare
le coordinate del sensore
per filtrare le coordinate. Devi eseguire questa operazione anche se il file manifest specifica
solo verticale.
Nota:alcuni sensori e metodi utilizzano un sistema di coordinate che viene
rispetto al riferimento globale (piuttosto che a quello del dispositivo). Questi
I sensori e i metodi restituiscono dati che rappresentano il movimento o la posizione del dispositivo in relazione
terra. Per ulteriori informazioni, vedi il metodo getOrientation()
, il metodo getRotationMatrix()
, Orientamento
Sensore e Vettore di rotazione
Sensore.
Limitazione della frequenza dei sensori
Per proteggere le informazioni potenzialmente sensibili degli utenti, se la tua app ha come target Android 12 (livello API 31) o versioni successive, il sistema pone un limite all'aggiornamento la velocità dei dati da determinati sensori di movimento e sensori di posizione. Questi dati include i valori registrati dal accelerometro, giroscopio e campo geomagnetico sensore.
Il limite di frequenza di aggiornamento dipende dal modo in cui accedi ai dati del sensore:
- Se chiami
registerListener()
per monitorare gli eventi del sensore, la frequenza di campionamento del sensore è a 200 Hz. Questo vale per tutte le varianti sovraccaricate MetodoregisterListener()
. - Se utilizzi
SensorDirectChannel
, la frequenza di campionamento del sensore è limitataRATE_NORMAL
, che in genere è di circa 50 Hz.
Se la tua app deve raccogliere i dati dei sensori di movimento a una velocità maggiore, devi
dichiara il
HIGH_SAMPLING_RATE_SENSORS
come mostrato nello snippet di codice riportato di seguito. Altrimenti, se la tua app prova a
di raccogliere i dati dei sensori di movimento a una velocità maggiore senza dichiarare questa autorizzazione,
si verifica un SecurityException
.
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Best practice per l'accesso e l'utilizzo dei sensori
Durante la progettazione dell'implementazione dei sensori, assicurati di seguire le linee guida descritte in questa sezione. Queste linee guida sono best practice consigliate a chiunque utilizzi il sensore per accedere ai sensori e acquisire i dati dei sensori.
Raccogli i dati dei sensori solo in primo piano
Sui dispositivi con Android 9 (livello API 28) o versioni successive, le app in esecuzione in di sfondo presentano le seguenti limitazioni:
- Sensori che utilizzano continua come accelerometri e giroscopi, non ricevono eventi.
- Sensori che utilizzano in caso di variazione o one-shot modalità di reporting non ricevono eventi.
Date queste limitazioni, è meglio rilevare gli eventi dei sensori quando il sia in primo piano o nell'ambito di un servizio in primo piano.
Annulla la registrazione dei listener dei sensori
Assicurati di annullare la registrazione del listener di un sensore quando hai finito di utilizzare il sensore o quando
l'attività viene messa in pausa. Se un listener dei sensori è registrato e la sua attività è in pausa,
ad acquisire dati e a utilizzare le risorse della batteria, a meno che non annulli la registrazione del sensore. Le seguenti
mostra come utilizzare il metodo onPause()
per annullare la registrazione di un listener:
Kotlin
private lateinit var sensorManager: SensorManager ... override fun onPause() { super.onPause() sensorManager.unregisterListener(this) }
Java
private SensorManager sensorManager; ... @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
Per ulteriori informazioni, vedi unregisterListener(SensorEventListener)
.
Esegui test con l'emulatore Android
Android Emulator include una serie di controlli per sensori virtuali che consentono di testare sensori come accelerometro, temperatura ambiente, magnetometro, vicinanza, luce e altro.
L'emulatore utilizza una connessione con un dispositivo Android che esegue SdkControllerSensor dell'app. Tieni presente che questa app è disponibile solo su dispositivi con Android 4.0 (API livello 14) o superiore. (Se il dispositivo utilizza Android 4.0, deve avere Revisione 2 installata. L'app SdkControllerSensor monitora le variazioni i sensori sul dispositivo e li trasmette all'emulatore. L'emulatore è viene poi trasformato in base ai nuovi valori che riceve dai sensori il tuo dispositivo.
Puoi visualizzare il codice sorgente per l'app SdkControllerSensor nella seguente luogo:
$ your-android-sdk-directory/tools/apps/SdkController
Per trasferire i dati tra il tuo dispositivo e l'emulatore, segui questi passaggi passaggi:
- Controlla che la porta USB il debug sia attivato sul tuo dispositivo.
- Collega il dispositivo alla macchina di sviluppo usando un cavo USB.
- Avvia l'app SdkControllerSensor sul tuo dispositivo.
- Nell'app, seleziona i sensori che vuoi emulare.
Esegui questo comando
adb
:- Avvia l'emulatore. Ora dovresti essere in grado di applicare le trasformazioni emulatore spostando il dispositivo.
$ adb forward tcp:1968 tcp:1968
Nota: se i movimenti che fai verso la
dispositivo fisico non sta trasformando l'emulatore, prova a eseguire
adb
dal passaggio 5.
Per ulteriori informazioni, vedi Android Guida dell'emulatore.
Non bloccare il metodo onSensorChanged()
I dati dei sensori possono variare con una frequenza elevata, il che significa che il sistema potrebbe chiamare il metodo onSensorChanged(SensorEvent)
abbastanza spesso. Come best practice,
dovrebbe fare il meno possibile con il metodo onSensorChanged(SensorEvent)
in modo da non bloccarlo. Se le tue
richiede l'applicazione di filtri o riduzione dei dati dei sensori, è necessario eseguire
che funzionano al di fuori del metodo onSensorChanged(SensorEvent)
.
Evita di utilizzare metodi o tipi di sensori deprecati
Diversi metodi e costanti sono stati ritirati.
In particolare, TYPE_ORIENTATION
tipo di sensore è stato ritirato. Per ottenere dati sull'orientamento, devi usare il metodo getOrientation()
. Analogamente,
Il tipo di sensore TYPE_TEMPERATURE
è stato deprecato. Dovresti usare
il tipo di sensore TYPE_AMBIENT_TEMPERATURE
sui dispositivi
che eseguono Android 4.0.
Verifica i sensori prima di utilizzarli
Verifica sempre che su un dispositivo sia presente un sensore prima di tentare di acquisirne i dati. Azioni sconsigliate presumere che un sensore esista semplicemente perché è un sensore di uso frequente. I produttori di dispositivi non è necessario fornire sensori particolari nei dispositivi.
Scegli con attenzione i ritardi dei sensori
Quando registri un sensore con il metodo registerListener()
, assicurati di scegliere una velocità di consegna adatta al tuo
un'applicazione o un caso d'uso. I sensori possono fornire dati a velocità molto elevate. Consenti al sistema di inviare
i dati aggiuntivi che non ti servono sprecano risorse di sistema e consumano la batteria.