Sensors API — je rozhraní platformy Android pro přístup k hardwarovým senzorům zařízení. API poskytuje jednotný způsob získávání dat z akcelerometru, gyroskopu, magnetometru, světelného senzoru a dalších senzorů. Podle údajů Google, 2026 je více než 95 % moderních Android zařízení vybaveno nejméně třemi typy senzorů, což otevírá široké možnosti pro vývoj kontextově závislých aplikací.
Hlavní body
Sensors API — je programové rozhraní Android Framework, které poskytuje vývojářům přístup k hardwarovým senzorům mobilního zařízení. API je součástí Android SDK od verze 1.0 a je přístupné přes balíček android.hardware. Rozhraní abstrahuje rozdíly mezi implementacemi senzorů od různých výrobců — Qualcomm, MediaTek, Samsung Exynos — a poskytuje jednotný model práce se senzory.
API umožňuje provádět tři klíčové operace: získat seznam dostupných senzorů, registrovat posluchače pro příjem dat a spravovat frekvenci aktualizace měření. SensorManager je centrálním přístupovým bodem ke všem operacím. Systém informuje aplikaci prostřednictvím callbacku onSensorChanged, který předává objekt SensorEvent s polem float hodnot.
Během existence Androidu prošlo API několika fázemi vývoje. Ve verzi 2.3 (Gingerbread) se objevila podpora Batch Processing — seskupování událostí senzoru pro snížení spotřeby energie. Android 4.0 (Ice Cream Sandwich) přidal virtuální senzory Gravity a Linear Acceleration. Od Androidu 8.0 systém omezil přístup na pozadí k senzorům pro zvýšení soukromí.
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
Log.d("Senzory", "${sensor.name} — ${sensor.type}")
}
Ne všechna zařízení mají stejnou sadu senzorů. Aplikace musí před registrací posluchače zkontrolovat dostupnost konkrétního senzoru. Android emulátor podporuje pouze omezenou sadu senzorů — akcelerometr a magnetometr. Pro testování ostatních senzorů je vyžadováno fyzické zařízení. Od Androidu 12 musí aplikace deklarovat použití senzorů v manifestu.
Android klasifikuje všechny senzory do tří kategorií: Motion (pohyb), Position (poloha) a Environment (prostředí). Senzory Motion zahrnují akcelerometr, gyroskop a krokoměr. Senzory Position obsahují magnetometr a Orientation. Environment — světelný senzor, tlak, teplota a vlhkost.
| Kategorie | Senzory | Typ (konstanta) | Fyzický/Virtuální |
|---|---|---|---|
| Motion | Akcelerometr | TYPE_ACCELEROMETER | Fyzický |
| Motion | Gyroskop | TYPE_GYROSCOPE | Fyzický |
| Motion | Krokoměr | TYPE_STEP_COUNTER | Fyzický |
| Motion | Gravity | TYPE_GRAVITY | Virtuální |
| Position | Magnetometr | TYPE_MAGNETIC_FIELD | Fyzický |
| Position | Rotation Vector | TYPE_ROTATION_VECTOR | Virtuální |
| Environment | Světlo | TYPE_LIGHT | Fyzický |
| Environment | Tlak | TYPE_PRESSURE | Fyzický |
Akcelerometr měří zrychlení v m/s² podél tří os — X, Y a Z. Hodnoty zahrnují gravitaci (9.8 m/s² na ose Z v klidovém stavu). Gyroskop měří úhlovou rychlost v rad/s — rychlost rotace zařízení kolem každé osy. Kombinace těchto dvou senzorů se používá v navigaci, hrách a AR aplikacích.
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) {}
}
Magnetometr (TYPE_MAGNETIC_FIELD) měří magnetické pole v mikroteslách (µT) podél tří os. Používá se jako digitální kompas — v kombinaci s akcelerometrem umožňuje určit azimut zařízení. Rotation Vector — virtuální senzor, který kombinuje data z gyroskopu, akcelerometru a magnetometru pro přesné určení orientace.
Světelný senzor (TYPE_LIGHT) měří úroveň vnějšího osvětlení v luxech (lx). Používá se pro automatické nastavení jasu obrazovky. Tlakový senzor (TYPE_PRESSURE) měří atmosférický tlak v hektopascalech (hPa) — používá se v navigačních aplikacích pro určení nadmořské výšky.
Sensors API je postaveno na architektuře klient-server. Aplikace funguje jako klient, SensorManager — jako systémová služba Androidu. Když aplikace registruje posluchače prostřednictvím registerListener, SensorManager se připojí k HAL (Hardware Abstraction Layer) — nízkodrovňovému ovladači senzoru pracujícímu na úrovni linuxového jádra.
Ovladač HAL přijímá surová data z hardwarového čipu, filtruje šum a předává je nahoru zásobníkem — přes SensorService (systémový proces) do aplikace. Data jsou přenášena jako objekt SensorEvent obsahující pole float hodnot values a časové razítko v nanosekundách. Frekvence událostí závisí na zvoleném režimu doručení.
Při registraci posluchače vývojář specifikuje požadované zpoždění mezi událostmi pomocí konstant SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) a SENSOR_DELAY_FASTEST (0 ms — maximální frekvence). Skutečná frekvence se může lišit — systém optimalizuje spotřebu energie.
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
this,
sensor,
SensorManager.SENSOR_DELAY_GAME
)
Od Androidu 2.3 senzory podporují dávkový režim — události se hromadí ve FIFO bufferu a jsou doručeny v jednom balíku. To umožňuje procesoru zůstat déle v režimu spánku, což snižuje spotřebu energie až o 60 %. Velikost bufferu závisí na čipu senzoru a je uvedena v poli Sensor.fifoMaxEventCount.
SensorManager — systémová služba přístupná přes getSystemService(Context.SENSOR_SERVICE). Poskytuje metody pro získání seznamu senzorů, získání konkrétního výchozího senzoru a registraci/zrušení posluchačů. SensorManager — singleton, jedna instance pro celou aplikaci.
Před použitím senzoru je nutné zkontrolovat jeho existenci. Metoda getDefaultSensor(type) vrací null, pokud senzor není na zařízení k dispozici. Získání null bez kontroly povede k NullPointerException při registraci posluchače. Seznam všech senzorů vrací metoda getSensorList(type).
fun checkSensorAvailability(type: Int): Boolean {
val sensorManager =
getSystemService(Context.SENSOR_SERVICE) as SensorManager
return sensorManager.getDefaultSensor(type) != null
}
// Použití:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
Log.d("Sensor", "Gyroskop je k dispozici")
}
Posluchač se registruje prostřednictvím registerListener(listener, sensor, delay). Důležité: zrušení posluchače musí být provedeno v metodě onPause() pomocí unregisterListener(listener). Pokud se tak nestane, aplikace bude nadále přijímat události senzoru, vybíjet baterii i na pozadí. Android 8+ zobrazuje varování v logcat o neregistrovaných posluchačích.
Metoda onAccuracyChanged(sensor, accuracy) je volána při změně přesnosti senzoru. Hodnoty: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW a UNRELIABLE. Při obdržení UNRELIABLE by měla být data senzoru ignorována, dokud se přesnost neobnoví. Například magnetometr vyžaduje kalibraci — třesení zařízením ve tvaru osmičky.
Podívejme se na praktické příklady použití Sensors API v Android aplikacích v Kotlin. První příklad — určení orientace obrazovky pomocí akcelerometru. Druhý — čtení údajů magnetometru s kalibrací. Třetí — detektor kroků pomocí krokoměru.
Pro určení orientace se používá kombinace akcelerometru a magnetometru. Metoda SensorManager.getRotationMatrix() vypočítá rotační matici a getOrientation() extrahuje úhly pitch, roll a azimuth. Azimuth (azimut) — úhel vůči magnetickému severu v radiánech.
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] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())
Krokoměr (TYPE_STEP_COUNTER) vrací celkový počet kroků, které uživatel udělal od posledního restartu zařízení. Senzor pracuje na hardwarové úrovni — je aktivní, i když aplikace není spuštěna. Pro získání počtu kroků za relaci je třeba uložit počáteční hodnotu a vypočítat rozdíl.
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("Kroky", "Kroků za relaci: $sessionSteps")
}
}
Světelný senzor umožňuje přizpůsobit rozhraní okolním podmínkám. Při nízkém osvětlení (méně než 10 lx) lze přepnout na tmavý motiv. Při jasném slunečním světle (více než 10000 lx) — zvýšit kontrast. Pro filtrování šumu se používá klouzavý průměr posledních 5 hodnot.
Android poskytuje několik virtuálních senzorů, které nemají přímý hardwarový ekvivalent. Virtuální senzor vypočítává své hodnoty na základě kombinace fyzických senzorů. To snižuje zátěž vývojáře — systém sám implementuje algoritmy fúze dat.
Senzor Gravity (TYPE_GRAVITY) extrahuje gravitační složku z měření akcelerometru pomocí dolní propusti (low-pass filtru). Linear Acceleration (TYPE_LINEAR_ACCELERATION) — naopak, odstraňuje gravitaci a ponechává pouze lineární zrychlení zařízení. Součet Gravity a Linear Acceleration dává surová měření akcelerometru.
Rotation Vector — nejsložitější virtuální senzor. Kombinuje data z gyroskopu (vysokofrekvenční změny), akcelerometru (vektor gravitace) a magnetometru (orientace vůči severu). Výsledkem je kvaternion popisující absolutní orientaci zařízení v prostoru. Používá se v AR aplikacích a VR headsety.
Game Rotation Vector — zjednodušená verze Rotation Vector bez použití magnetometru. To poskytuje nižší přesnost určení azimutu, ale vyšší frekvenci aktualizace a stabilitu. Doporučuje se pro hry, kde je důležitá nízká latence, nikoli absolutní orientace vůči severu.
Senzory — jedna z nejvíce energeticky náročných součástí zařízení. Akcelerometr a gyroskop při maximální frekvenci dotazování mohou vybít baterii za 3–4 hodiny nepřetržitého provozu. Optimalizace práce se senzory je kritickým úkolem pro každou aplikaci používající Sensors API.
Nepoužívejte SENSOR_DELAY_FASTEST bez potřeby. Pro UI animace stačí SENSOR_DELAY_UI (60 ms). Pro určení orientace obrazovky — SENSOR_DELAY_NORMAL (200 ms). Čím vyšší frekvence, tím více času tráví procesor v aktivním stavu. Rozdíl mezi NORMAL a FASTEST je až 10x ve spotřebě energie.
Od Androidu 8.0 (API 26) dostávají aplikace na pozadí události senzorů se sníženou frekvencí. V Androidu 12+ vyžaduje přístup na pozadí k senzorům Motion a Position oprávnění BODY_SENSORS_BACKGROUND. Zrušte registraci posluchače při přechodu aplikace do režimu na pozadí — to prodlužuje výdrž baterie zařízení.
Používejte dávkové zpracování prostřednictvím metody registerListener(listener, sensor, delay, maxReportLatencyUs). Parametr maxReportLatencyUs určuje maximální zpoždění doručení událostí v mikrosekundách. Při hodnotě 1000000 (1 sekunda) se události hromadí ve FIFO bufferu senzoru a jsou doručeny jednou za sekundu — procesor se méně často probouzí ze spánku.
Často kladené otázky
Minimální sada — akcelerometr a magnetometr. Tyto dva senzory jsou přítomny na více než 95 % zařízení. Gyroskop, světelný senzor a senzor přiblížení — na 70–80 % moderních modelů. Ostatní senzory (tlak, teplota, vlhkost, krokoměr) jsou méně běžné a závisí na cenové kategorii zařízení.
TYPE_ACCELEROMETER vrací plné zrychlení včetně gravitace (9.8 m/s²). TYPE_LINEAR_ACCELERATION vrací zrychlení bez gravitace — pouze zrychlení od pohybu zařízení. Pokud zařízení leží nehybně, akcelerometr ukáže 9.8 m/s² na ose Z, zatímco Linear Acceleration — 0 na všech osách.
Použijte getPackageManager().hasSystemFeature() s odpovídajícími konstantami: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY a dalšími. Alternativní způsob — zavolat getDefaultSensor(type) a zkontrolovat výsledek na null. První způsob je preferován pro kontrolu ve fázi inicializace.
Surová data ze senzorů obsahují šum. Pro vyhlazení použijte dolní propust (low-pass filtr): newValue = alpha * rawValue + (1 — alpha) * previousValue. Koeficient alpha = 0.1–0.3 poskytuje dobrou rovnováhu mezi odezvou a hladkostí. Pro gyroskop se také používá horní propust (high-pass filtr) pro odstranění nulového driftu.
Ano, ale s omezeními. Od Androidu 8.0 je frekvence událostí senzoru snížena pro aplikace na pozadí. Od Androidu 12 je vyžadováno oprávnění BODY_SENSORS_BACKGROUND pro přístup k senzorům na pozadí. Pro práci na pozadí se doporučuje použít Foreground Service s notifikací.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také