Większość urządzeń z Androidem ma wbudowane czujniki do pomiaru ruchu, orientacji, i różnych warunkach środowiskowych. Czujniki te są w stanie dostarczać nieprzetworzone dane o wysokiej precyzji i dokładności. Przydają się przy monitorowaniu trójwymiarowego ruchu urządzenia lub lub monitorować zmiany w środowisku otoczenia w pobliżu urządzenia. Na przykład plik gra może śledzić odczyty z czujnika grawitacji urządzenia, aby wywnioskować złożone gesty użytkownika takich jak pochylenie, potrząśnięcie, obrót i zamach. Podobnie aplikacja pogodowa może używać czujnika temperatury i wilgotności w urządzeniu do obliczania i zgłaszania punktu rosy lub podróży aplikacja może używać czujnika pola geomagnetycznego i akcelerometru do wskazania kompasu ducha.
Zapoznaj się z tymi powiązanymi materiałami:
Platforma Android obsługuje trzy ogólne kategorie czujników:
- Czujniki ruchu
Czujniki te mierzą siły przyspieszenia i siły obrotowe wzdłuż 3 osi. Ten kategoria obejmuje akcelerometry, czujniki grawitacji, żyroskopy i wektor obrotowy i czujników.
- Czujniki środowiskowe
Czujniki mierzą różne parametry środowiskowe, takie jak temperatura otoczenia oraz ciśnienie, oświetlenie i wilgotność. Do tej kategorii należą: barometry, fotometry termometrów.
- Czujniki pozycji
Te czujniki mierzą fizyczne położenie urządzenia. Ta kategoria obejmuje czujniki orientacji i magnetometry.
Za pomocą urządzenia z Androidem można uzyskać dostęp do czujników w urządzeniu i pobrać nieprzetworzone dane z czujników platformy czujnika. Struktura czujnika udostępnia kilka klas i interfejsów, które ułatwiają wykonanie wykonywać wiele zadań związanych z czujnikami. Za pomocą konstrukcji czujnika można na przykład:
- Ustal, które czujniki są dostępne w urządzeniu.
- Określ możliwości pojedynczego czujnika, takie jak jego maksymalny zasięg, producenta, moc i rozwiązywania problemów.
- Uzyskiwanie nieprzetworzonych danych z czujnika i określanie minimalnej częstotliwości ich pozyskiwania.
- Rejestrowanie i wyrejestrowywanie detektorów zdarzeń czujnika, które monitorują zmiany czujników.
W tej części opisujemy czujniki dostępne na platformie Android. Przedstawiamy w nim też konstrukcję czujnika.
Wprowadzenie do czujników
Platforma czujników w Androidzie zapewnia dostęp do wielu typów czujników. Niektóre z tych czujników są są oparte na sprzęcie, a niektóre na oprogramowaniu. Sprzętowe czujniki to fizyczne komponenty zaprojektowane do telefonu lub tabletu. Dane czerpią bezpośrednio z pomiarów środowiska takie jak przyspieszenie, siła pola geomagnetycznego czy zmiana kątowa. Oparte na oprogramowaniu Czujniki nie są urządzeniami fizycznymi, chociaż imitują czujniki sprzętowe. Czujniki programowe czerpią dane z jednego lub kilku czujników sprzętowych i czasami są nazywane czujniki lub czujniki syntetyczne. Czujnik przyspieszenia liniowego i czujnik grawitacji to przykłady czujnikach opartych na oprogramowaniu. W tabeli 1 znajdziesz podsumowanie czujników obsługiwanych przez system Android. platformy.
Niewiele urządzeń z Androidem ma czujniki każdego typu. Na przykład większość telefonów Tablety mają akcelerometr i magnetometr, ale mniej urządzeń np. barometrów czy termometrów. Oprócz tego urządzenie może mieć więcej niż 1 czujnik danego typu. Dla: urządzenie może mieć np. dwa czujniki grawitacji, z których każdy ma inny zakres.
Tabela 1. Typy czujników obsługiwane przez platformę Androida.
Czujnik | Typ | Opis | Częste zastosowania |
---|---|---|---|
TYPE_ACCELEROMETER |
Sprzęt | Mierzy siłę przyspieszenia w m/s2, która jest stosowana do urządzenia wszystkich 3 osie fizycznych (x, y i z), w tym siły grawitacji. | Wykrywanie ruchu (potrząśnięcie, pochylenie itp.). |
TYPE_AMBIENT_TEMPERATURE |
Sprzęt | Mierzy temperaturę otoczenia w stopniach Celsjusza (°C). Zobacz uwagę poniżej. | Monitoruję temperatury powietrza. |
TYPE_GRAVITY |
Oprogramowanie lub sprzęt | Mierzy siłę grawitacji w m/s2, która jest stosowana do urządzenia na wszystkich urządzeniach 3 osie fizyczne (x, y, z). | Wykrywanie ruchu (potrząśnięcie, pochylenie itp.). |
TYPE_GYROSCOPE |
Sprzęt | Mierzy szybkość obrotu urządzenia w rad/s wokół każdego z trzech z nich osie fizyczne (x, y i z). | Wykrywanie obrotu (obrót, obrót itp.). |
TYPE_LIGHT |
Sprzęt | Mierzy poziom jasności otoczenia (oświetlenie) w lx. | Sterowanie jasnością ekranu |
TYPE_LINEAR_ACCELERATION |
Oprogramowanie lub sprzęt | Mierzy siłę przyspieszenia w m/s2, która jest zastosowano na urządzeniu na wszystkich trzech osi fizycznych (x, y i z), z wyłączeniem siły grawitacji. | Monitorowanie przyspieszenia na jednej osi. |
TYPE_MAGNETIC_FIELD |
Sprzęt | Mierzy pole geomagnetyczne otoczenia dla wszystkich 3 osi fizycznych (x, y, z) w μT. | Tworzę kompas. |
TYPE_ORIENTATION |
Oprogramowanie | Mierzy stopnie obrotu urządzenia wokół wszystkich 3 osi fizycznych (x, y, z).
Od poziomu 3 interfejsu API można uzyskać macierz pochylenia i obrotu dla
urządzenia za pomocą czujnika grawitacji i czujnika pola geomagnetycznego w połączeniu z
getRotationMatrix()
. |
Określanie pozycji urządzenia. |
TYPE_PRESSURE |
Sprzęt | Mierzy ciśnienie powietrza w otoczeniu w hPa lub mbar. | Monitorowanie zmian ciśnienia. |
TYPE_PROXIMITY |
Sprzęt | Mierzy odległość obiektu w cm w odniesieniu do ekranu widoku urządzenia. Czujnik zwykle służy do określania, czy podnosisz słuchawkę czyjegoś ucha. | Pozycja telefonu podczas połączenia. |
TYPE_RELATIVE_HUMIDITY |
Sprzęt | Mierzy względną wilgotność otoczenia w procentach (%). | Monitoruję punkt rosy oraz wilgotność bezwzględną i względną. |
TYPE_ROTATION_VECTOR |
Oprogramowanie lub sprzęt | Mierzy orientację urządzenia, przesyłając 3 elementy: wektora obrotu. | Wykrywanie ruchu i obrotu. |
TYPE_TEMPERATURE |
Sprzęt | Mierzy temperaturę urządzenia w stopniach Celsjusza (°C). Ten czujnik
implementacja może się różnić w zależności od urządzenia
ten czujnik został zastąpiony czujnikiem TYPE_AMBIENT_TEMPERATURE w:
Poziom API 14 |
Monitoruję temperatury. |
Platforma czujników
Możesz uzyskać dostęp do tych czujników i pobierać nieprzetworzone dane z czujników, korzystając z platformy czujników w Androidzie.
Układ czujnika jest częścią pakietu android.hardware
i obejmuje:
klas i interfejsów:
SensorManager
- Za pomocą tej klasy możesz utworzyć instancję usługi czujnika. Te zajęcia: różne metody dostępu do czujników i ich wyświetlania, rejestrowania i wyrejestrowania zdarzeń czujnika słuchaczy i uzyskiwanie informacji o orientacji. Ta klasa zawiera też kilka stałych wartości czujnika używane do raportowania dokładności czujników, ustawiania współczynników pozyskiwania danych i kalibrowania czujników.
Sensor
- Za pomocą tej klasy możesz utworzyć instancję konkretnego czujnika. Te zajęcia przedstawiają różne za pomocą których można określić możliwości czujnika.
SensorEvent
- System używa tej klasy do utworzenia obiektu zdarzenia czujnika, który dostarcza informacje o zdarzenie czujnika. Obiekt zdarzenia czujnika zawiera następujące informacje: nieprzetworzone dane z czujnika, typu czujnika, który wygenerował zdarzenie, dokładności danych oraz sygnatury czasowej .
SensorEventListener
- Za pomocą tego interfejsu możesz utworzyć 2 metody wywołania zwrotnego, które otrzymują powiadomienia (czujnik zdarzeń), gdy zmienią się wartości czujnika lub ich dokładność.
W typowej aplikacji te interfejsy API związane z czujnikami wykonują 2 podstawowe zadania:
- Identyfikowanie czujników i ich funkcji
Identyfikowanie czujników i ich funkcji w czasie działania jest przydatne, jeśli aplikacja funkcje, które zależą od konkretnych typów lub możliwości czujnika. Możesz na przykład: identyfikować wszystkie czujniki w urządzeniu i wyłączać funkcje aplikacji korzystających z brakujących czujników. Możesz również zidentyfikować wszystkie czujniki, danego typu, dzięki czemu możesz wybrać implementację czujnika, która daje optymalną wydajność dla Twojej aplikacji.
- Monitorowanie zdarzeń z czujnika
Monitorowanie zdarzeń z czujników to sposób na pozyskiwanie nieprzetworzonych danych z czujnika. Zdarzenie z czujnikiem występuje za każdym razem czujnik wykrywa zmianę mierzonych parametrów. Zdarzenie z czujnika dostarcza z czterema informacjami: nazwą czujnika, który wywołał zdarzenie, sygnaturę czasową zdarzenia, dokładność zdarzenia oraz nieprzetworzone dane z czujnika, które je wywołały do zdarzenia.
Dostępność czujników
Dostępność czujników jest różna w zależności od urządzenia, ale może też różnić się w zależności od Androida wersji. Wynika to z faktu, że czujniki Androida zostały wprowadzone w ciągu kilku i kolejnych wersjach platformy. Na przykład w Androidzie 1.5 wprowadziliśmy wiele czujników (poziom API 3), ale niektóre nie zostały wdrożone i nie można ich używać do wersji Androida 2.3 (poziom interfejsu API 9). Podobnie, wprowadziliśmy w Androidzie 2.3 (poziom API 9) i 4.0 (poziom API 14) kilka czujników. Dwa Czujniki zostały wycofane i zastąpione nowszymi, lepszymi czujnikami.
W tabeli 2 podsumowano dostępność każdego czujnika z poszczególnych platform. Tylko cztery platformy są wymienione na liście, ponieważ to właśnie na nich występują zmiany w czujnikach. Czujniki, które są oznaczone jako wycofane są nadal dostępne na kolejnych platformach (pod warunkiem, znajduje się w urządzeniu, co jest zgodne z zasadami dotyczącymi zgodności z przejściem dla Androida.
Tabela 2. Dostępność czujników według platformy.
Czujnik | Android 4.0 (poziom API 14) |
Android 2.3 (poziom API 9) |
Android 2.2 (poziom API 8) |
Android 1.5 (poziom API 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
Tak | Tak | Tak | Tak |
TYPE_AMBIENT_TEMPERATURE |
Tak | nie dotyczy | nie dotyczy | nie dotyczy |
TYPE_GRAVITY |
Tak | Tak | nie dotyczy | nie dotyczy |
TYPE_GYROSCOPE |
Tak | Tak | nie dotyczy1 | nie dotyczy1 |
TYPE_LIGHT |
Tak | Tak | Tak | Tak |
TYPE_LINEAR_ACCELERATION |
Tak | Tak | nie dotyczy | nie dotyczy |
TYPE_MAGNETIC_FIELD |
Tak | Tak | Tak | Tak |
TYPE_ORIENTATION |
Tak2 | Tak2 | Tak2 | Tak |
TYPE_PRESSURE |
Tak | Tak | nie dotyczy1 | nie dotyczy1 |
TYPE_PROXIMITY |
Tak | Tak | Tak | Tak |
TYPE_RELATIVE_HUMIDITY |
Tak | nie dotyczy | nie dotyczy | nie dotyczy |
TYPE_ROTATION_VECTOR |
Tak | Tak | nie dotyczy | nie dotyczy |
TYPE_TEMPERATURE |
Tak2 | Tak | Tak | Tak |
1 Ten typ czujnika został dodany w Androidzie 1.5 (poziom API 3), ale nie można było z niej korzystać aż do wersji 2.3 (poziom interfejsu API 9).
2 Ten czujnik jest dostępny, ale wycofane.
Rozpoznawanie czujników i ich funkcji
Platforma czujników w Androidzie udostępnia kilka metod, które ułatwiają określanie które czujniki znajdują się w urządzeniu. Udostępnia on również metody, które pozwalają określić możliwości każdego z czujników, takie jak jego maksymalny zasięg, rozdzielczość i moc .
Aby zidentyfikować czujniki urządzenia, musisz najpierw uzyskać odniesienie do czujnika.
posprzedażna. W tym celu należy utworzyć instancję klasy SensorManager
przez
wywoływanie metody getSystemService()
i fałszowanie wyników
w argumencie SENSOR_SERVICE
. Na przykład:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Następnie możesz wyświetlić listę wszystkich czujników urządzenia, wywołując metodę
getSensorList()
ze stałą TYPE_ALL
. Na przykład:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Jeśli chcesz wyświetlić wszystkie czujniki danego typu, możesz użyć innej stałej zamiast
TYPE_ALL
, na przykład TYPE_GYROSCOPE
,
TYPE_LINEAR_ACCELERATION
lub
TYPE_GRAVITY
Możesz też określić, czy w urządzeniu istnieje określony typ czujnika, używając metody getDefaultSensor()
i przekazując typ
stałą dla konkretnego czujnika. Jeśli urządzenie ma więcej niż 1 czujnik danego typu, jeden z
muszą być ustawione jako czujniki domyślne. Jeśli domyślny czujnik nie istnieje dla danego
typ czujnika, wywołanie metody zwraca wartość null, co oznacza, że urządzenie nie ma tego typu
. Na przykład ten kod sprawdza, czy na urządzeniu znajduje się magnetometr:
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. }
Uwaga: producenci urządzeń nie wymagają od producentów urządzeń z Androidem tworzenia jakichkolwiek określonych typów czujników do urządzeń z Androidem. Dzięki temu urządzenia mogą łączyć się z szerokim zakresem konfiguracji czujnika.
Oprócz wyświetlania listy czujników zainstalowanych na urządzeniu możesz użyć publicznych metod
Sensor
klasa do określania możliwości i atrybutów poszczególnych osób
i czujników. Jest to przydatne, jeśli chcesz, aby aplikacja działała inaczej w zależności od tego, które czujniki lub
funkcje czujnika są dostępne w urządzeniu. Na przykład możesz użyć getResolution()
i getMaximumRange()
to metoda uzyskiwania rozdzielczości czujnika oraz maksymalnego zakresu pomiarów. Możesz też użyć usługi
Metoda getPower()
, która pozwala uzyskać wymagania dotyczące zasilania czujnika.
Dwie publiczne metody są szczególnie przydatne, jeśli chcesz zoptymalizować aplikację pod kątem
czujniki różnych producentów
lub różne wersje czujnika. Jeśli na przykład Twoja aplikacja
monitorowania gestów użytkownika, takich jak przechylanie i potrząśnięcie, można utworzyć jeden zestaw filtrów
reguł i optymalizacji nowszych urządzeń, które mają czujnik grawitacji konkretnego dostawcy, oraz inne.
zestawu reguł filtrowania danych i optymalizacji dla urządzeń, które nie mają czujnika grawitacji i
tylko za pomocą akcelerometru. Poniższy przykładowy kod pokazuje, jak możesz wykorzystać metody getVendor()
i getVersion()
.
to osiągnąć. W tym przykładzie szukamy czujnika grawitacji z listą Google LLC jako dostawcy,
ma wersję 3. Jeśli tego czujnika nie ma w urządzeniu, staramy się używać
przy użyciu akcelerometru.
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. } }
Inną przydatną metodą jest getMinDelay()
,
który zwraca minimalny przedział czasu (w mikrosekundach), którego czujnik może użyć do wykrywania danych. Dowolny czujnik
, która zwraca wartość inną niż zero dla funkcji getMinDelay()
metoda to strumieniowanie
. Czujniki strumieniowania wykrywają dane w regularnych odstępach czasu i zostały wprowadzone w Androidzie 2.3 (interfejs API
Poziom 9). Jeśli czujnik zwróci 0 przy wywołaniu metody getMinDelay()
, oznacza to, że
czujnik nie jest czujnikiem strumieniowania, ponieważ przekazuje dane tylko w przypadku zmiany
wykrywanych przez nią parametrów.
Metoda getMinDelay()
jest przydatna, ponieważ pozwala
określasz maksymalną szybkość
w którym czujnik może zbierać dane. Jeśli niektóre funkcje aplikacji wymagają dużej ilości danych
ze współczynnikami pozyskiwania i czujnikami strumieniowania, możesz użyć tej metody, aby określić, czy
spełnia te wymagania, a następnie włącz lub wyłącz odpowiednie funkcje aplikacji
odpowiednio się zmienia.
Uwaga: maksymalna częstotliwość pozyskiwania danych przez czujnik nie jest zawsze z jakąś szybkością, z jaką platforma czujnika dostarcza dane z czujnika do aplikacji. Platforma czujnika przekazuje dane na podstawie zdarzeń z czujnika, a kilka czynników wpływa na aplikacja odbiera zdarzenia z czujnika. Więcej informacji znajdziesz w artykule Monitorowanie zdarzeń z czujnika.
Monitorowanie zdarzeń z czujnika
Aby monitorować nieprzetworzone dane z czujników, musisz wdrożyć dwie metody wywołania zwrotnego, które są udostępniane
interfejs SensorEventListener
: onAccuracyChanged()
i onSensorChanged()
. System Android wywołuje
te metody, gdy:
- Dokładność czujnika jest inna.
W takim przypadku system wywołuje metodę
onAccuracyChanged()
, podając odnosi się do obiektuSensor
, który uległ zmianie, nowej dokładności czujnika. Dokładność jest reprezentowana przez jedną z czterech stałych stanu:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, lubSENSOR_STATUS_UNRELIABLE
. - Czujnik zgłasza nową wartość.
W takim przypadku system wywołuje metodę
onSensorChanged()
, udostępniając obiektSensorEvent
. ObiektSensorEvent
zawiera informacje o nowych danych z czujnika, w tym ich dokładność, czujnik, który wygenerował dane, sygnatura czasowa momentu wygenerowania danych oraz nowy zarejestrowane przez czujnik.
Poniższy kod pokazuje, jak używać metody onSensorChanged()
do monitorowania danych z
czujnika światła. Ten przykład wyświetla nieprzetworzone dane z czujnika w TextView
czyli
zdefiniowaną w pliku main.xml jako 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); } }
W tym przykładzie domyślne opóźnienie danych (SENSOR_DELAY_NORMAL
) jest określane przy wywoływaniu metody registerListener()
. Dane
opóźnienie (lub częstotliwość próbkowania) określa odstęp czasu, po którym zdarzenia z czujnika są wysyłane do aplikacji.
za pomocą metody wywołania zwrotnego onSensorChanged()
. Domyślny
opóźnienie danych jest odpowiednie do monitorowania
typowa orientacja ekranu zmienia się z opóźnieniem 200 000 mikrosekund. Możesz też określić inne
opóźnienia danych, takie jak SENSOR_DELAY_GAME
(20 000 mikrosekund
opóźnienie), SENSOR_DELAY_UI
(opóźnienie 60 000 mikrosekund) lub SENSOR_DELAY_FASTEST
(opóźnienie 0 mikrosekund). Od Androida 3.0 (API)
poziomu 11) możesz też określić opóźnienie w postaci wartości bezwzględnej (w mikrosekundach).
Podane przez Ciebie opóźnienie jest tylko sugerowanym opóźnieniem. System Android i inne aplikacje co może zmienić to opóźnienie. Najlepiej podać największe opóźnienie, ponieważ system zwykle używa mniejszego opóźnienia niż podane przez Ciebie (tzn. jako najwolniejszej częstotliwości próbkowania, która w dalszym ciągu spełnia potrzeby Twojej aplikacji). Większe opóźnienie nakłada obciąża procesor i zużywa mniej energii.
Nie istnieje publiczna metoda pozwalająca określić szybkość, z jaką platforma czujnika wysyła dane zdarzenia z czujnika dla aplikacji; ale możesz użyć sygnatur czasowych powiązanych z każdym zdarzenia czujnika, aby obliczyć częstotliwość próbkowania dla kilku zdarzeń. Nie musisz zmieniać parametru częstotliwości próbkowania (opóźnienia). Jeśli z jakiegoś powodu musisz zmienić opóźnienie, wyrejestrować i ponownie zarejestrować detektor czujnika.
Warto też pamiętać, że w tym przykładzie użyto atrybutów onResume()
i
onPause()
metoda wywołania zwrotnego do rejestrowania i wyrejestrowania zdarzenia czujnika
słuchacz. Sprawdzoną metodą jest wyłączenie czujników, których nie potrzebujesz, zwłaszcza gdy
aktywność jest wstrzymana. Jeśli tego nie zrobisz, bateria może wyczerpać się już w ciągu kilku godzin, ponieważ niektóre czujniki
mają znaczne wymagania w zakresie zasilania i mogą szybko zużywać baterię. System
nie wyłącza automatycznie czujników po wyłączeniu ekranu.
Obsługa różnych konfiguracji czujników
Android nie określa standardowej konfiguracji czujnika dla urządzeń, co oznacza, że producenci urządzeń mogą stosować w swoich urządzeniach dowolną konfigurację Urządzenia z systemem Android. Urządzenia mogą więc obejmować różne funkcje, w wielu różnych konfiguracjach. Jeśli Twoja aplikacja korzysta z określonego typu czujnika, musisz upewnić się, że w urządzeniu jest czujnik, który umożliwia prawidłowe działanie aplikacji.
Masz 2 sposoby sprawdzania, czy dany czujnik znajduje się w urządzeniu:
- Wykrywanie czujników w czasie działania i włączanie lub wyłączanie odpowiednich funkcji aplikacji.
- Aby kierować reklamy na urządzenia o określonych konfiguracjach czujników, użyj filtrów Google Play.
Każda z tych opcji została omówiona w kolejnych sekcjach.
Wykrywanie czujników w czasie działania
Jeśli Twoja aplikacja korzysta z określonego typu czujnika, ale nie zależy od niego, możesz użyć parametru platforma czujnika do wykrywania czujnika w czasie działania, a następnie wyłączania lub włączania funkcji aplikacji w razie potrzeby. Na przykład aplikacja do nawigacji może korzystać z czujnika temperatury, czujnik ciśnienia, czujnika GPS i czujnik pola geomagnetycznego do wyświetlania temperatury, barometryczne takie jak ciśnienie, położenie i położenie kompasu. Jeśli urządzenie nie ma czujnika ciśnienia, czujnika do wykrywania braku czujnika ciśnienia w czasie działania, a następnie wyłączania interfejsu aplikacji, w którym widać nacisk. Na przykład te kontrole kodu czy urządzenie jest wyposażone w czujnik ciśnienia:
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. }
Używanie filtrów Google Play do kierowania reklam na określone konfiguracje czujników
Jeśli publikujesz aplikację w Google Play, możesz użyć atrybutu
<uses-feature>
w pliku manifestu, aby odfiltrować aplikację z urządzeń, które nie korzystają z tej funkcji
zapewnić odpowiednią konfigurację czujnika dla swojej aplikacji.
Element <uses-feature>
ma kilka deskryptorów sprzętowych, które umożliwiają filtrowanie
w zależności od obecności określonych czujników. Czujniki, które możesz wyświetlić, to:
akcelerometr, barometr, kompas (pole geomagnetyczne), żyroskop, światło i bliskość.
poniżej znajdziesz przykładowy wpis w pliku manifestu, który filtruje aplikacje bez akcelerometru:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Jeśli dodasz ten element i deskryptor do pliku manifestu aplikacji, użytkownicy zobaczą w Google Play tylko wtedy, gdy ich urządzenie jest wyposażone w akcelerometr.
Deskryptor należy ustawić na android:required="true"
tylko wtedy, gdy aplikacja
zależy całkowicie od konkretnego czujnika. Jeśli Twoja aplikacja używa czujnika do obsługi pewnych funkcji, ale
nadal działa bez czujnika, wymień czujnik w <uses-feature>
ale ustaw deskryptor na android:required="false"
. Dzięki temu będziesz mieć pewność, że
nawet jeśli nie mają danego czujnika. To również
sprawdzone metody zarządzania projektem, które pomagają śledzić funkcje używane w aplikacji.
Pamiętaj, że jeśli Twoja aplikacja korzysta z konkretnego czujnika, ale działa bez niego,
należy wykryć czujnik w czasie działania i wyłączyć lub włączyć funkcje aplikacji jako
odpowiednie.
System współrzędnych czujnika
Ogólnie rzecz biorąc, do wyrażenia wartości danych szkielet czujnika wykorzystuje standardowy 3-osiowy układ współrzędnych. W przypadku większości czujników układ współrzędnych jest definiowany w odniesieniu do ekranu urządzenia, gdy urządzenie jest w domyślnej orientacji (zobacz ilustrację 1). Gdy urządzenie jest trzymane w domyślnej orientacji, Oś X jest pozioma i wskazuje po prawej stronie, oś Y jest pionowa i jest skierowana w górę, a oś Z w kierunku zewnętrznym. W tym systemie współrzędne za ekranem mają ujemne wartości Z. Z tego układu współrzędnych korzystają następujące czujniki:
![](https://developer.android.google.cn/static/images/axis_device.png?authuser=8&hl=pl)
Rysunek 1. System współrzędnych (w odniesieniu do urządzenia), którego używa czujnik API.
- Przyspieszenie rozwoju czujnik
- Grawitacja czujnik
- Żyroskop
- Przyspieszenie liniowe czujnik
- Pole geomagnetyczne czujnik
Najważniejszym aspektem tego układu współrzędnych jest to, że osie nie są zamieniane po zmianie orientacji ekranu urządzenia – czyli w układzie współrzędnych czujnika. nigdy nie zmienia się wraz z poruszeniem urządzenia. Takie działanie jest takie samo jak w przypadku trybu OpenGL. układ współrzędnych.
Należy też zrozumieć, że aplikacja nie może zakładać, że urządzenie (domyślna) jest pionowa. Na wielu tabletach naturalna orientacja to pozioma. oraz układ współrzędnych czujnika zawsze opiera się na naturalnej orientacji urządzenia.
Wreszcie, jeśli aplikacja dopasowuje dane z czujnika do wyświetlacza, musisz użyć
getRotation()
, aby określić obrót ekranu, a następnie użyj
Metoda remapCoordinateSystem()
do mapowania
współrzędne czujnika do współrzędnych ekranu. Jest to konieczne, nawet jeśli w pliku manifestu określono, że
w orientacji pionowej.
Uwaga: niektóre czujniki i metody wykorzystują układ współrzędnych
względem układu odniesienia na świecie (a nie układu odniesienia urządzenia). Te
czujniki i metody zwracają dane, które reprezentują ruch lub położenie urządzenia względem
Ziemię. Aby uzyskać więcej informacji, zapoznaj się z metodami getOrientation()
i getRotationMatrix()
, Orientacja
Czujnik i Wektor obrotu
Czujnik.
Ograniczenie szybkości czujnika
Aby chronić potencjalnie poufne informacje o użytkownikach, jeśli Twoja aplikacja jest kierowana w Androidzie 12 (poziom interfejsu API 31) lub nowszym system ogranicza odświeżanie. szybkości transmisji danych z określonych czujników ruchu i pozycji. Te dane obejmuje wartości zarejestrowane przez funkcję akcelerometr, żyroskop, pole geomagnetyczne .
Limit częstotliwości odświeżania zależy od sposobu uzyskania dostępu do danych z czujnika:
- Jeśli wywołujesz metodę
registerListener()
do monitorowania zdarzeń z czujnika, częstotliwość próbkowania będzie wynosić ograniczona do 200 Hz. Dotyczy to wszystkich przeciążonych wariantów interfejsu MetodaregisterListener()
. - Jeśli używasz tagu
SensorDirectChannel
zajęcia, częstotliwość próbkowania czujnika jest ograniczona doRATE_NORMAL
, czyli zwykle ok. 50 Hz.
Jeśli aplikacja ma szybciej gromadzić dane z czujnika ruchu, musisz:
zadeklaruj
HIGH_SAMPLING_RATE_SENSORS
jak widać poniżej. W przeciwnym razie, jeśli aplikacja
aby zbierać dane z czujników ruchu z większą szybkością bez deklarowania tego uprawnienia,
występuje SecurityException
.
AndroidManifest.xml
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Sprawdzone metody dostępu do czujników i ich używania
Podczas projektowania implementacji czujnika przestrzegaj wytycznych opisanych w w tej sekcji. Te wytyczne są zalecanymi sprawdzonymi metodami dla każdego, kto korzysta z czujnika do uzyskiwania dostępu do czujników i pozyskiwania z nich danych.
Zbieraj dane z czujników tylko na pierwszym planie
Na urządzeniach z Androidem 9 (poziom interfejsu API 28) lub nowszym aplikacje działające mają następujące ograniczenia:
- Czujniki, które używają ciągły np. akcelerometry i żyroskopy, zdarzeń.
- Czujniki, które używają w zmianie lub one-shot tryby raportowania nie odbierają zdarzeń.
Ze względu na te ograniczenia najlepiej jest wykrywać zdarzenia z czujnika zarówno wtedy, gdy aplikacja jest na pierwszym planie lub w ramach usługę działającą na pierwszym planie.
Wyrejestruj detektory czujników
Pamiętaj, aby wyrejestrować detektor czujnika, gdy przestaniesz go używać
o przerwach w działaniu. Jeśli detektor czujnika jest zarejestrowany, a jego aktywność jest wstrzymana, czujnik
kontynuuj pobieranie danych i korzystanie z zasobów baterii, chyba że wyrejestrujesz czujnik. Poniżej
kod pokazuje, jak użyć metody onPause()
do wyrejestrowania odbiornika:
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); }
Więcej informacji: unregisterListener(SensorEventListener)
.
Testowanie za pomocą emulatora Androida
Emulator Androida zawiera zestaw elementów sterujących czujnikami wirtualnymi, które pozwalają na do testowania czujników, takich jak akcelerometr, temperatura otoczenia, magnetometr, bliskości, światła i innych obiektów.
Emulator używa połączenia z urządzeniem z Androidem, na którym działa SdkControllerSensor . Pamiętaj, że ta aplikacja jest dostępna tylko na urządzeniach z Androidem 4.0 (interfejs API poziomu 14) lub wyższym. (Jeśli na urządzeniu jest Android 4.0, Wersja 2 została zainstalowana). Aplikacja SdkControllerSensor monitoruje zmiany w czujników urządzenia i przesyła je do emulatora. Ten emulator jest przekształcona na podstawie nowych wartości otrzymywanych z czujników na Twoim urządzeniu.
Kod źródłowy aplikacji SdkControllerSensor możesz wyświetlić w ta lokalizacja:
$ your-android-sdk-directory/tools/apps/SdkController
Aby przenieść dane między urządzeniem a emulatorem, wykonaj te czynności: kroki:
- Sprawdź, czy USB jest włączone debugowanie na urządzeniu.
- Podłącz urządzenie do maszyny wirtualnej za pomocą kabla USB.
- Na urządzeniu uruchom aplikację SdkControllerSensor.
- W aplikacji wybierz czujniki, które chcesz emulować.
Uruchom to polecenie
adb
:- Uruchom emulator. Możesz teraz zastosować przekształcenia do funkcji za pomocą emulatora.
$ adb forward tcp:1968 tcp:1968
Uwaga: jeśli ruchy wykonywane przez Ciebie
urządzenie fizyczne nie zmienia emulatora, spróbuj uruchomić
adb
z kroku 5.
Więcej informacji znajdziesz w artykule Android Przewodnik po emulatorach.
Nie blokuj metody onSensorChanged()
Dane z czujników mogą zmieniać się z dużą szybkością, co oznacza, że system może dość często wywoływać metodę onSensorChanged(SensorEvent)
. Zgodnie ze sprawdzoną metodą
powinien robić jak najwięcej w ramach metody onSensorChanged(SensorEvent)
, aby jej nie blokować. Jeśli
filtrowanie lub redukcji danych z czujnika wymaga wykonania jakichkolwiek czynności,
które działają poza metodą onSensorChanged(SensorEvent)
.
Unikaj używania wycofanych metod lub typów czujników
Kilka metod i stałych zostało wycofanych.
Przede wszystkim pamiętaj, że TYPE_ORIENTATION
Typ czujnika został wycofany. Aby uzyskać dane orientacji, użyj metody getOrientation()
. Podobnie
Typ czujnika TYPE_TEMPERATURE
został wycofany. Należy użyć
w urządzeniach jest natomiast typ czujnika TYPE_AMBIENT_TEMPERATURE
.
z Androidem 4.0.
Sprawdź czujniki, zanim ich użyjesz
Przed podjęciem próby pozyskania danych z urządzenia zawsze sprawdź, czy znajduje się w nim czujnik. Przeciwwskazania zakładamy, że czujnik istnieje tylko dlatego, że jest często używany. Producenci urządzeń to nie muszą dostarczać żadnych konkretnych czujników w urządzeniach.
Starannie wybieraj opóźnienia z czujnika
Gdy rejestrujesz czujnik za pomocą metody registerListener()
, wybierz częstotliwość przesyłania, która Ci odpowiada
do danej aplikacji lub przypadku użycia. Czujniki dostarczają dane w bardzo dużych ilościach. Umożliwianie systemowi wysyłania
dodatkowe dane, których nie potrzebujesz, zużywają zasoby systemu i zużywają baterię.