Android od podstaw: czujniki sprzętowe
() translation by (you can also view the original English article)
Jedną z rzeczy, która wyróżnia programowanie dla urządzeń mobilnych na tle innych platform jest fakt, że telefon lub tablet posiada wiele czujników, które deweloperzy mogą wykorzystać do wprowadzania danych. W tym poradniku przedstawię ci strukturę czujników systemu Android. Dowiesz się jak wykryć dostępne czujniki w urządzeniu i odczytywać z nich dane.
Czujniki urządzenia
Istnieją trzy główne kategorie podstawowych czujników, które należy znać: ruchu, środowiskowe i pozycji urządzenia Czujniki ruchu wykrywają zmiany w siłach wokół trzech osi urządzenia: X, Y i Z jak pokazano poniżej:



Czujniki ruchu obejmują żyroskop, akcelerometr oraz czujniki wektora obrotowego.
Środowiskowe czujniki zbierają informacje o środowisku, w którym znajduje się telefon. Obejmują one czujniki wilgotności, temperatury otoczenia, oświetlenia i barometry.
Trzecia kategoria bazowych czujników oznacza dokładnie to, czego można było się spodziewać: wykrywa pozycję urządzenia. Kategoria obejmuje czujniki orientacji i magnetometr.
Każdy czujnik, który nie zalicza się do ani jednej podstawowej kategorii jest traktowany jako czujnik kompozytowy. Nie są to czujniki w tradycyjnym tego słowa znaczeniu, ponieważ zbierają swoje dane z wielu innych fizycznych czujników urządzenia i zestawiają je. Przykłady obejmują licznik kroków, czujnik grawitacji i wektora obrotowego.
Odczytywanie danych z czujnika
Skoro już trochę wiesz o rodzajach czujników w urządzeniach mobilnych, pora na rozpoczęcie odczytywania danych ze sprzętu. Zacznijmy od poznania czujników dostępnych w urządzeniu.
Odkrywanie czujników w urządzeniu
Aby uzyskać dostęp do czujników w urządzeniu, musisz skorzystać z klasy SensorManager
, którą możesz pobrać jako usługę systemową z Activity
.
1 |
mSensorManager = (SensorManager) getSystemService( Context.SENSOR_SERVICE ); |
Gdy uzyskasz już SensorManager
, możesz pobrać domyślny Sensor
w zależności od typu lub pobrać obiekty Sensor
List
bazując na rodzaju parametru. W tym przykładzie pobierzemy List
wszystkich obiektów Sensor
w ten sposób:
1 |
List<Sensor> sensorList = mSensorManager.getSensorList( Sensor.TYPE_ALL ); |
Zwróć uwagę, ze użyliśmy tutaj TYPE_ALL
. Jeśli chcemy uzyskać dany podzestaw czujników, możemy przejść do obsługiwanych atrybutów typu, takich jak elementy na poniższej liście.
1 |
TYPE_AMBIENT_TEMPERATURE
|
2 |
TYPE_DEVICE_PRIVATE_BASE
|
3 |
TYPE_GAME_ROTATION_VECTOR
|
4 |
TYPE_GEOMAGNETIC_ROTATION_VECTOR
|
5 |
TYPE_GRAVITY
|
6 |
TYPE_GYROSCOPE
|
7 |
TYPE_GYROSCOPE_UNCALIBRATED
|
8 |
TYPE_HEART_BEAT
|
9 |
TYPE_HEART_RATE
|
10 |
TYPE_LIGHT
|
11 |
TYPE_LINEAR_ACCELERATION
|
12 |
TYPE_MAGNETIC_FIELD
|
13 |
TYPE_MAGNETIC_FIELD_UNCALIBRATED
|
14 |
TYPE_MOTION_DETECT
|
Po wybraniu obiektu Sensor
, z którym chcesz pracować, możesz rozpocząć pobieranie z niego danych.
Nasłuchiwanie wydarzeń czujnika
Każdy obiekt Sensor
zawiera informacje o fizycznym sprzęcie czujnika, takie jak zasilanie, opóźnienie wejścia, nazwę, typ i producent. Jeśli chcesz pobrać informację z tego czujnika, musisz najpierw zarejestrować SensorEventListener
, który będzie wywoływany w określonych odstępach czasu z odczytami informacji.
1 |
mSensorManager.registerListener( this, mSensor, SensorManager.SENSOR_DELAY_UI ); |
Wyszczególniamy cztery prędkości odczytu: najszybsza, gra, normalna i UI. Niektóre umożliwiają odczytywanie informacji częściej, ale zużywają więcej energii urządzenia. Im rzadziej czujnik jest wywoływany, tym mniej energii pobiera.
Po zarejestrowaniu SensorEventListener
, zostanie wywołana metoda onSensorChanged
z nowym SensorEvent
za każdym razem, gdy czujnik jest uruchamiany. SensorEvent
owija obiekt Sensor
, który dostarcza mu danych, jak również informacji o czasie, dokładności czujnika i rzeczywistych danych wejściowych.
Wprowadzone dane są przechowywane w tablicy float
zwanej values
. Długość values
może się różnić w zależności od czujnika. Na przykład, akcelerometr będzie posiadał trzy wartości (wejście X, Y i Z), podczas gdy barometr tylko jedną. Podczas korzystania z danych z czujnika, warto zrozumieć jakie informacje mamy do dyspozycji oraz jak są one przechowywane w tablicy values
, ponieważ w ten sposób będziesz wiadomo jak budować aplikację oraz jak uniknąć problemów związanych z wyjątkiem ArrayIndexOutOfBoundsException
.
1 |
@Override
|
2 |
public void onSensorChanged(SensorEvent sensorEvent) { |
3 |
Log.e("Tuts+", "Accuracy: " + sensorEvent.accuracy ); |
4 |
Log.e("Tuts+", "Timestamp: " + sensorEvent.timestamp); |
5 |
Log.e("Tuts+", "Accelerometer X: " + sensorEvent.values[0]); |
6 |
Log.e("Tuts+", "Accelerometer Y: " + sensorEvent.values[1]); |
7 |
Log.e("Tuts+", "Accelerometer Z: " + sensorEvent.values[2]); |
8 |
}
|
Kiedy uruchomisz akcelerometr urządzenia, powyższy fragment kodu dostarczy takich danych wyjściowych:
1 |
E/Tuts+: Accuracy: 3 |
2 |
E/Tuts+: Timestamp: 572565573007319 |
3 |
E/Tuts+: Accelerometer X: 0.80444336 |
4 |
E/Tuts+: Accelerometer Y: 1.7597351 |
5 |
E/Tuts+: Accelerometer Z: 9.425964 |
Ponieważ nasłuchiwanie pozwala na wprowadzanie danych w miarę upływu czasu, można je przenieść na wykres podobny do poniższego (choć sama biblioteka graficzna wykracza poza zakres tego poradnika).



Wyzwalacze zdarzeń
Podczas gdy SensorEventListener
ciągle podaje informacje w miarę upływu czasu, TriggerEventListener
nasłuchuje wydarzeń i natychmiast się wyłącza. Ten rodzaj nasłuchiwania służy do sytuacji, w których występuje istotny ruch. Możesz dodać TriggerEventListener
do SensorManager
w ten sposób.
1 |
mSensorManager.requestTriggerSensor(new TriggerEventListener() { |
2 |
@Override
|
3 |
public void onTrigger(TriggerEvent triggerEvent) { |
4 |
Log.e("Tuts+", "onTrigger"); |
5 |
for(int i = 0; i < triggerEvent.values.length; i++ ) { |
6 |
Log.e("Tuts+", "item " + i + ": " + triggerEvent.values[i]); |
7 |
}
|
8 |
}
|
9 |
}, mSensor); |
Jeśli Sensor
przekazany do requestTriggerSensor
jest znaczącym czujnikiem ruchu, to otrzyma on sygnał wyjściowy, gdy urządzenie się przemieści:
1 |
E/Tuts+: onTrigger |
2 |
E/Tuts+: item 0: 1.0 |
Należy zwrócić uwagę, że SensorEventListener
oraz TriggerEventListener
powinny zostać wyrejestrowane z SensorMagager
po zakończeniu korzystania z nich, na przykład za pomocą onDestroy
wewnątrz klas Fragment
lub Activity
w celu uniknięcia przecieków w aplikacji.
Podsumowanie
W tym poradniku przedstawiłem ci strukturę czujników systemu Android. Dowiedziałeś się jak odnaleźć czujniki w urządzeniu i pobrać z nich informacje. Dzięki czemu, możesz budować złożone aplikacje, które są świadome swojego środowiska i czynności użytkownika. Nauka obsługi danych z czujników pozwoli na stworzenie interesujących funkcji i sposobów działania, które możesz wykorzystać w swoich aplikacjach.