All checks were successful
APK-BUILD/pipeline/head This commit looks good
The 7-tap top-left corner gesture passed every tap through to the page, triggering site UI underneath it. Remove it entirely and open the admin dialog (exit / toggle soft keyboard) by either: - holding Volume Up + Volume Down together for 5 seconds; volume keys are consumed so they never reach the page, or - scanning AppConfig.ADMIN_BARCODE in Intent output mode, which opens the dialog instead of being injected into the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
3.7 KiB
Markdown
86 lines
3.7 KiB
Markdown
# JoykooScanner — Android Barcode Scanner Kiosk App
|
|
|
|
## What This Is
|
|
|
|
Native Android app (Kotlin) that wraps `https://smart.joykoo.mx/` in a fullscreen WebView for dedicated Chinese industrial handheld barcode scanners. The scanner operates in HID/keyboard-wedge mode — it sends Android key events like a physical keyboard.
|
|
|
|
## Critical Design Decision
|
|
|
|
The Android soft keyboard must NEVER appear. Keyboard suppression uses multiple layers — do not remove any of them:
|
|
|
|
1. `NoSoftKeyboardWebView.onCheckIsTextEditor()` → `false`
|
|
2. `EditorInfo` flags `IME_FLAG_NO_EXTRACT_UI | IME_FLAG_NO_FULLSCREEN` in `onCreateInputConnection()`
|
|
3. `InputMethodManager.hideSoftInputFromWindow()` posted after each InputConnection request and on page load / window focus
|
|
4. JavaScript injection setting `inputmode="none"` on all `<input>`, `<textarea>`, and `contenteditable` elements via `MutationObserver`
|
|
5. Manifest `windowSoftInputMode="stateAlwaysHidden|adjustNothing"`
|
|
|
|
The real `InputConnection` from `super.onCreateInputConnection()` **must be returned** — returning `null` breaks hardware key input from the barcode scanner on devices like the Urovo CT58C.
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
app/src/main/java/mx/joykoo/scanner/
|
|
AppConfig.kt — URL, allowed hosts, admin triggers, scanner broadcasts (single config point)
|
|
MainActivity.kt — Fullscreen kiosk activity, WebView setup, navigation, lifecycle
|
|
NoSoftKeyboardWebView.kt — IME suppression via null InputConnection
|
|
ScannerIntegration.kt — Scanner lifecycle interface
|
|
BroadcastScannerIntegration.kt — Intent-output scans → JS injection (React-safe value setter)
|
|
```
|
|
|
|
## Build
|
|
|
|
- **Language**: Kotlin, targeting JVM 1.8 bytecode
|
|
- **SDK**: compileSdk 34, minSdk 24, targetSdk 34
|
|
- **Dependencies**: androidx core-ktx, appcompat, webkit, swiperefreshlayout
|
|
- **Gradle**: 8.7 with Kotlin DSL, AGP 8.5.2, Kotlin 1.9.24
|
|
- **Package**: `mx.joykoo.scanner`
|
|
|
|
### Build prerequisites (not yet installed on this server)
|
|
|
|
1. `sudo dnf install java-17-openjdk-devel` — only the JRE is installed, need javac
|
|
2. Android SDK cmdline-tools — download to `~/Android/Sdk/`, then install:
|
|
- `platform-tools`
|
|
- `platforms;android-34`
|
|
- `build-tools;34.0.0`
|
|
3. Set env vars:
|
|
```
|
|
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-17.0.20.1.1-1.2.el9.x86_64
|
|
ANDROID_HOME=~/Android/Sdk
|
|
```
|
|
4. `./gradlew assembleDebug`
|
|
|
|
### Server environment (RHEL 9.8)
|
|
|
|
- JRE 17 installed at `/usr/lib/jvm/java-17-openjdk-17.0.20.1.1-1.2.el9.x86_64`
|
|
- 323 GB free on /home, 5.5 GB free on /
|
|
- curl, wget, unzip, zip available
|
|
- No Android SDK present anywhere
|
|
|
|
## Configuration
|
|
|
|
All configurable values are in `AppConfig.kt`:
|
|
- `HOME_URL` — the webpage to load
|
|
- `ALLOWED_HOSTS` — domains that stay inside the WebView
|
|
- `BACK_PRESS_EXIT_COUNT` / `BACK_PRESS_WINDOW_MS` — back-button exit guard
|
|
- `ADMIN_VOLUME_HOLD_MS` — hold Volume Up + Volume Down this long to open the admin dialog
|
|
- `ADMIN_BARCODE` — scanning this value (Intent mode) opens the admin dialog
|
|
|
|
## Navigation Rules
|
|
|
|
- URLs on `joykoo.mx` or `smart.joykoo.mx` (and subdomains) load inside the WebView
|
|
- All other URLs are silently blocked
|
|
- Back button goes back in WebView history; 3 rapid presses exits when no history
|
|
- Admin dialog (exit / toggle soft keyboard): hold both volume keys 5 s, or scan `ADMIN_BARCODE`. Volume keys are consumed and never reach the page. No touch gestures — corner taps leaked through to site UI
|
|
|
|
## Security
|
|
|
|
- HTTPS only, no cleartext, no SSL error bypass
|
|
- No JavaScript interfaces exposed
|
|
- No file:// or content:// access
|
|
- Network security config enforces system trust anchors only
|
|
- Domain allowlist in WebViewClient
|
|
|
|
## UI Strings
|
|
|
|
Spanish (`es`) — this is for a Mexico-based company.
|