Датчики руху в Android: Sensor API, події, батчі

Неправильна робота з датчиками руху призводить до перегріву пристрою та швидкого розряду батареї. Ми розробляємо Android-застосунки з коректним використанням Sensor API, підбираючи оптимальні віртуальні датчики та батч-оновлення. Наша команда реалізує проєкт під ключ — від аудиту до підтримки, забезпечуючи стабільну роботу без зриву термінів.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Датчики руху в Android: Sensor API, події, батчі
Середній
від 1 дня до 3 днів
Часті запитання

Перегрів пристрою через неправильну частоту опитування датчиків — типова проблема. Розряд батареї за годину замість дня. Ми стикалися з проектом, де sensor fusion видавав випадкові кватерніони на дешевих телефонах. Рішення — правильний вибір віртуальних датчиків та батч-оновлень. Більше 5 років досвіду та більше 20 проектів із датчиками руху — за нашими плечима.

Android Sensor Framework надає доступ до 13+ типів датчиків через єдиний SensorManager. Акселерометр та гіроскоп — апаратні. TYPE_LINEAR_ACCELERATION, TYPE_ROTATION_VECTOR, TYPE_GRAVITY — віртуальні: обчислюються з апаратних через sensor fusion у firmware. Різниця в тому, що віртуальні датчики споживають більше CPU при високій частоті та можуть бути недоступні на бюджетних пристроях. Детальніше — в Android Developer: Sensors Overview. Наш досвід показує: для точної орієнтації використовуйте TYPE_ROTATION_VECTOR, для лінійного прискорення — TYPE_LINEAR_ACCELERATION.

Реєстрація та життєвий цикл

class SensorViewModel(application: Application) : AndroidViewModel(application) {
    private val sensorManager = application.getSystemService(SENSOR_SERVICE) as SensorManager
    private val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    private val gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
    private val _sensorData = MutableStateFlow<SensorData>(SensorData.Empty)
    val sensorData: StateFlow<SensorData> = _sensorData.asStateFlow()
    private val sensorEventListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            when (event.sensor.type) {
                Sensor.TYPE_ACCELEROMETER -> handleAccelerometer(event.values)
                Sensor.TYPE_GYROSCOPE -> handleGyroscope(event.values)
            }
        }
        override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
    }
    fun startListening() {
        accelerometer?.let {
            sensorManager.registerListener(
                sensorEventListener,
                it,
                SensorManager.SENSOR_DELAY_GAME // ~20ms
            )
        }
    }
    fun stopListening() {
        sensorManager.unregisterListener(sensorEventListener)
    }
    override fun onCleared() {
        stopListening()
    }
}

Ключове: unregisterListener строго в onCleared() ViewModel або в onPause() Activity. Забутий listener працює у фоні, жере батарею та може крашити застосунок при знищенні Activity.

Частоти опитування: константи та реальність

Константа Номінальна затримка Реальна частота
SENSOR_DELAY_NORMAL 200 мс ~5 Гц
SENSOR_DELAY_UI 60 мс ~16 Гц
SENSOR_DELAY_GAME 20 мс ~50 Гц
SENSOR_DELAY_FASTEST 0 мс максимум заліза

З Android API 9 можна задавати довільний інтервал у мікросекундах через registerListener(listener, sensor, samplingPeriodUs). Наприклад, 10000 мкс = 100 Гц.

SENSOR_DELAY_FASTEST на Snapdragon 8 Gen 2 дає до 500 Гц на акселерометрі — це потрібно тільки для спеціалізованих застосунків (аналіз вібрацій, балансування). Для більшості задач 50–100 Гц достатньо.

Чому Sensor Fusion в Android вимагає калібрування?

Датчики на дешевих пристроях мають зсуви та шум. Віртуальні датчики (TYPE_ROTATION_VECTOR) використовують вбудоване калібрування firmware, але на старих ядрах можуть дрейфувати. Ми тестуємо на апаратах різних вендорів та при необхідності додаємо свій фільтр (Mahony/Madgwick) для корекції.

TYPE_ROTATION_VECTOR — кватерніон орієнтації пристрою, обчислений з акселерометра + гіроскопа + магнітометра. Точніше ніж робити fusion вручну:

val rotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
// В onSensorChanged:
val rotationMatrix = FloatArray(9)
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
val orientationAngles = FloatArray(3)
SensorManager.getOrientation(rotationMatrix, orientationAngles)
val azimuth = Math.toDegrees(orientationAngles[0].toDouble()) // 0-360° від півночі
val pitch = Math.toDegrees(orientationAngles[1].toDouble()) // -90 до +90°
val roll = Math.toDegrees(orientationAngles[2].toDouble()) // -180 до +180°

TYPE_LINEAR_ACCELERATION — акселерометр без гравітації (аналог userAcceleration в iOS CoreMotion). Використовуємо замість TYPE_ACCELEROMETER коли потрібно вимірювати тільки динамічне прискорення.

Як реалізувати детекцію падіння?

  1. Використовуйте акселерометр із частотою 50 Гц.
  2. Застосуйте високочастотний фільтр для відділення гравітації:
    val gravity = FloatArray(3)
    val linearAccel = FloatArray(3)
    val alpha = 0.8f
    
    // В onSensorChanged для TYPE_ACCELEROMETER:
    gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]
    gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]
    gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2]
    
    linearAccel[0] = event.values[0] - gravity[0]
    linearAccel[1] = event.values[1] - gravity[1]
    linearAccel[2] = event.values[2] - gravity[2]
    
    val magnitude = sqrt(
        linearAccel[0].pow(2) +
        linearAccel[1].pow(2) +
        linearAccel[2].pow(2)
    )

    Для носимих пристроїв (літні люди, шахтарі) цей метод чудово працює.

    Як організувати фоновий моніторинг без перевитрати батареї?

    Використовуйте батч-оновлення (maxReportLatencyUs) та JobScheduler для періодичної обробки. Віртуальні датчики у фоні краще не використовувати — вони споживають CPU постійно. Для простої детекції активності (кроки, спокій) достатньо акселерометра з частотою 5-10 Гц та батчем в 1 секунду (1000 мс).

    Класифікація активностей

    Паттерни: ходьба — регулярні піки 1.5–2.5 м/с² з частотою 1.5–2.5 Гц. Їзда — низькочастотні вібрації < 0.5 Гц. Спокій — magnitude < 0.1 м/с². Для класифікації використовуйте простий пороговий детектор або модель машинного навчання (наприклад, випадковий ліс) — це покращує точність до 95%.

    Батч-оновлення (Android 4.4+)

    SensorManager.flush() та параметр maxReportLatencyUs в registerListener дозволяють накопичувати дані в hardware FIFO та отримувати пачками. Корисно для фонових застосунків — сенсор копить дані, поки CPU спить, прокидається раз на N секунд, віддає все одразу:

    sensorManager.registerListener(
        listener,
        accelerometer,
        10_000, // samplingPeriodUs = 100 Гц
        500_000 // maxReportLatencyUs = 500 мс
        batch
    )

    Об'єм FIFO у різних чипсетів різний (512–4096 семплів). При переповненні старі дані витісняються — враховуйте при тривалих сесіях.

    Що входить у роботу з інтеграції датчиків

    • Аналіз — вибір датчиків під сценарій (навігація, трекінг активності, носимі пристрої)
    • Архітектура — ViewModel/Service, обробка lifecycle, сенсорна оптимізація батареї
    • Реалізація — реєстрація, фільтрація, класифікація подій (падіння, кроки, повороти)
    • Тестування — на реальних пристроях (5+ моделей з різними чипсетами)
    • Підтримка — документація API, навчання команди, гарантія на код до 6 місяців

    Порівняння підходів до sensor fusion

    Характеристика TYPE_ROTATION_VECTOR (вбудований) Ручний Madgwick/Mahony
    Точність на дорогих пристроях ±1° ±2-3° після калібрування
    Споживання CPU Низьке Високе (оновлення 200+ раз/с)
    Підтримка на бюджетних телефонах Часто немає Працює всюди
    Складність інтеграції Мінімальна Потрібне налаштування параметрів

    Наш досвід: для 90% проектів вистачає вбудованих віртуальних датчиків. Ручний fusion потрібний тільки для AR/VR або роботи з застарілими SoC.

    Терміни

    Базова інтеграція 1–2 датчиків з обробкою даних — від 3 до 5 робочих днів. Багатодатчиковий алгоритм із класифікацією активностей, фоновим записом та аналітикою — від 2 до 4 тижнів. Вартість розраховується індивідуально після аналізу вимог. Часові рамки уточнюємо після аудиту вашого проекту.

    Наша команда — більше 5 років досвіду та більше 20 успішних проектів із датчиками руху. Замовте консультацію — оцінимо feasibility та запропонуємо архітектуру під ваш сценарій. Отримайте якісну інтеграцію з гарантією на код до 6 місяців.

    Детальніше про Sensor API читайте в офіційній документації Android.

Наші компетенції:

Останні роботи

  • Розробка мобільного додатка для компанії FEEDME
    Розробка мобільного додатка для компанії FEEDME
    1010
  • Розробка мобільного додатку для компанії XOOMER
    Розробка мобільного додатку для компанії XOOMER
    903
  • Розробка мобільного додатку для компанії RHL
    Розробка мобільного додатку для компанії RHL
    1332
  • Розробка мобільного додатку для компанії ZIPPY
    Розробка мобільного додатку для компанії ZIPPY
    1180
  • Розробка мобільного додатку для компанії Affhome
    Розробка мобільного додатку для компанії Affhome
    1107
  • Розробка мобільного додатку для компанії FLAVORS
    Розробка мобільного додатку для компанії FLAVORS
    714