Skip to content

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

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions