package com.rfidsoftwares.demo.chainway import android.os.Bundle import android.os.Handler import android.os.Looper import android.util.Log import android.view.KeyEvent import androidx.appcompat.app.AppCompatActivity import com.rscja.deviceapi.RFIDWithUHFUART import com.rscja.deviceapi.entity.UHFTAGInfo /** * Minimal Standalone Chainway C72 / C66 UHF RFID Scanner Demo * * Demonstrates: * 1. Initializing UART serial hardware bus (/dev/ttyMT2 or /dev/ttyHSL1) * 2. Setting transmission RF power (5 - 30 dBm) * 3. Continuous tag inventory polling via high-speed hardware buffer * 4. Intercepting physical trigger key events (KEYCODE_F4 / Barcode Pistol Grip) * 5. Clean teardown and power cutoff */ class ChainwayInventoryActivity : AppCompatActivity() { private var mReader: RFIDWithUHFUART? = null private var isInventoryRunning = false private val mainHandler = Handler(Looper.getMainLooper()) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) initHardwareReader() } private fun initHardwareReader() { Thread { try { mReader = RFIDWithUHFUART.getInstance() val success = mReader?.init() ?: false if (success) { Log.i(TAG, "Chainway UHF Reader initialized successfully.") // Set RF output power to 30 dBm (Maximum distance ~6-8 meters) mReader?.setPower(30) } else { Log.e(TAG, "Failed to power on Chainway UHF module.") } } catch (e: Exception) { Log.e(TAG, "Hardware exception during reader initialization", e) } }.start() } /** * Start continuous tag inventory sweep */ fun startInventory() { if (isInventoryRunning || mReader == null) return val started = mReader?.startInventoryTag() ?: false if (started) { isInventoryRunning = true Log.i(TAG, "Tag inventory started.") startReadThread() } } /** * Stop continuous inventory sweep */ fun stopInventory() { if (!isInventoryRunning) return mReader?.stopInventory() isInventoryRunning = false Log.i(TAG, "Tag inventory stopped.") } private fun startReadThread() { Thread { while (isInventoryRunning && mReader != null) { val tagInfo: UHFTAGInfo? = mReader?.readTagFromBuffer() if (tagInfo != null) { val epc = tagInfo.epc val rssi = tagInfo.rssi mainHandler.post { onTagScanned(epc, rssi) } } else { Thread.sleep(10) // Yield CPU to avoid thread thrashing } } }.start() } private fun onTagScanned(epc: String, rssi: String?) { Log.d(TAG, "Tag Detected: EPC=$epc | RSSI=$rssi dBm") // TODO: Reconcile with local SQLite cache or ERP gateway } /** * Listen for physical pistol grip trigger squeeze */ override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // Chainway C72 pistol grip triggers standard KEYCODE_F4 (134) or KEYCODE_139 if (keyCode == KeyEvent.KEYCODE_F4 || keyCode == 139) { if (event?.repeatCount == 0 && !isInventoryRunning) { startInventory() return true } } return super.onKeyDown(keyCode, event) } override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_F4 || keyCode == 139) { stopInventory() return true } return super.onKeyUp(keyCode, event) } override fun onDestroy() { super.onDestroy() stopInventory() // Crucial: Free hardware module to release UART port and conserve battery mReader?.free() mReader = null Log.i(TAG, "Chainway UHF Reader freed.") } companion object { private const val TAG = "ChainwayDemo" } }