Skip to content

Inconsistent RFID Inventory Start/Stop Behavior with RFD4031 in React Native Integration #28

@ap-scatterlink

Description

@ap-scatterlink

We have integrated Zebra’s RFID3 SDK for Android into a React Native application using a custom native module (RFIDControllerModule.java). The goal is to allow inventory to start/stop via both:

The handheld trigger on the RFD4031 device

A “Start/Stop Scanning” button in the React Native UI

The problem is that inventory sessions do not consistently start or stop as expected:

Sometimes multiple inventory sessions appear to overlap, causing duplicate reads or rapid tag data events even after issuing a stop command.

Stop commands occasionally take several seconds to take effect.

When the physical trigger and the UI button are both used, the behavior becomes unpredictable (start/stop events race each other).

Steps to Reproduce:

Pair a Zebra RFD4031-G10B700-US via Bluetooth with an Android device.

Launch the provided React Native application (code attached below).

Press and hold the physical trigger to start scanning, then release it.

→ Expected: Inventory starts instantly and stops immediately when the trigger is released.

→ Actual: Sometimes stop is delayed or ignored, and tag reads continue.

Use the UI button to start/stop scanning in between trigger presses.

→ Observed: Inconsistent state — scanning may not start, or stopping takes multiple presses.

Repeat steps 3–4 a few times. The issue becomes more apparent with rapid presses or mixed trigger/UI usage.

@ReactMethod

public void startInventory(Promise promise) {

    inventoryPromise = promise;

    performInventory();

}

@ReactMethod

public void stopInventory(Promise promise) {

    stopInventoryInternal();

    promise.resolve("Inventory stopped");

}

private synchronized void performInventory() {

    try {

        reader.Actions.Inventory.perform();

    } catch (InvalidUsageException | OperationFailureException e) {

        e.printStackTrace();

        if (inventoryPromise != null) {

            inventoryPromise.reject("InventoryError", e.getMessage());

            inventoryPromise = null;

        }

    }

}

private synchronized void stopInventoryInternal() {

    try {

        reader.Actions.Inventory.stop();

    } catch (InvalidUsageException | OperationFailureException e) {

        e.printStackTrace();

    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions