Sensors API: co to jest, typy czujników i praca z sensorami

Autor: IT Sectr Opublikowano: 2026-03-26 Czas czytania: 10 min

Sensors API — to interfejs platformy Android do dostępu do sprzętowych czujników urządzenia. API zapewnia jednolity sposób pobierania danych z akcelerometru, żyroskopu, magnetometru, czujnika oświetlenia i innych sensorów. Według danych Google, 2026, ponad 95% nowoczesnych urządzeń z Androidem jest wyposażonych w co najmniej trzy typy czujników, co otwiera szerokie możliwości tworzenia aplikacji kontekstowych.

Najważniejsze

  • Sensors API — ujednolicony interfejs Androida do pracy ze sprzętowymi czujnikami urządzenia.
  • Trzy kategorie — czujniki Motion, Position i Environment o różnych zasadach pomiaru.
  • SensorManager — usługa systemowa do uzyskiwania listy czujników i rejestracji słuchaczy.
  • Częstotliwość aktualizacji jest ustawiana przez stałe SENSOR_DELAY od NORMAL do FASTEST.
  • Wirtualne czujniki — Gravity, Rotation Vector i Linear Acceleration oparte na kombinacji fizycznych sensorów.

Czym jest Sensors API w Androidzie?

Sensors API — to interfejs programowy Android Framework, zapewniający programistom dostęp do sprzętowych czujników urządzenia mobilnego. API wchodzi w skład Android SDK od wersji 1.0 i jest dostępne przez pakiet android.hardware. Interfejs abstrahuje różnice między implementacjami czujników różnych producentów — Qualcomm, MediaTek, Samsung Exynos — i zapewnia jednolity model pracy z sensorami.

Główne możliwości Sensors API

API umożliwia wykonanie trzech kluczowych operacji: pobranie listy dostępnych czujników, rejestrację słuchaczy do otrzymywania danych oraz zarządzanie częstotliwością aktualizacji odczytów. SensorManager jest centralnym punktem dostępu do wszystkich operacji. System powiadamia aplikację przez callback onSensorChanged, przekazując obiekt SensorEvent z tablicą wartości float.

Ewolucja Sensors API

W trakcie istnienia Androida API przeszło kilka etapów rozwoju. W wersji 2.3 (Gingerbread) pojawiło się wsparcie Batch Processing — grupowanie zdarzeń czujnika w celu zmniejszenia zużycia energii. Android 4.0 (Ice Cream Sandwich) dodał wirtualne czujniki Gravity i Linear Acceleration. Od Androida 8.0 system ograniczył dostęp w tle do czujników w celu zwiększenia prywatności.

kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
    Log.d("Czujniki", "${sensor.name} — ${sensor.type}")
}

Ograniczenia i wymagania

Nie wszystkie urządzenia mają ten sam zestaw czujników. Aplikacja musi sprawdzać dostępność konkretnego sensora przed rejestracją słuchacza. Emulator Androida obsługuje tylko ograniczony zestaw czujników — akcelerometr i magnetometr. Do testowania pozostałych czujników wymagane jest fizyczne urządzenie. Od Androida 12 aplikacje muszą deklarować użycie czujników w manifeście.

Typy czujników Androida: Motion, Position, Environment

Android klasyfikuje wszystkie czujniki na trzy kategorie: Motion (ruch), Position (położenie) i Environment (otoczenie). Czujniki Motion obejmują akcelerometr, żyroskop i licznik kroków. Czujniki Position zawierają magnetometr i Orientation. Environment — czujnik oświetlenia, ciśnienia, temperatury i wilgotności.

KategoriaCzujnikiTyp (stała)Fizyczny/Wirtualny
MotionAkcelerometrTYPE_ACCELEROMETERFizyczny
MotionŻyroskopTYPE_GYROSCOPEFizyczny
MotionLicznik krokówTYPE_STEP_COUNTERFizyczny
MotionGravityTYPE_GRAVITYWirtualny
PositionMagnetometrTYPE_MAGNETIC_FIELDFizyczny
PositionRotation VectorTYPE_ROTATION_VECTORWirtualny
EnvironmentOświetlenieTYPE_LIGHTFizyczny
EnvironmentCiśnienieTYPE_PRESSUREFizyczny

Czujniki Motion: akcelerometr i żyroskop

Akcelerometr mierzy przyspieszenie w m/s² w trzech osiach — X, Y i Z. Wartości obejmują grawitację (9.8 m/s² w osi Z w stanie spoczynku). Żyroskop mierzy prędkość kątową w rad/s — prędkość obrotu urządzenia wokół każdej osi. Kombinacja tych dwóch czujników jest używana w nawigacji, grach i aplikacjach AR.

kotlin
class SensorActivity : Activity(), SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]
            textView.text = "X: $x, Y: $y, Z: $z"
        }
    }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

Czujniki Position: magnetometr i orientacja

Magnetometr (TYPE_MAGNETIC_FIELD) mierzy pole magnetyczne w mikroteślach (µT) w trzech osiach. Używany jako cyfrowy kompas — w połączeniu z akcelerometrem pozwala określić azymut urządzenia. Rotation Vector — wirtualny czujnik, który łączy dane z żyroskopu, akcelerometru i magnetometru w celu dokładnego określenia orientacji.

Czujniki Environment: oświetlenie, ciśnienie, temperatura

Czujnik oświetlenia (TYPE_LIGHT) mierzy poziom oświetlenia zewnętrznego w luksach (lx). Używany do automatycznej regulacji jasności ekranu. Czujnik ciśnienia (TYPE_PRESSURE) mierzy ciśnienie atmosferyczne w hektopaskalach (hPa) — stosowany w aplikacjach nawigacyjnych do określania wysokości nad poziomem morza.

Jak działa architektura Sensors API

Sensors API jest zbudowany na architekturze klient-serwer. Aplikacja występuje jako klient, SensorManager — jako usługa systemu Android. Gdy aplikacja rejestruje słuchacza przez registerListener, SensorManager komunikuje się z HAL (Hardware Abstraction Layer) — niskopoziomowym sterownikiem czujnika działającym na poziomie jądra Linux.

Cykl życia zdarzenia czujnika

Sterownik HAL otrzymuje surowe dane z układu scalonego, filtruje szumy i przekazuje je w górę stosu — przez SensorService (proces systemowy) do aplikacji. Dane są przesyłane jako obiekt SensorEvent, zawierający tablicę wartości float values i znacznik czasu w nanosekundach. Częstotliwość zdarzeń zależy od wybranego trybu dostarczania.

Tryby dostarczania zdarzeń

Podczas rejestracji słuchacza programista określa żądane opóźnienie między zdarzeniami za pomocą stałych SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) i SENSOR_DELAY_FASTEST (0 ms — maksymalna częstotliwość). Rzeczywista częstotliwość może się różnić — system optymalizuje zużycie energii.

kotlin
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
    this,
    sensor,
    SensorManager.SENSOR_DELAY_GAME
)

Przetwarzanie wsadowe (Batch Processing)

Od Androida 2.3 czujniki obsługują tryb wsadowy — zdarzenia gromadzą się w buforze FIFO i są dostarczane w jednym pakiecie. Pozwala to procesorowi dłużej pozostawać w trybie uśpienia, zmniejszając zużycie energii nawet o 60%. Rozmiar bufora zależy od układu czujnika i jest określony w polu Sensor.fifoMaxEventCount.

Użycie SensorManager do dostępu do czujników

SensorManager — usługa systemowa dostępna przez getSystemService(Context.SENSOR_SERVICE). Udostępnia metody do pobierania listy czujników, uzyskiwania konkretnego czujnika domyślnego oraz rejestracji/anulowania słuchaczy. SensorManager — singleton, jedna instancja na całą aplikację.

Sprawdzanie dostępności czujnika

Przed użyciem czujnika należy sprawdzić jego dostępność. Metoda getDefaultSensor(type) zwraca null, jeśli czujnik nie jest dostępny na urządzeniu. Otrzymanie null bez sprawdzenia doprowadzi do NullPointerException przy rejestracji słuchacza. Listę wszystkich czujników zwraca metoda getSensorList(type).

kotlin
fun checkSensorAvailability(type: Int): Boolean {
    val sensorManager =
        getSystemService(Context.SENSOR_SERVICE) as SensorManager
    return sensorManager.getDefaultSensor(type) != null
}

// Użycie:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
    Log.d("Sensor", "Żyroskop dostępny")
}

Rejestracja i anulowanie słuchacza

Słuchacz jest rejestrowany przez registerListener(listener, sensor, delay). Ważne: anulowanie słuchacza należy wykonać w metodzie onPause() przez unregisterListener(listener). Jeśli tego nie zrobisz, aplikacja będzie nadal otrzymywać zdarzenia czujnika, rozładowując baterię nawet w tle. Android 8+ wyświetla ostrzeżenie w logcat o niezarejestrowanych słuchaczach.

Obsługa zmiany dokładności

Metoda onAccuracyChanged(sensor, accuracy) jest wywoływana przy zmianie dokładności czujnika. Wartości: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW i UNRELIABLE. Po otrzymaniu UNRELIABLE dane czujnika należy ignorować do czasu przywrócenia dokładności. Na przykład magnetometr wymaga kalibracji — potrząśnięcia urządzeniem w kształcie ósemki.

Przykłady kodu do pracy z czujnikami w Kotlin

Rozważmy praktyczne przykłady użycia Sensors API w aplikacjach Android w Kotlin. Pierwszy przykład — określanie orientacji ekranu za pomocą akcelerometru. Drugi — odczytywanie wskazań magnetometru z kalibracją. Trzeci — detektor kroków z użyciem licznika kroków.

Określanie orientacji urządzenia

Do określenia orientacji używana jest kombinacja akcelerometru i magnetometru. Metoda SensorManager.getRotationMatrix() oblicza macierz obrotu, a getOrientation() wyodrębnia kąty pitch, roll i azimuth. Azimuth (azymut) — kąt względem północy magnetycznej w radianach.

kotlin
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)

SensorManager.getRotationMatrix(
    rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azymut, [1] — pochylenie, [2] — obrót
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())

Detektor kroków z licznikiem kroków

Licznik kroków (TYPE_STEP_COUNTER) zwraca całkowitą liczbę kroków wykonanych przez użytkownika od ostatniego restartu urządzenia. Czujnik działa na poziomie sprzętowym — jest aktywny nawet gdy aplikacja nie jest uruchomiona. Aby uzyskać liczbę kroków w sesji, należy zapisać wartość początkową i obliczyć różnicę.

kotlin
var initialSteps = 0
var isInitialized = false

override fun onSensorChanged(event: SensorEvent) {
    if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
        if (!isInitialized) {
            initialSteps = event.values[0].toInt()
            isInitialized = true
        }
        val currentSteps = event.values[0].toInt()
        val sessionSteps = currentSteps - initialSteps
        Log.d("Kroki", "Kroki w sesji: $sessionSteps")
    }
}

Adaptacyjna jasność według czujnika oświetlenia

Czujnik oświetlenia pozwala dostosować interfejs do warunków otoczenia. Przy niskim oświetleniu (poniżej 10 lx) można przełączyć się na ciemny motyw. Przy jasnym świetle słonecznym (powyżej 10000 lx) — zwiększyć kontrast. Do filtrowania szumów używana jest średnia ruchoma z 5 ostatnich wartości.

Wirtualne czujniki i algorytmy fuzji

Android udostępnia kilka wirtualnych czujników, które nie mają bezpośredniego odpowiednika sprzętowego. Wirtualny czujnik oblicza swoje wskazania na podstawie kombinacji fizycznych sensorów. Zmniejsza to obciążenie programisty — system sam implementuje algorytmy fuzji danych.

Gravity i Linear Acceleration

Czujnik Gravity (TYPE_GRAVITY) wyodrębnia składową grawitacyjną z odczytów akcelerometru za pomocą filtra dolnoprzepustowego (low-pass). Linear Acceleration (TYPE_LINEAR_ACCELERATION) — odwrotnie, usuwa grawitację i pozostawia tylko liniowe przyspieszenie urządzenia. Suma Gravity i Linear Acceleration daje surowe odczyty akcelerometru.

Rotation Vector

Rotation Vector — najbardziej złożony wirtualny czujnik. Łączy dane z żyroskopu (zmiany wysokiej częstotliwości), akcelerometru (wektor grawitacji) i magnetometru (orientacja względem północy). Wynik — kwaternion opisujący absolutną orientację urządzenia w przestrzeni. Używany w aplikacjach AR i goglach VR.

Game Rotation Vector

Game Rotation Vector — uproszczona wersja Rotation Vector bez użycia magnetometru. Daje to niższą dokładność określania azymutu, ale wyższą częstotliwość aktualizacji i stabilność. Zalecany do gier, gdzie ważne jest niskie opóźnienie, a nie absolutna orientacja względem północy.

Optymalizacja zużycia energii przy pracy z czujnikami

Czujniki — jedne z najbardziej energochłonnych komponentów urządzenia. Akcelerometr i żyroskop przy maksymalnej częstotliwości odpytywania mogą rozładować baterię w ciągu 3–4 godzin ciągłej pracy. Optymalizacja pracy z czujnikami to krytyczne zadanie dla każdej aplikacji używającej Sensors API.

Wybór optymalnego opóźnienia

Nie używaj SENSOR_DELAY_FASTEST bez potrzeby. Do animacji UI wystarczy SENSOR_DELAY_UI (60 ms). Do określania orientacji ekranu — SENSOR_DELAY_NORMAL (200 ms). Im wyższa częstotliwość, tym więcej czasu procesor spędza w stanie aktywnym. Różnica między NORMAL a FASTEST wynosi do 10x w zużyciu energii.

Anulowanie słuchaczy w tle

Od Androida 8.0 (API 26) aplikacje w tle otrzymują zdarzenia czujników ze zmniejszoną częstotliwością. W Androidzie 12+ dostęp w tle do czujników Motion i Position wymaga uprawnienia BODY_SENSORS_BACKGROUND. Anuluj rejestrację słuchacza przy przejściu aplikacji w tryb tła — wydłuża to czas pracy urządzenia.

Przetwarzanie wsadowe i bufor FIFO

Używaj przetwarzania wsadowego przez metodę registerListener(listener, sensor, delay, maxReportLatencyUs). Parametr maxReportLatencyUs określa maksymalne opóźnienie dostarczania zdarzeń w mikrosekundach. Przy wartości 1000000 (1 sekunda) zdarzenia gromadzą się w buforze FIFO czujnika i są dostarczane raz na sekundę — procesor rzadziej wychodzi ze stanu uśpienia.

Często zadawane pytania

Jakie czujniki są na wszystkich urządzeniach z Androidem?

Minimalny zestaw — akcelerometr i magnetometr. Te dwa czujniki są obecne na ponad 95% urządzeń. Żyroskop, czujnik oświetlenia i czujnik zbliżeniowy — na 70–80% nowoczesnych modeli. Pozostałe czujniki (ciśnienie, temperatura, wilgotność, licznik kroków) występują rzadziej i zależą od kategorii cenowej urządzenia.

Jaka jest różnica między TYPE_ACCELEROMETER a TYPE_LINEAR_ACCELERATION?

TYPE_ACCELEROMETER zwraca pełne przyspieszenie, włączając grawitację (9.8 m/s²). TYPE_LINEAR_ACCELERATION zwraca przyspieszenie bez grawitacji — tylko przyspieszenie od ruchu urządzenia. Jeśli urządzenie leży nieruchomo, akcelerometr pokaże 9.8 m/s² w osi Z, a Linear Acceleration — 0 we wszystkich osiach.

Jak sprawdzić, czy urządzenie ma wymagany czujnik?

Użyj getPackageManager().hasSystemFeature() z odpowiednimi stałymi: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY i innymi. Alternatywny sposób — wywołaj getDefaultSensor(type) i sprawdź wynik na null. Pierwszy sposób jest preferowany do sprawdzania na etapie inicjalizacji.

Dlaczego wartości czujnika skaczą i jak je wygładzić?

Surowe dane z czujników zawierają szumy. Do wygładzania używaj filtra dolnoprzepustowego (low-pass): newValue = alpha * rawValue + (1 — alpha) * previousValue. Współczynnik alpha = 0.1–0.3 daje dobry balans między responsywnością a gładkością. Dla żyroskopu stosuje się również filtr górnoprzepustowy (high-pass) do usuwania dryftu zera.

Czy można używać czujników w tle?

Tak, ale z ograniczeniami. Od Androida 8.0 częstotliwość zdarzeń czujnika jest zmniejszana dla aplikacji w tle. Od Androida 12 wymagane jest uprawnienie BODY_SENSORS_BACKGROUND do dostępu do czujników w tle. Do pracy w tle zaleca się użycie Foreground Service z powiadomieniem.

Podsumowanie

  • Sensors API — ujednolicony interfejs Androida do pobierania danych ze sprzętowych czujników urządzenia przez SensorManager.
  • Trzy kategorie — Motion (akcelerometr, żyroskop), Position (magnetometr) i Environment (oświetlenie, ciśnienie) o różnych zasadach działania i zastosowania.
  • Wirtualne czujniki — Gravity, Linear Acceleration i Rotation Vector oparte na fuzji danych z fizycznych sensorów i nieposiadające odpowiednika sprzętowego.
  • Optymalizacja — wybór odpowiedniego opóźnienia (SENSOR_DELAY_NORMAL, UI, GAME, FASTEST) i użycie przetwarzania wsadowego zmniejszają zużycie energii nawet o 60%.
  • Ograniczenia — Android 8+ zmniejsza częstotliwość czujników w tle, Android 12+ wymaga BODY_SENSORS_BACKGROUND do dostępu w tle.
  • Podstawowe sprawdzenie — przed rejestracją słuchacza sprawdź dostępność czujnika przez getDefaultSensor lub hasSystemFeature.
  • Używaj filtra low-pass do wygładzania szumów i anuluj rejestrację słuchacza przy przejściu w tło, aby oszczędzać baterię.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również