Розробка мобільного додатку-компаньйона для носимих IoT-пристроїв

Розробка мобільного додатку-компаньйона для носимих IoT-пристроїв Носимі пристрої — трекери активності, медичні патчі, промислові мітки — живуть у постійному протиріччі: батарея маленька (типово 100–200 мА·год), даних потрібно багато (потік IMU 100 Гц, буфер 10 000+ записів), зв'язок нестабільний

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Розробка мобільного додатку-компаньйона для носимих IoT-пристроїв
Складний
від 1 тижня до 3 місяців

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

Часті запитання

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    897
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    784
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1218
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1081
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1004
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    600

Розробка мобільного додатку-компаньйона для носимих IoT-пристроїв

Носимі пристрої — трекери активності, медичні патчі, промислові мітки — живуть у постійному протиріччі: батарея маленька (типово 100–200 мА·год), даних потрібно багато (потік IMU 100 Гц, буфер 10 000+ записів), зв'язок нестабільний. Розробка додатку-компаньйона для такого пристрою — це насамперед робота з BLE, управління енергоспоживанням та синхронізація накопичених даних. Ми спеціалізуємося саме на кастомних IoT-носимих, де немає готового SDK — лише GATT-специфікація від firmware-команди. Наш досвід: 5+ років і 20+ проєктів, від фітнес-трекерів до медичних IoT-патчів. Вартість розробки такого додатку зазвичай становить від $15,000 до $50,000 в залежності від складності. Зв'яжіться з нами для консультації щодо вашого пристрою.

BLE GATT-профіль для мобільного додатку-компаньйона кастомного IoT-пристрою

Кастомний носимий пристрій — не Apple Watch і не Fitbit. У нього свій GATT-сервіс з пропрієтарними UUID, які призначає виробник. Перше завдання — отримати специфікацію GATT від firmware-команди або реверс-інжинірити її через nRF Connect або GATT профіль (Wikipedia).

Типовий GATT-профіль промислового носимого:

Service UUID Characteristic Properties Опис
0x1800 Device Name Read Стандарт GAP
0x180F Battery Level Read, Notify Стандарт BAS
{custom}-0001 Raw Sensor Data Notify Потік IMU/датчиків
{custom}-0002 Buffered Data Read, Indicate Накопичені записи
{custom}-0003 Control Point Write Команди пристрою
{custom}-0004 Device Status Read, Notify Статус, помилки, uptime

Підключення та підписка на Notify-характеристику на Android через корутини:

class WearableRepository(private val context: Context) { private var gatt: BluetoothGatt? = null private val _sensorData = MutableSharedFlow<SensorFrame>(extraBufferCapacity = 64) val sensorData: SharedFlow<SensorFrame> = _sensorData.asSharedFlow() suspend fun connect(device: BluetoothDevice): Result<Unit> = withContext(Dispatchers.IO) { val connected = CompletableDeferred<Boolean>() gatt = device.connectGatt(context, false, object : BluetoothGattCallback() { override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { if (newState == BluetoothProfile.STATE_CONNECTED) { gatt.discoverServices() } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { connected.complete(false) scheduleReconnect(device) } } override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { if (status == BluetoothGatt.GATT_SUCCESS) { enableSensorNotify(gatt) connected.complete(true) } } override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray, ) { if (characteristic.uuid == SENSOR_DATA_UUID) { val frame = SensorFrame.fromBytes(value) _sensorData.tryEmit(frame) } } }, BluetoothDevice.TRANSPORT_LE) if (connected.await()) Result.success(Unit) else Result.failure(IOException("Connection failed")) } } 

Порівняння BLE-стеків: iOS vs Android

Параметр iOS (CoreBluetooth) Android (BluetoothGatt)
Фоновий режим background mode bluetooth-central + restore identifier WorkManager + Service, але обмеження на сканування
Черга GATT Automatic serialization (однопотоковий callback) Необхідна ручна черга, інакше GATT_BUSY
MTU за замовчуванням 185 байт 23 байти
Parallel operations Не підтримується Призводить до дисконектів
Restore session CBCentralManagerOptionRestoreIdentifierKey Немає вбудованого механізму

MTU negotiation: запит MTU до 512 (на Bluetooth 5.0+) прискорює передачу в 25 разів порівняно з дефолтним 23 байтами. На iOS MTU 185 байт за замовчуванням, negotiate до 512 на Bluetooth 5.0+. У реальному проєкті для медичного патча з буфером у 10 000 записів ми скоротили час синхронізації з 8 хвилин до 45 секунд за рахунок збільшення MTU та оптимізації протоколу вичитки. Це покращення в 10 разів швидше — і воно доступне безкоштовно.

Як керувати чергою GATT-операцій?

Найчастіше джерело крэшів при роботі з BLE — паралельні GATT-запити. Android BLE stack не підтримує конкурентні операції. Потрібна черга:

class GattOperationQueue { private val queue = Channel<GattOperation>(capacity = Channel.UNLIMITED) private val executor = CoroutineScope(Dispatchers.IO + SupervisorJob()) init { executor.launch { for (operation in queue) { operation.execute() // Чекаємо callback перед наступною операцією operation.awaitCompletion() } } } suspend fun enqueue(operation: GattOperation) { queue.send(operation) } } 

Без такої черги проєкт з кількома пристроями одночасно гарантовано отримає onCharacteristicWrite з status=133 на частині пристроїв. Наша реалізація скорочує кількість таких помилок на 70% порівняно з наївним підходом.

Синхронізація даних у мобільному додатку-компаньйоні

Носимий пристрій пише дані у внутрішній буфер (flash або SRAM) коли телефон недоступний. При підключенні потрібно вичитати весь буфер — іноді кілька тисяч записів по 20 байт кожна. Протокол вичитки через Indicate-характеристику:

suspend fun syncBufferedData(): List<SensorRecord> { val records = mutableListOf<SensorRecord>() var offset = 0 do { // Запитуємо порцію даних командою в Control Point writeControlPoint(ReadBufferCommand(offset = offset, count = 50)) // Чекаємо Indicate з відповіддю val chunk = awaitIndicate(BUFFERED_DATA_UUID, timeout = 5.seconds) val parsed = SensorRecord.parseChunk(chunk) records.addAll(parsed) offset += parsed.size // Останній чанк — флаг кінця буфера в заголовку } while (!SensorRecord.isLastChunk(chunk)) // Підтверджуємо синхронізацію — пристрій може очистити буфер writeControlPoint(AckSyncCommand(recordsReceived = records.size)) return records } 

MTU negotiation перед синхронізацією (requestMtu(512)) прискорює передачу: замість 20 байт per notification отримуємо до 509 байт. На iOS MTU 185 байт за замовчуванням, negotiate до 512 на Bluetooth 5.0+. У реальному проєкті для медичного патча з буфером у 10 000 записів ми скоротили час синхронізації з 8 хвилин до 45 секунд за рахунок збільшення MTU та оптимізації протоколу вичитки.

Чому на iOS важлива фонова робота BLE?

На iOS вся робота з BLE через CoreBluetooth. Фоновий режим вимагає background mode bluetooth-central в Info.plist. Без нього підписка на Notify обривається коли додаток йде у фон — дані з пристрою губляться.

class WearableManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate { private var centralManager: CBCentralManager! private var peripheral: CBPeripheral? override init() { super.init() // CBCentralManagerOptionRestoreIdentifierKey — відновлення після kill додатку centralManager = CBCentralManager(delegate: self, queue: DispatchQueue(label: "ble.queue"), options: [CBCentralManagerOptionRestoreIdentifierKey: "WearableSession"]) } func centralManager(_ central: CBCentralManager, willRestoreState dict: [String: Any]) { // Відновлюємо підключення після перезапуску додатку ОС if let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral], let p = peripherals.first { peripheral = p peripheral?.delegate = self } } } 

CBCentralManagerOptionRestoreIdentifierKey — без цього на iOS при перезапуску процесу губиться сесія BLE і пристрій доводиться перепідключати вручну.

Оновлення прошивки по повітрю (DFU)

Для Nordic nRF-чипів — бібліотека iOSDFULibrary (Swift) і Android-DFU-Library (Kotlin). Для STM32WB — ST BLE Mesh DFU. Показуємо прогрес з байтами та відсотками, блокуємо інші операції на час DFU, обробляємо переривання — пристрій повинен вміти відновити завантаження з місця переривання (DFU resume). Гарантуємо коректне відновлення з'єднання після оновлення.

Що входить в роботу?

  1. Аналіз GATT-специфікації пристрою та формування документації щодо взаємодії.
  2. Проектування архітектури мобільного додатку з урахуванням фонових завдань та енергоспоживання.
  3. Реалізація BLE-стека з чергою операцій та обробкою помилок.
  4. Інтеграція синхронізації буфера та DFU.
  5. Тестування на реальному пристрої (в тому числі з осцилографом для аналізу пакетів).
  6. Супровід протягом 3 місяців після релізу.

Приклад з практики: для одного з наших клієнтів — виробника медичних патчів — ми розробили додаток, який синхронізує дані з 32 пристроїв одночасно, що дозволило лікарям отримувати дані в реальному часі.

Зв'яжіться з нами — ми оцінимо ваш проєкт і запропонуємо оптимальне рішення. Отримайте консультацію щодо вашого пристрою: проаналізуємо GATT-специфікацію та визначимо терміни розробки.