Skip to content

Hardware and Local Testing

Countertop Supermarket Lane

This should be the primary reference setup for supermarkets.

  • touch POS terminal or all-in-one countertop PC
  • fixed barcode scanner
  • 80mm receipt printer
  • printer-driven cash drawer
  • browser kiosk running POS Cashier Web

Mobile / Secondary Kit

Use this for supervisors, queue-busting, and smaller merchants.

  • Android phone
  • optional Bluetooth scanner
  • optional Bluetooth, USB-host/OTG or private-LAN ESC/POS printer
  • POS Android app

The Android app now includes a transport router plus generic Bluetooth Classic SPP, USB-host printer-class bulk OUT and private-LAN raw-TCP ESC/POS adapters. It offers 32-character/58 mm and 48-character/80 mm profiles, stores both the selected device and its transport locally, marks every reprint, and retains failed jobs in a Room-backed queue for operator retry. Checkout and the spool depend only on the country- and vendor-neutral printer contract. An integrated handheld printer can therefore be added as a small status-aware vendor adapter without adding Ciontek, Sunmi, Kenya or another market concept to sale code. Discovery isolates adapter failures, so missing Bluetooth permission cannot hide a connected USB, configured network or installed built-in printer adapter.

The generic built-in-printer boundary is now implemented. It advertises no device when a build has no licensed bridge, maps ready/busy/paper-out/cover-open/ offline states into the common contract, sanitizes private SDK failures and distinguishes exact-job completion from accepted-but-unconfirmed submission. Eight focused tests cover those guarantees. The exact Ciontek, SUNMI or other vendor AAR bridge is still conditional on the purchased model, firmware and SDK.

The app accepts rapid keyboard-wedge barcode input from a real external HID device. A second adapter accepts a configurable foreground Android broadcast from a managed scanner service. A third, hardware-independent fallback uses the camera and a bundled on-device decoder. It deliberately does not advertise a camera or a merely configured broadcast as a working scanner: each software adapter becomes ready only after its permission/configuration requirements and a valid test scan. Terminal activation and the periodic sync worker publish country-neutral battery, network, printer and scanner readiness to the POS service. A configured printer is only reported ready after its selected adapter passes a real check: bonded-device visibility, enabled Bluetooth and permission for SPP; temporary Android device permission and a successful interface claim for USB; or a bounded TCP connection to a private resolved address for a network printer.

USB-host ESC/POS printer

Use an Android terminal that advertises USB host/OTG support. Connect only a printer whose USB descriptor exposes printer class 7 at the device or interface level and a bulk OUT endpoint. Open Settings → Receipt printer, select Find Bluetooth and USB printers, choose the device, and approve the Android access dialog. Permission is temporary and ends when the printer is disconnected. The app stores only an opaque local identity derived from the vendor/product pair and Android device path; it does not persist a serial number. If exactly one same-model printer reconnects under a new path, it is resolved safely. Multiple indistinguishable same-model devices require the operator to select the intended printer again.

The adapter claims only the qualified printer interface, writes bounded 16 KiB chunks to its bulk OUT endpoint, and then releases and closes the connection. It never inspects mass-storage, HID, card-reader or vendor-class devices. USB bulk output cannot portably confirm paper completion, so a full write remains SUBMITTED_UNCONFIRMED. Any timeout or partial write requires paper inspection and is not automatically retried. Test the exact OTG cable, powered hub, charger path and full-shift power behavior; many phones cannot charge while acting as the USB host. This follows the official Android USB host contract and UsbManager permission lifecycle.

Local-network ESC/POS printer

Use a DHCP reservation or static private address for the printer. In Settings → Receipt printer, enter the hostname or IPv4 address and the device's raw ESC/POS TCP port, commonly 9100; do not enter an HTTP administration URL or IPP port. Save it, choose the correct paper width and print a test receipt.

The adapter resolves the hostname and refuses any result that is not loopback, link-local, private/site-local, or IPv6 ULA. It uses a 3-second connect bound and a 12-second whole-print bound. A successful socket write is one-way transport acceptance, not proof of paper output. If a failure occurs after writing starts, the app does not try another address or mark the job retryable because the printer may already hold a partial or complete receipt. Place printers on a dedicated merchant LAN/VLAN; raw port 9100 is normally unencrypted and must not be exposed to the public internet.

Camera barcode fallback

Open Checkout → Scan with camera on an authenticated POS terminal. Android requests CAMERA permission only when this action is selected. CameraX binds the rear camera to the foreground checkout lifecycle with keep-only-latest analysis, and the bundled ML Kit model supports Code 128/39/93, Codabar, EAN-13/8, ITF, UPC-A/E, QR, PDF417, Aztec and Data Matrix without downloading a model. The analyzer closes every frame, returns only a bounded validated value to the existing catalog lookup path, and stores or uploads no image.

Readiness has three independent gates: camera present, permission granted and a successful valid decode in the current app process. This makes a phone or tablet useful for the low-cost pilot without claiming the camera is equivalent to a high-throughput scan engine. Physical lane testing must still qualify focus speed, low light, damaged labels and repeated scans. See CameraX image analysis and ML Kit barcode scanning.

Integrated scanner intent contract

Open Settings → Integrated scanner broadcast and configure the contract provided by the handheld vendor. The included DataWedge-compatible starting profile is:

Setting Value
Delivery Broadcast intent
Action com.emali2.pos.SCAN
Category android.intent.category.DEFAULT
Barcode data extra com.symbol.datawedge.data_string
Symbology extra com.symbol.datawedge.label_type
Target package com.emali2.pos

The action, category and both extra keys are runtime configuration, not POS domain constants. A Ciontek, Sunmi, Zebra or other managed device can therefore use its documented names without adding a country-specific checkout path. The receiver exists only while an authenticated POS activity is in the foreground, accepts the exact configured action/category, rejects unsafe or oversized values, permits the GS1 group separator, and suppresses repeated delivery of the same scan within 750 milliseconds. It does not persist barcode values in Settings. The pure processor suite and a package-targeted Android 14 instrumentation test cover this contract; the selected handheld's real scanner service remains the physical acceptance gate.

For Zebra DataWedge, configure Component Information for package com.emali2.pos and enable its app-signature check when the device supports it. Android warns that exported context receivers can otherwise receive broadcasts from other installed applications, so enable this bridge only on a managed or dedicated POS device with an approved scanner service. An incoming scan can only initiate catalog lookup/basket entry; it cannot authorize payment, refund, supervisor override or drawer operation. See Zebra Intent Output and Android broadcast security guidance.

Kenya pilot procurement (country-neutral product)

Recommended local-first setup:

  • existing Samsung NFC phone
  • second low-cost Android phone
  • wireless or Bluetooth 2D barcode scanner
  • Bluetooth receipt printer
  • laptop for POS Backoffice and POS Cashier Web

For supermarkets specifically:

  • favor countertop hardware over handheld SmartPOS
  • keep handheld SmartPOS for mobile use cases, not the main checkout lane

Handheld with built-in printer: current Kenya cost

Prices and stock were rechecked on 24 July 2026. These are Kenya pilot procurement observations only: neither the Android hardware contract nor the Emali2 POS application requires KRA, eTIMS, M-PESA or any other country-specific service. The recommended first integrated-printer evaluation unit is the Ciontek CS30 at KSh 23,000, but only after an in-person acceptance demo. The local listing identifies an Android 14/11 unit; Ciontek's OEM specification lists Android 14, 2 GB RAM, 16 GB storage, a 58 mm printer at 70 mm/s, and an optional Zebra/Symbol 4710 2D scanner. More importantly for the current Emali2 build, Ciontek documents a Bluetooth printer mode that accepts ESC/P commands. That makes the CS30 the best candidate for using the existing generic printer bridge before building a vendor AAR integration. Ciontek says its SDK and technical support are available after a sample order, while a publicly available CS30Pro integration guide describes an older Android 10-era PosApiHelper/AIDL contract. That older guide is useful only for evaluating the shape of a future adapter; it is not acceptance evidence for the current Android 14 CS30 firmware. Obtain the exact sample's matching SDK, license terms, demo and status-code contract before compiling vendor binaries into Emali2.

The refreshed seller pages put mainstream integrated-printer handhelds at about KSh 23,000–33,000. They list the CS30 in stock at KSh 23,000; an H10S with Android 13, 2 GB/16 GB, a built-in 58 mm printer and a stated free SDK at KSh 25,000 excluding VAT; an Android 12 NB55 with 3 GB/16 GB, NFC, a stated 1D/2D scan engine and 58 mm printer at KSh 28,000; generic marketplace units at KSh 23,990–32,999; the YCP-58 at KSh 5,000; and the Deli E14952 at KSh 8,500. The H10S and NB55 are the more current-OS comparisons, but a listing or “free SDK” claim is not enough: obtain the actual AAR/API, license and a paper-out/status demonstration before purchase. These are web offers, not quotations; confirm VAT, delivery, warranty and the exact SKU in writing before payment.

Pilot option Listed price Qualification decision
Ciontek SmartPOS CS30 KSh 23,000 First integrated evaluation choice. Require Android 11 or newer, signed-APK installation and a successful ESC/P or supplied-SDK print demo
H10S Android 13, 2 GB/16 GB, 58 mm printer KSh 25,000 ex VAT Modern-OS comparison choice. Require delivery of the advertised SDK, third-party APK installation, exact printer status behavior and scanner-option confirmation
NB55 Android 12, 3 GB/16 GB, NFC, stated 1D/2D scanner and 58 mm printer KSh 28,000 Scanner-equipped comparison choice. Require the exact scan engine, broadcast/SDK contract, printer status API and signed-APK installation to be demonstrated
Generic marketplace Android terminal with 58 mm printer KSh 23,990–32,999 Marketplace comparison only; no dependable OEM, SDK or firmware assurance in the listings
Comstore 4 GB/32 GB, 58 mm printer KSh 25,000 Reject as the primary new pilot unit: the current listing identifies Android 10, below the Android 11 floor; its 5 MP camera is not a qualified scan engine
Ciontek CS50 or 3 GB CS30G KSh 26,000 Alternative after the exact SKU, Android build and hardware SDK are confirmed
SUNMI V2s KSh 35,800–38,000 locally Better-documented 58 mm/80 mm/s OEM platform, but the local listings conflict: one says Android 11 with 2 GB/16 GB and another says Android 7.1, while SUNMI's current T5940 standard specification is Android 12 Go with 1 GB/8 GB. Buy only the exact demonstrated SKU
SUNMI V2 Pro KSh 43,000 ex VAT Do not select for a new pilot: the current local listing is in stock with a built-in 58 mm printer but identifies Android 7/7.1
SmartPOS H5, Android 8.1, 1 GB/8 GB KSh 19,999 Compatibility testing only; technically above API 26 but too old and constrained for a new production pilot
Fingerprint CS30G/CS50 variants KSh 28,000–30,000 Do not pay the premium until fingerprint is a confirmed Emali2 workflow

Sources: AndroidPOSKenya CS30 listing, Ciontek CS30 OEM specification, Ciontek SDK/support FAQ, Viva CS30 SDK integration page, public CS30Pro SDK guide (older Android 10 reference only), Jumia CS30 listing and Android POS comparisons, TDK H10S listing, Carl & Kyle NB55 listing, Jumia Android POS price comparison, Nebula Comstore listing, SUNMI V2s OEM specification, and Kenya SUNMI V2s listings from TechHub and Sawa Gadgets, plus Fgee's SUNMI V2 Pro listing.

The V2s model name alone is therefore not an acceptance criterion. Record the model/variant identifier, OS build, RAM/storage, GMS state, scan-engine option and printer API observed on the actual unit in the purchase acceptance report.

Printer delivery confidence

The Android print queue now distinguishes device confirmed from transport accepted, unconfirmed. A generic Bluetooth SPP, USB bulk OUT or raw-TCP socket can prove that Android flushed the ESC/POS bytes, but it normally cannot prove that the printer had paper or completed the receipt. Such a job is stored as SUBMITTED_UNCONFIRMED, receives no printedAt value and is never silently auto-retried. The operator must inspect the paper output; any new attempt is an explicit marked reprint. Only a qualified bidirectional vendor SDK or another status-capable transport may return device-confirmed completion.

The app-side BuiltInPrinterBridge now enforces this boundary without carrying any brand or country rule in checkout. A bridge is not included in the generic APK: it must be compiled only for the exact accepted device SDK and must map all private status/error values to the closed, sanitized POS model.

This is a selection advantage for a vendor SDK that exposes truthful paper, cover and completion status, but it does not block the KSh 23,000 CS30 evaluation: its documented Bluetooth ESC/P mode can exercise the current country-neutral bridge with the safer unconfirmed outcome.

The app now persists BLUETOOTH_SPP, USB, NETWORK or VENDOR_SDK with the selected printer and routes every print, readiness check and guarded drawer request to that exact adapter. A later CS30 adapter must translate exact-firmware initialization, print-start, paper-out, cover, temperature/voltage and completion statuses into the shared failure and delivery-confidence model. It may return DEVICE_CONFIRMED only after the exact device reports successful completion; submitting a command to an SDK is not sufficient.

Do not order two integrated terminals yet. Ask AndroidPOSKenya to reserve one CS30 and perform the following acceptance demo before payment:

  1. Show the Android version, RAM/storage, model number and Google Play/GMS state.
  2. Install the signed Emali2 debug/UAT APK without seller-controlled kiosk or application allow-list restrictions.
  3. Pair or expose the built-in printer in ESC/P Bluetooth mode and print the Emali2 test receipt. If that mode is unavailable, supply the matching AAR, API documentation and sample application before purchase.
  4. Print at least 25 receipts, exercise paper-out, reboot, sleep/wake and reconnect, and show that a failed job can be retried as a marked reprint.
  5. Identify whether the unit includes the optional professional 2D engine. A camera alone is not scanner qualification. If the engine is present, supply its Android intent or SDK contract, configure the action/category/extra keys in Emali2, and scan EAN-13, Code 128 and an on-screen QR code into the app.
  6. Confirm warranty length, return terms, replacement printer heads, battery, charger and 58 × 40 mm paper availability on the invoice.

Capture the exact evidence and purchase decision in the POS Hardware Acceptance Report. Do not accept a family name, another app's print demo or a marketing compliance badge in place of the checks in that report.

The lowest-risk lab bundle is therefore:

Item Budget
One conditional Ciontek CS30 KSh 23,000
YCP-58 Bluetooth/USB fallback printer KSh 5,000
Deli E14952 wired 1D/2D scanner KSh 8,500
Five 57 × 35 mm thermal rolls about KSh 500
Hardware subtotal about KSh 37,000

Delivery, USB-C OTG adapter, SIM/data and a spare charger are extra. The fallback printer and scanner keep physical UAT moving if the integrated printer or optional scan engine needs a vendor adapter. For the absolute cheapest peripheral-only proof with an existing Android phone, use the YCP-58 and a KSh 4,000 wired 1D HID scanner: approximately KSh 9,000, plus paper and an OTG adapter. Current peripheral sources: YCP-58 and Nebula scanner/printer catalogue.

Fixed-lane peripheral cost in Kenya

These prices exclude the PC, touch display or tablet that runs Cashier Web. Listings do not always use the same VAT or delivery treatment, so compare final written quotations rather than adding unlike prices.

Peripheral Current listed price Pilot use
YCP-58 Bluetooth/USB 58 mm printer KSh 5,000 Mobile receipt proof, not the preferred busy-lane printer
RD-P58E Bluetooth 58 mm printer KSh 5,500 Second portable-printer comparison model
CK710 80 mm USB/Ethernet printer KSh 9,500 (out of stock) Price comparison only; do not include it in the current purchase order
E-POS ECO250 USB/serial/Ethernet printer KSh 14,500 Better-connected fixed-lane candidate; verify cutter and drawer port
Wired USB HID 1D scanner KSh 4,000 Cheapest physical EAN/Code 128 proof
Deli E14952 wired 1D/2D scanner KSh 8,500 Recommended low-cost QR and product-barcode proof; confirm Android HID behavior in the seller demo
Honeywell omni-directional 1D/2D USB kit KSh 15,339.84 Better-supported fixed-lane comparison
RJ11 cash drawer KSh 6,500 locally Connect through a compatible receipt printer, not directly to Android

A currently buyable low-cost fixed-lane peripheral kit is approximately KSh 29,500: the ECO250, Deli 1D/2D scanner and KSh 6,500 drawer. The same printer with the Honeywell scanner and drawer is approximately KSh 36,340, excluding the cashier computer/touch display, tax treatment, delivery and consumables. Prices come from the Nebula POS catalogue, its ECO250 listing, CK710 stock listing, and AndroidPOSKenya catalogue; obtain a written final quotation because web prices and stock can change.

Kenya is only the first procurement and certification reference. Hardware, tender and fiscal adapters remain selected through the store operating profile; the POS domain does not call a tax authority or mobile-money brand directly.

Cash Drawer

Cash drawers are recommended for real cash lanes, but not required for early software development.

Best approach:

  • use a printer-driven RJ11 or RJ12 drawer
  • trigger drawer open from the receipt printer
  • only open on:
  • cash sale
  • cash refund
  • supervisor-approved no-sale

Local Testing Matrix

POS Cashier Web

  • keyboard wedge barcode input
  • product lookup and basket creation
  • mixed tender capture
  • receipt print popup
  • session recovery by terminal

POS Android

  • rapid external HID keyboard-wedge scan; slow ordinary typing must not be mistaken for a barcode
  • revoke camera permission, select Scan with camera, grant it at runtime, scan a valid Code 128/EAN/QR label and confirm exactly one catalog lookup/basket addition
  • verify Settings changes from permission/validation pending to camera scanner Ready, then restart the process and confirm a fresh validation is required
  • configure the handheld's explicit target package, scan action, category and decoded-data extra under Integrated scanner broadcast
  • confirm the intent bridge says Listening; test required until a real scan is received, then changes to Validated without showing or storing the scan value in Settings
  • send the same broadcast twice inside 750 milliseconds and confirm only one catalog lookup/basket addition occurs
  • background or sign out of the POS app and confirm scanner broadcasts no longer reach checkout
  • local image rendering
  • offline-first session and receipt behavior
  • handheld checkout UX
  • pair the printer in Android system settings
  • grant BLUETOOTH_CONNECT and BLUETOOTH_SCAN on Android 12+
  • select the device under Settings → Receipt printer
  • select the 58 mm/32-column or 80 mm/48-column profile and print a test before using sale receipts
  • print a test receipt, then a marked reprint from Receipts & Refunds
  • power the printer off, confirm the job remains visible, power it on, and use Retry print queue
  • after a successful Bluetooth send, confirm the app says output is unconfirmed and does not fabricate a printer-completed timestamp
  • verify paper width, accented customer names, QR/barcode support, cut behavior, paper-out handling, and reconnect on the actual model
  • enroll the terminal and verify its first heartbeat reports the real network, battery, printer transport and scanner readiness
  • leave periodic sync enabled and verify terminal health refreshes approximately every 15 minutes
  • confirm a camera-only device without permission/validation and an unvalidated broadcast profile are not marked scanner-ready
  • with the drawer empty and closed, connect it through the printer, explicitly enable drawer testing, and send one test pulse
  • confirm drawer testing starts disabled after selecting a different printer and that drawer pulses never enter Retry print queue

The generic adapter has an unknowable physical-delivery boundary: a Bluetooth disconnect after the printer accepts bytes can leave paper output uncertain. Android therefore records transport acceptance as unconfirmed and does not auto-retry it. Operator retries are always labelled REPRINT COPY. Do not auto-retry an unmarked fiscal original through this bridge.

POS Backoffice

  • inventory onboarding
  • item images
  • loyalty and engagement configuration
  • branch operations and reporting

Pre-Pilot Additions

  • countertop printer and cash drawer
  • customer-facing display if needed
  • dedicated lane touch terminal
  • bank-approved PDQ only when card-present integration starts