Sensors API: какво е това, типове сензори и работа със сензори

Автор: IT Sectr Публикувано: 2026-03-26 Време за четене: 10 мин

Sensors API — интерфейс на платформата Android за достъп до хардуерните сензори на устройството. API предоставя унифициран начин за получаване на данни от акселерометър, жироскоп, магнитометър, сензор за осветеност и други сензори. Според данни на Google, 2026, над 95% от съвременните Android устройства са оборудвани с поне три типа сензори, което отваря широки възможности за разработка на контекстно-зависими приложения.

Основни моменти

  • Sensors API — унифициран Android интерфейс за работа с хардуерните сензори на устройството.
  • Три категории — сензори Motion, Position и Environment с различни принципи на измерване.
  • SensorManager — системна услуга за получаване на списък със сензори и регистриране на слушатели.
  • Честота на обновяване се задава чрез константите SENSOR_DELAY от NORMAL до FASTEST.
  • Виртуални сензори — Gravity, Rotation Vector и Linear Acceleration, базирани на комбинация от физически сензори.

Какво е Sensors API в Android?

Sensors API — програмен интерфейс на Android Framework, предоставящ на разработчиците достъп до хардуерните сензори на мобилното устройство. API е част от Android SDK от версия 1.0 и е достъпен чрез пакета android.hardware. Интерфейсът абстрахира разликите между имплементациите на сензори от различни производители — Qualcomm, MediaTek, Samsung Exynos — и предоставя унифициран модел за работа със сензори.

Основни възможности на Sensors API

API позволява изпълнението на три ключови операции: получаване на списък с налични сензори, регистриране на слушатели за получаване на данни и управление на честотата на обновяване на показанията. SensorManager е централната точка за достъп до всички операции. Системата уведомява приложението чрез callback onSensorChanged, предавайки обект SensorEvent с масив от float стойности.

Еволюция на Sensors API

По време на съществуването на Android, API премина през няколко етапа на развитие. Във версия 2.3 (Gingerbread) се появи поддръжка за Batch Processing — групиране на събития от сензори за намаляване на консумацията на енергия. Android 4.0 (Ice Cream Sandwich) добави виртуалните сензори Gravity и Linear Acceleration. От Android 8.0 системата ограничи фонов достъп до сензори за повишаване на поверителността.

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

Ограничения и изисквания

Не всички устройства имат еднакъв набор от сензори. Приложението трябва да провери наличността на конкретен сензор преди регистриране на слушател. Android емулаторът поддържа само ограничен набор от сензори — акселерометър и магнитометър. За тестване на останалите сензори е необходимо физическо устройство. От Android 12 приложенията трябва да декларират използването на сензори в манифеста.

Типове Android сензори: Motion, Position, Environment

Android класифицира всички сензори в три категории: Motion (движение), Position (положение) и Environment (околна среда). Motion сензорите включват акселерометър, жироскоп и крачкомер. Position сензорите включват магнитометър и Orientation. Environment — сензор за осветеност, налягане, температура и влажност.

КатегорияСензориТип (константа)Физически/Виртуален
MotionАкселерометърTYPE_ACCELEROMETERФизически
MotionЖироскопTYPE_GYROSCOPEФизически
MotionКрачкомерTYPE_STEP_COUNTERФизически
MotionGravityTYPE_GRAVITYВиртуален
PositionМагнитометърTYPE_MAGNETIC_FIELDФизически
PositionRotation VectorTYPE_ROTATION_VECTORВиртуален
EnvironmentОсветеностTYPE_LIGHTФизически
EnvironmentНаляганеTYPE_PRESSUREФизически

Motion сензори: акселерометър и жироскоп

Акселерометърът измерва ускорението в m/s² по три оси — X, Y и Z. Стойностите включват гравитацията (9.8 m/s² по оста Z в покой). Жироскопът измерва ъгловата скорост в rad/s — скоростта на въртене на устройството около всяка ос. Комбинацията от тези два сензора се използва в навигация, игри и 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) {}
}

Position сензори: магнитометър и ориентация

Магнитометърът (TYPE_MAGNETIC_FIELD) измерва магнитното поле в микротесла (µT) по три оси. Използва се като цифров компас — в комбинация с акселерометъра позволява определяне на азимута на устройството. Rotation Vector — виртуален сензор, който обединява данни от жироскоп, акселерометър и магнитометър за точно определяне на ориентацията.

Environment сензори: осветеност, налягане, температура

Сензорът за осветеност (TYPE_LIGHT) измерва нивото на външно осветление в лукс (lx). Използва се за автоматично регулиране на яркостта на екрана. Сензорът за налягане (TYPE_PRESSURE) измерва атмосферното налягане в хектопаскали (hPa) — прилага се в навигационни приложения за определяне на надморска височина.

Как работи архитектурата на Sensors API

Sensors API е изграден върху клиент-сървър архитектура. Приложението действа като клиент, SensorManager — като системна услуга на Android. Когато приложението регистрира слушател чрез registerListener, SensorManager се свързва с HAL (Hardware Abstraction Layer) — нисконивов драйвер на сензора, работещ на ниво ядро на Linux.

Жизнен цикъл на събитие от сензор

HAL драйверът получава сурови данни от хардуерния чип, филтрира шума и ги предава нагоре по стека — чрез SensorService (системен процес) към приложението. Данните се предават като обект SensorEvent, съдържащ масив от float стойности values и времеви клеймо в наносекунди. Честотата на събитията зависи от избрания режим на доставка.

Режими на доставка на събития

При регистриране на слушател, разработчикът задава желаното закъснение между събитията чрез константите SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) и SENSOR_DELAY_FASTEST (0 ms — максимална честота). Реалната честота може да се различава — системата оптимизира консумацията на енергия.

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

Пакетна обработка (Batch Processing)

От Android 2.3 сензорите поддържат пакетен режим — събитията се натрупват в FIFO буфер и се доставят в един пакет. Това позволява на процесора да остане по-дълго в режим на сън, намалявайки консумацията на енергия до 60%. Размерът на буфера зависи от чипа на сензора и е посочен в полето Sensor.fifoMaxEventCount.

Използване на SensorManager за достъп до сензори

SensorManager — системна услуга, достъпна чрез getSystemService(Context.SENSOR_SERVICE). Предоставя методи за получаване на списък със сензори, получаване на конкретен сензор по подразбиране и регистриране/отмяна на слушатели. SensorManager — сингълтън, един екземпляр за цялото приложение.

Проверка на наличността на сензор

Преди използване на сензора трябва да се провери неговото наличие. Методът getDefaultSensor(type) връща null, ако сензорът не е наличен на устройството. Получаване на null без проверка ще доведе до NullPointerException при регистриране на слушател. Списъкът на всички сензори се връща от метода getSensorList(type).

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

// Използване:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
    Log.d("Sensor", "Жироскопът е наличен")
}

Регистриране и отмяна на слушател

Слушателят се регистрира чрез registerListener(listener, sensor, delay). Важно: отмяната на слушателя трябва да се извърши в метода onPause() чрез unregisterListener(listener). Ако това не бъде направено, приложението ще продължи да получава събития от сензора, изтощавайки батерията дори на фонов режим. Android 8+ показва предупреждение в logcat за нерегистрирани слушатели.

Обработка на промяна на точността

Методът onAccuracyChanged(sensor, accuracy) се извиква при промяна на точността на сензора. Стойности: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW и UNRELIABLE. При получаване на UNRELIABLE данните от сензора трябва да се игнорират до възстановяване на точността. Например, магнитометърът изисква калибриране — разклащане на устройството във формата на осмица.

Примери за код за работа със сензори в Kotlin

Нека разгледаме практически примери за използване на Sensors API в Android приложения на Kotlin. Първи пример — определяне на ориентацията на екрана с помощта на акселерометър. Втори — отчитане на показанията на магнитометъра с калибриране. Трети — детектор на стъпки с крачкомер.

Определяне на ориентацията на устройството

За определяне на ориентацията се използва комбинация от акселерометър и магнитометър. Методът SensorManager.getRotationMatrix() изчислява ротационна матрица, а getOrientation() извлича ъглите pitch, roll и azimuth. Azimuth (азимут) — ъгълът спрямо магнитния север в радиани.

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] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())

Детектор на стъпки с крачкомер

Крачкомерът (TYPE_STEP_COUNTER) връща общия брой стъпки, направени от потребителя от последното рестартиране на устройството. Сензорът работи на хардуерно ниво — активен е дори когато приложението не работи. За получаване на броя стъпки на сесия е необходимо да се запази началната стойност и да се изчисли разликата.

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("Стъпки", "Стъпки на сесия: $sessionSteps")
    }
}

Адаптивна яркост по сензор за осветеност

Сензорът за осветеност позволява адаптиране на интерфейса към условията на околната среда. При ниска осветеност (под 10 lx) може да се превключи на тъмна тема. При ярка слънчева светлина (над 10000 lx) — да се увеличи контрастът. За филтриране на шума се използва пълзяща средна на последните 5 стойности.

Виртуални сензори и алгоритми за сливане

Android предоставя няколко виртуални сензора, които нямат пряк хардуерен еквивалент. Виртуалният сензор изчислява своите показания на базата на комбинация от физически сензори. Това намалява натоварването на разработчика — системата сама имплементира алгоритмите за сливане на данни.

Gravity и Linear Acceleration

Сензорът Gravity (TYPE_GRAVITY) извлича гравитационния компонент от показанията на акселерометъра с помощта на нискочестотен (low-pass) филтър. Linear Acceleration (TYPE_LINEAR_ACCELERATION) — обратно, премахва гравитацията и оставя само линейното ускорение на устройството. Сумата от Gravity и Linear Acceleration дава суровите показания на акселерометъра.

Rotation Vector

Rotation Vector — най-сложният виртуален сензор. Той комбинира данни от жироскоп (високочестотни промени), акселерометър (гравитационен вектор) и магнитометър (ориентация спрямо север). Резултатът — кватернион, описващ абсолютната ориентация на устройството в пространството. Използва се в AR приложения и VR очила.

Game Rotation Vector

Game Rotation Vector — опростена версия на Rotation Vector без използване на магнитометър. Това осигурява по-ниска точност на определяне на азимута, но по-висока честота на обновяване и стабилност. Препоръчва се за игри, където ниската латентност е важна, а не абсолютната ориентация спрямо север.

Оптимизация на консумацията на енергия при работа със сензори

Сензорите — един от най-енергоемките компоненти на устройството. Акселерометърът и жироскопът при максимална честота на запитване могат да изтощят батерията за 3–4 часа непрекъсната работа. Оптимизацията на работата със сензори е критична задача за всяко приложение, използващо Sensors API.

Избор на оптимално закъснение

Не използвайте SENSOR_DELAY_FASTEST без необходимост. За UI анимации е достатъчен SENSOR_DELAY_UI (60 ms). За определяне на ориентацията на екрана — SENSOR_DELAY_NORMAL (200 ms). Колкото по-висока е честотата, толкова повече време процесорът прекарва в активно състояние. Разликата между NORMAL и FASTEST е до 10x в консумацията на енергия.

Отмяна на слушатели на фонов режим

От Android 8.0 (API 26) фоноворежимните приложения получават събития от сензори с намалена честота. В Android 12+ фоновият достъп до Motion и Position сензори изисква разрешение BODY_SENSORS_BACKGROUND. Отменяйте регистрацията на слушателя при преминаване на приложението във фонов режим — това удължава живота на батерията.

Пакетна обработка и FIFO буфер

Използвайте пакетна обработка чрез метода registerListener(listener, sensor, delay, maxReportLatencyUs). Параметърът maxReportLatencyUs задава максималното закъснение на доставка на събития в микросекунди. При стойност 1000000 (1 секунда) събитията се натрупват във FIFO буфера на сензора и се доставят веднъж в секунда — процесорът по-рядко излиза от режим на сън.

Често задавани въпроси

Какви сензори има на всички Android устройства?

Минималният набор — акселерометър и магнитометър. Тези два сензора присъстват на над 95% от устройствата. Жироскоп, сензор за осветеност и сензор за близост — на 70–80% от съвременните модели. Останалите сензори (налягане, температура, влажност, крачкомер) се срещат по-рядко и зависят от ценовата категория на устройството.

Каква е разликата между TYPE_ACCELEROMETER и TYPE_LINEAR_ACCELERATION?

TYPE_ACCELEROMETER връща пълното ускорение, включително гравитацията (9.8 m/s²). TYPE_LINEAR_ACCELERATION връща ускорение без гравитация — само ускорението от движението на устройството. Ако устройството лежи неподвижно, акселерометърът ще покаже 9.8 m/s² по оста Z, а Linear Acceleration — 0 по всички оси.

Как да проверя дали устройството има нужния сензор?

Използвайте getPackageManager().hasSystemFeature() със съответните константи: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY и други. Алтернативен начин — извикайте getDefaultSensor(type) и проверете резултата за null. Първият начин е за предпочитане за проверка в етапа на инициализация.

Защо стойностите на сензора скачат и как да ги изгладя?

Суровите данни от сензорите съдържат шум. За изглаждане използвайте нискочестотен (low-pass) филтър: newValue = alpha * rawValue + (1 — alpha) * previousValue. Коефициентът alpha = 0.1–0.3 дава добър баланс между отзивчивост и гладкост. За жироскопа се прилага и високочестотен (high-pass) филтър за премахване на нулевия дрейф.

Могат ли да се използват сензори във фонов режим?

Да, но с ограничения. От Android 8.0 честотата на събитията от сензори се намалява за фоноворежимни приложения. От Android 12 се изисква разрешение BODY_SENSORS_BACKGROUND за достъп до сензори на фонов режим. За фонова работа се препоръчва използването на Foreground Service с известие.

Обобщение

  • Sensors API — унифициран Android интерфейс за получаване на данни от хардуерните сензори на устройството чрез SensorManager.
  • Три категории — Motion (акселерометър, жироскоп), Position (магнитометър) и Environment (осветеност, налягане) с различни принципи на работа и приложения.
  • Виртуални сензори — Gravity, Linear Acceleration и Rotation Vector, базирани на сливане на данни от физически сензори, без хардуерен еквивалент.
  • Оптимизация — избор на правилно закъснение (SENSOR_DELAY_NORMAL, UI, GAME, FASTEST) и използване на пакетна обработка намаляват консумацията на енергия до 60%.
  • Ограничения — Android 8+ намалява честотата на сензорите на фонов режим, Android 12+ изисква BODY_SENSORS_BACKGROUND за фонов достъп.
  • Основна проверка — преди регистриране на слушател проверявайте наличността на сензора чрез getDefaultSensor или hasSystemFeature.
  • Използвайте low-pass филтър за изглаждане на шум и отменяйте регистрацията на слушателя при преминаване на фонов режим за пестене на батерия.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също