UHF long-range RFID scanner integration in mobile app

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
UHF long-range RFID scanner integration in mobile app
Medium
~5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Integrating UHF RFID Readers (Long-Range) into Mobile Applications

UHF RFID (860–960 MHz) — different world compared to HF NFC/MIFARE. Read distance 3–10 meters, mass reading hundreds of tags per second, passive tags costing $0.05–0.15 each. Zebra RFD40, Chainway R6, Bluebird EF500 — mobile UHF readers with BLE or USB connection. Integrating these devices into mobile apps has specifics: LLRP protocol, EPC C1G2 standard, antenna power management.

LLRP vs Proprietary SDK

LLRP (Low Level Reader Protocol, ISO 15961) — standard protocol for managing UHF readers. Supported by Impinj, Zebra, Alien. Allows using one code for different readers. For mobile app via Wi-Fi connection to reader.

Proprietary SDK — Zebra RFID SDK, Chainway SDK. Easier to use, locked to specific manufacturer, works via BLE or USB.

For most mobile readers with BLE — proprietary SDK. LLRP — for stationary readers on network.

Zebra RFID SDK: Practice

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

class UhfReaderManager(private val context: Context) : RfidEventsListener {
    private var reader: RFIDReader? = null
    private val readers = Readers(context, ENUM_TRANSPORT.BLUETOOTH)

    fun connect(deviceName: String) {
        val readerDevices = readers.GetAvailableRFIDReaderList()
        val targetDevice = readerDevices?.find { it.name == deviceName } ?: return
        reader = targetDevice.RFIDReader
        reader?.connect()

        // Configure read parameters
        val params = reader?.Config?.antennaConfigurations?.get(0)
        params?.transmitPowerIndex = 270  // ~30 dBm, maximum power
        params?.receiveFrequency = 55     // optimal for most regions

        reader?.Config?.setAntennaConfiguration(params)

        // Events
        reader?.Events?.apply {
            addEventsListener(this@UhfReaderManager)
            setHandheldEvent(true)    // reader trigger button
            setTagReadEvent(true)
            setInventoryStartEvent(true)
            setInventoryStopEvent(true)
        }
    }

    // Start inventory with EPC mask filtering
    fun startInventoryWithFilter(epcMask: String?) {
        val startTrigger = TriggerInfo().apply {
            startTrigger.triggerType = START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE
        }
        val stopTrigger = TriggerInfo().apply {
            stopTrigger.triggerType = STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_DURATION
            stopTrigger.stopTriggerByDuration.duration = 5000  // 5 seconds
        }

        val tagFilter = if (epcMask != null) {
            TagFilter().apply {
                tagPattern = epcMask
                tagPatternBitCount = epcMask.length * 4
                filterAction = FILTER_ACTION.FILTER_ACTION_STATE_AWARE_FILTERING_ACTION_UNSPECIFIED
            }
        } else null

        reader?.Actions?.Inventory?.perform(startTrigger, stopTrigger, tagFilter)
    }

    override fun eventReadNotify(e: RfidReadEvents) {
        e.ReadEventData.TagData.forEach { tag ->
            onTagRead(
                epc = tag.TagID,
                rssi = tag.PeakRSSI.toInt(),
                antennaId = tag.AntennaID.toInt(),
                readCount = tag.ReadCount
            )
        }
    }

    override fun eventStatusNotify(rfidStatusEvents: RfidStatusEvents) {
        when (rfidStatusEvents.StatusEventData.statusEventType) {
            STATUS_EVENT_TYPE.INVENTORY_START_EVENT -> onInventoryStarted()
            STATUS_EVENT_TYPE.INVENTORY_STOP_EVENT -> onInventoryCompleted()
            STATUS_EVENT_TYPE.HANDHELD_TRIGGER_EVENT -> {
                val triggerType = rfidStatusEvents.StatusEventData.HandheldTriggerEventData.handheldEvent
                if (triggerType == HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED) {
                    startInventoryWithFilter(null)
                }
            }
        }
    }
}

transmitPowerIndex = 270 — power in reader units. Each manufacturer has its own scale. Zebra RFD40: 0–270 = 0–30 dBm. Excessive power in closed warehouse → reflections → false reads from adjacent zones.

Regulatory Frequency Limitations

UHF RFID operates in different bands:

  • USA/Canada (FCC): 902–928 MHz
  • Europe/Russia (ETSI): 865–868 MHz
  • China: 920–925 MHz

Mobile app should configure regional reader band:

reader?.Config?.setRegulatoryConfig(
    RegulatoryConfig().apply {
        region = REGULATORY_REGION.REGULATORY_REGION_ETSI // or FCC, China
        enableHoppingChannels = true
    }
)

Using FCC band in Russia — regulatory violation. Readers with regional firmware locks won't allow wrong region, but worth checking.

Performance: 500 Tags Per Second

UHF reader can read hundreds of tags per second. Tag stream cannot be processed on main thread — UI freeze:

private val tagChannel = Channel<TagReadData>(capacity = Channel.UNLIMITED)

// In BroadcastReceiver/reader callback — just put in channel
override fun eventReadNotify(e: RfidReadEvents) {
    e.ReadEventData.TagData.forEach { tag ->
        tagChannel.trySend(tag) // non-blocking, no exception
    }
}

// Process in background coroutine
fun processTagsInBackground() {
    scope.launch(Dispatchers.Default) {
        for (tag in tagChannel) {
            val epc = tag.TagID
            inventoryRepository.recordRead(epc, tag.PeakRSSI.toInt())
        }
    }
}

Timeline

Zebra/Chainway UHF BLE reader integration with basic inventory and tag display: 5 days. Extended solution with regional settings, filtering, EPC decoding, and WMS sync: 1–2 weeks.