Jewelsoft RFID Handheld
An Android app for UHF RFID handhelds that turns a jewellery stock-take into a walk past the shelves. Licensed per device against its own key server, and built to keep counting when the shop's Wi-Fi does not reach.
Jewelsoft RFID Handheld
Counting a jewellery inventory by hand is slow and error-prone. With a UHF RFID reader it becomes a sweep: the operator imports the stock list, walks the shelves, and exports a report of what was found and what was not.
Meeting the hardware where it is
The reader is driven over a serial port through the vendor's SDK. Handhelds differ in how the RF module is powered on and which key the trigger maps to, so the device is identified at runtime and the right sequence is used — an unrecognised model still runs, it just never powers the radio.
The count itself
Stock lists arrive as whatever the shop already has: .xlsx, .xls or .csv, with delimiters detected rather than configured, columns read positionally, and tags normalised to uppercase on import so they match the EPCs the reader returns. Matched items turn green and the running weight updates live. Scan state is persisted in Room, so closing the app halfway through a count is safe.
Two ways to work
The handheld can hold the list itself, or a desktop companion can hold it — matching every tag the handheld reads and pushing the running total, the item just found and its picture back to the scan screen. In that mode the handheld needs no import and no export at all. It advertises itself over mDNS from the moment the app opens and serves its export folder over HTTP, so the two find each other without anyone configuring anything.
Licensing that survives the shop floor
Each handheld activates against a licence server and claims a seat; a copy installed on a second device computes a different device id and has to claim its own. Every later launch re-checks, and a revoked or expired licence is dropped on the spot with a reason rather than a blank form.
The interesting constraint is that stock-takes happen where the Wi-Fi does not reach. So the re-check waits four seconds — long enough for a revocation to bite on the next launch rather than the one after it — and past that the app carries on for a fortnight of offline grace from its last successful check, warning the operator once that window is nearly out. The check still completes in the background and persists its answer.
The activation record lives in its own encrypted store, keyed to both the device and the APK's signing certificate and carrying an HMAC over the same key: copying it to another handheld, or opening it from a repackaged build, produces a record that fails verification and is discarded. Winding the clock back to sit in the grace window forever trips a high-water-mark check that demands a fresh online verification. The licence gate is the only launcher entry point, and every activity re-checks on start, so there is no way around it.
Small details matter here too: keys are issued as lowercase hex and matched case-sensitively, so the activation field never auto-capitalises and what the operator types is normalised before it is sent — spacing, dashes and case all reach the server as the same key.
