Интеграция RFID-считывателя через Bluetooth в мобильное приложение

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Интеграция RFID-считывателя через Bluetooth в мобильное приложение
Средний
~5 дней
Часто задаваемые вопросы

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

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Интеграция RFID-считывателя через Bluetooth в мобильное приложение

RFID-считыватели с BLE-интерфейсом — это отдельный класс устройств: Zebra RFD40/RFD90, Chainway R6, TSL 1128. Они соединяются с телефоном по BLE SPP-профилю (Serial Port Profile) или кастомному GATT-сервису и стримят считанные EPC/UID-теги. Интеграция проще чем кажется, если понимать протокол конкретного ридера.

BLE SPP vs GATT

Большинство Bluetooth RFID-ридеров работают через два режима:

BLE SPP (Serial Port Profile over BLE) — эмулируют последовательный порт. Данные идут в потоке через кастомные GATT-характеристики с UUID производителя. Nordic UART Service (NUS) — самый распространённый: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E.

Стандартный GATT — некоторые ридеры реализуют проприетарный GATT-сервис с отдельными характеристиками для команд и ответов.

Для Zebra RFD40 — Nordic UART Service:

val NORDIC_UART_SERVICE = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
val NORDIC_UART_RX = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E") // write
val NORDIC_UART_TX = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E") // notify

fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
    val service = gatt.getService(NORDIC_UART_SERVICE) ?: return

    // Подписка на TX (получение данных от ридера)
    val txChar = service.getCharacteristic(NORDIC_UART_TX)
    gatt.setCharacteristicNotification(txChar, true)
    val descriptor = txChar.getDescriptor(CCCD_UUID)
    descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
    gatt.writeDescriptor(descriptor)
}

fun sendCommand(command: ByteArray) {
    val rxChar = bluetoothGatt?.getService(NORDIC_UART_SERVICE)
        ?.getCharacteristic(NORDIC_UART_RX) ?: return

    // Если команда > MTU-3 байт, нужна фрагментация
    if (command.size > negotiatedMtu - 3) {
        sendFragmented(command)
    } else {
        rxChar.value = command
        bluetoothGatt?.writeCharacteristic(rxChar)
    }
}

Парсинг RFID-ответов

Протокол зависит от ридера. Zebra RFD40 возвращает ASCII-строки в формате EPC: <hex>\r\n. TSL 1128 использует бинарный пакет с заголовком и CRC. Пример для ASCII-протокола:

private val dataBuffer = StringBuilder()

fun onCharacteristicChanged(value: ByteArray) {
    dataBuffer.append(String(value, Charsets.UTF_8))

    // Данные приходят фрагментами — ждём полную строку
    while (dataBuffer.contains('\n')) {
        val lineEnd = dataBuffer.indexOf('\n')
        val line = dataBuffer.substring(0, lineEnd).trim()
        dataBuffer.delete(0, lineEnd + 1)

        if (line.startsWith("EPC:")) {
            val epc = line.removePrefix("EPC:").trim()
            onTagRead(epc)
        }
    }
}

Критично: BLE пакеты могут приходить разделёнными — одна строка в нескольких onCharacteristicChanged уведомлениях. Всегда буферизировать до разделителя (обычно \r\n).

Zebra SDK как альтернатива

Для Zebra-устройств (RFD40, RFD90, RFD8500) — официальный EMDK for Android или Zebra RFID SDK:

implementation("com.zebra.rfid.api3:rfid-api3:2.0.2.109")

val readers = Readers(context, ENUM_TRANSPORT.BLUETOOTH)
readers.GetAvailableRFIDReaderList()?.forEach { readerDevice ->
    val reader = readerDevice.RFIDReader
    reader.connect()
    reader.Events.addEventsListener(rfidEventsListener)
    reader.Events.setHandheldEvent(true)
    reader.Events.setTagReadEvent(true)
    reader.Actions.Inventory.perform() // начать непрерывное сканирование
}

private val rfidEventsListener = object : RfidEventsListener {
    override fun eventReadNotify(e: RfidReadEvents) {
        e.ReadEventData.TagData.forEach { tag ->
            Log.d("RFID", "EPC: ${tag.TagID}, RSSI: ${tag.PeakRSSI}")
        }
    }

    override fun eventStatusNotify(rfidStatusEvents: RfidStatusEvents) {
        // STATUS_EVENT_BATTERY_LOW и другие статусы
    }
}

RSSI из Zebra SDK даёт приблизительную дистанцию до тега — полезно для приоритизации при одновременном считывании нескольких тегов в поле.

Сроки

Интеграция по Nordic UART Service или аналогичному кастомному GATT с парсингом ASCII-протокола: 5 дней. Интеграция через Zebra/Chainway SDK с расширенными функциями (inventory, RSSI, write to tag): 1–2 недели.