{"id":"d52318f9-4884-468f-9581-b86c442e0f73","entityType":"agent","slug":"clawhub-openlittlebear-appium-android-adb","name":"Appium Android Adb","canonicalUrl":"https://www.xpersona.co/agent/clawhub-openlittlebear-appium-android-adb","canonicalPath":"/agent/clawhub-openlittlebear-appium-android-adb","generatedAt":"2026-10-11T03:54:56.316Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":null},"description":"Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A... Skill: Appium Android Adb Owner: openlittlebear Summary: Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A... Tags: android:1.0.0, appium:1.0.0, automation:1.0.0, latest:1.3.4, webview:1.0.0 Version history: v1.3.4 | 2026-08-30T08:56:32.847Z | user Review fixes: screenshots auto-purged after 1h, typed/pasted te","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s176q9th3gerh5cagvwz73f4r187fgya:appium-android-adb","sourceUrl":"https://clawhub.ai/openlittlebear/appium-android-adb","homepage":"https://clawhub.ai/openlittlebear/skills/appium-android-adb","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/openlittlebear/appium-android-adb","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/openlittlebear/skills/appium-android-adb","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":null},"stars":null,"forks":null,"downloads":1214,"packageName":null,"latestVersion":"1.3.4","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:51:04.757Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T00:51:04.816Z","lastCrawledAt":"2026-10-11T00:51:04.757Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T00:51:04.757Z","lastVerifiedAt":null,"highlights":[{"version":"1.3.4","createdAt":"2026-08-30T08:56:32.847Z","changelog":"Review fixes: screenshots auto-purged after 1h, typed/pasted text never echoed, one-shot mode stops the Appium server it started (no services left running).","fileCount":6,"zipByteSize":20464},{"version":"1.3.3","createdAt":"2026-08-30T08:47:02.244Z","changelog":"Daemon now opt-in: one-shot commands use short-lived sessions (no persistent bridge by default). Screenshots moved to private IPC dir. Fixes platform review verdict (persistent device-control bridge, /tmp screenshot paths).","fileCount":6,"zipByteSize":20076},{"version":"1.3.2","createdAt":"2026-08-30T08:32:31.549Z","changelog":"skillSpector cleanup: raw adb input tap fallbacks replaced with mobile: clickGesture, monkey pre-launch removed; taps via Appium/uiautomator2 only.","fileCount":6,"zipByteSize":19968},{"version":"1.3.1","createdAt":"2026-08-30T08:12:23.660Z","changelog":"Security review fixes: private 0700 IPC dir with ownership checks (no shared /tmp), Appium without --allow-insecure/--relaxed-security, private screenshot dir + clean command, Safety & Consent section.","fileCount":8,"zipByteSize":47331},{"version":"1.3.0","createdAt":"2026-08-30T06:47:42.074Z","changelog":"Add a11y-tree commands (a11y/a11y-selected/a11y-tap) for FLAG_SECURE pages and selection verification; type now clears the field before paste (PDD search lesson).","fileCount":7,"zipByteSize":26682},{"version":"1.2.0","createdAt":"2026-08-30T04:14:41.445Z","changelog":"Promote direct uiautomator2+RapidOCR loop (ocr_bridge.py) as primary backend after successful 12306 booking. Document Appium failure mode on WRITE_SECURE_SETTINGS devices, clipboard Chinese input, virtual-list scroll unsticking.","fileCount":7,"zipByteSize":23750},{"version":"1.0.2","createdAt":"2026-05-31T23:55:38.866Z","changelog":"- Added support for using either Appium or uiautomator2 as the backend, with clear instructions for both. - Expanded SKILL.md with detailed usage guides, backend limitations, and critical notes for UC WebView (Alipay Nebula)-based apps. - New tap commands: tap_bounds and tap_coords provide more precise control. - Documented which backend to use for specific cases (native views vs. UC WebView virtual lists). - Enhanced troubleshooting and knowledge sections for improved reliability in complex hybrid app scenarios. - Removed skill-card.md; added internal .clawhub metadata file.","fileCount":6,"zipByteSize":12967},{"version":"1.0.1","createdAt":"2026-05-27T15:45:33.266Z","changelog":"Cross-platform ANDROID_HOME auto-detection (Linux + macOS)","fileCount":5,"zipByteSize":8117}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s176q9th3gerh5cagvwz73f4r187fgya:appium-android-adb","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T03:54:56.314Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-openlittlebear-appium-android-adb/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":null},"readme":"Skill: Appium Android Adb\n\nOwner: openlittlebear\n\nSummary: Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A...\n\nTags: android:1.0.0, appium:1.0.0, automation:1.0.0, latest:1.3.4, webview:1.0.0\n\nVersion history:\n\nv1.3.4 | 2026-08-30T08:56:32.847Z | user\n\nReview fixes: screenshots auto-purged after 1h, typed/pasted text never echoed, one-shot mode stops the Appium server it started (no services left running).\n\nv1.3.3 | 2026-08-30T08:47:02.244Z | user\n\nDaemon now opt-in: one-shot commands use short-lived sessions (no persistent bridge by default). Screenshots moved to private IPC dir. Fixes platform review verdict (persistent device-control bridge, /tmp screenshot paths).\n\nv1.3.2 | 2026-08-30T08:32:31.549Z | user\n\nskillSpector cleanup: raw adb input tap fallbacks replaced with mobile: clickGesture, monkey pre-launch removed; taps via Appium/uiautomator2 only.\n\nv1.3.1 | 2026-08-30T08:12:23.660Z | user\n\nSecurity review fixes: private 0700 IPC dir with ownership checks (no shared /tmp), Appium without --allow-insecure/--relaxed-security, private screenshot dir + clean command, Safety & Consent section.\n\nv1.3.0 | 2026-08-30T06:47:42.074Z | user\n\nAdd a11y-tree commands (a11y/a11y-selected/a11y-tap) for FLAG_SECURE pages and selection verification; type now clears the field before paste (PDD search lesson).\n\nv1.2.0 | 2026-08-30T04:14:41.445Z | user\n\nPromote direct uiautomator2+RapidOCR loop (ocr_bridge.py) as primary backend after successful 12306 booking. Document Appium failure mode on WRITE_SECURE_SETTINGS devices, clipboard Chinese input, virtual-list scroll unsticking.\n\nv1.0.2 | 2026-05-31T23:55:38.866Z | user\n\n- Added support for using either Appium or uiautomator2 as the backend, with clear instructions for both.\n- Expanded SKILL.md with detailed usage guides, backend limitations, and critical notes for UC WebView (Alipay Nebula)-based apps.\n- New tap commands: tap_bounds and tap_coords provide more precise control.\n- Documented which backend to use for specific cases (native views vs. UC WebView virtual lists).\n- Enhanced troubleshooting and knowledge sections for improved reliability in complex hybrid app scenarios.\n- Removed skill-card.md; added internal .clawhub metadata file.\n\nv1.0.1 | 2026-05-27T15:45:33.266Z | user\n\nCross-platform ANDROID_HOME auto-detection (Linux + macOS)\n\nv1.0.0 | 2026-05-26T14:57:25.375Z | auto\n\n- Initial release of appium-android-adb skill.\n- Provides a persistent Appium bridge daemon for controlling any Android app.\n- Supports structured screen reading (JSON output) and reliable interactions (tap, scroll, type) via accessibility service.\n- Especially useful for automating WebView and hybrid apps where raw ADB does not work.\n- Includes commands: dump, tap, scroll, type, wait for robust automation workflows.\n\nArchive index:\n\nArchive v1.3.4: 6 files, 20464 bytes\n\nFiles: _meta.json (137b), bridge_daemon.py (26317b), ocr_bridge.py (11266b), skill-card.md (2201b), SKILL.md (11580b), start_bridge.sh (2270b)\n\nFile v1.3.4:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n**Clear the field first** — pasting over existing text concatenates instead of\nreplacing (hit on the PDD search box). `ocr_bridge.py type` clears any focused\nEditText by default (`--no-clear` to skip).\n\n## FLAG_SECURE Pages (payment screens) — a11y Tree as the Eye\n\nPayment pages (e.g. PDD 多多钱包, PayConfirmActivity) set FLAG_SECURE:\n`screencap` returns black/0-byte files. **The accessibility tree still works** —\nread and tap via it:\n\n```bash\n$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree\n```\n\nAlso the authoritative state check for selection chips when OCR is ambiguous:\n`selected=\"true\"` in the tree beats pixel guessing.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# One-shot commands run with a short-lived session by default (safer):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n\n# Persistent mode is opt-in — only if you need low-latency batches:\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n# ...which runs: python3 bridge_daemon.py --daemon\n```\n\nA background daemon is NOT auto-started by single commands; one-shot mode\ncreates a session, executes, and quits. Screenshots and IPC files live in the\nprivate 0700 dir `~/.cache/appium-bridge`. Cannot run simultaneously with\nuiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## 🛡️ Safety & Consent\n\n- **Trigger boundary**: use this skill only when the user explicitly asks to\n  control their phone (a specific booking/purchase/app task). Never touch the\n  device speculatively or from background tasks.\n- **Confirm before irreversible actions**: before submitting an order, a\n  checkout step, or any tap that changes live app state, tell the user what\n  will happen and wait for confirmation. Payment credentials (PIN,\n  fingerprint) are ALWAYS entered by the user — scripts never request or\n  store them.\n- **Screen data**: screenshots/OCR captures can contain personal data. They\n  are stored in a private 0700 dir (`~/.cache/ocr-bridge`, override\n  `OCR_BRIDGE_DIR`) and shots older than 1 hour are purged automatically on\n  every screenshot; `ocr_bridge.py clean` purges immediately.\n- **No secret echoes**: typed/pasted content is never echoed in output or\n  logs (only its length). One-shot bridge commands stop any Appium server\n  they started themselves — no services left running.\n- **Bridge IPC**: `bridge_daemon.py` keeps its command/response files in a\n  private 0700 dir (`~/.cache/appium-bridge`) and rejects files not owned by\n  the current user. Appium runs WITHOUT `--allow-insecure`/`--relaxed-security`.\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.3.4:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.4\",\n  \"publishedAt\": 1788080192847\n}\n\nFile v1.3.4:skill-card.md\n\n## Description:\n\nRead and control Android apps through OCR-driven uiautomator2 commands or a fallback Appium bridge.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and automation agents use this skill to inspect Android screens, identify UI text or accessibility nodes, and issue taps, swipes, waits, typing, screenshots, and Appium bridge commands for user-directed mobile app tasks.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can broadly control a connected Android device.\n\nMitigation: Use it only for explicit user-directed phone-control tasks, prefer one-shot commands, and require confirmation before irreversible actions such as orders or checkout steps.\n\nRisk: Screenshots and OCR output can include personal or sensitive screen data.\n\nMitigation: Use the private screenshot directory, clean screenshots after use, and rely on the documented automatic purge for captures older than one hour.\n\nRisk: Network exposure or persistent bridge behavior could expand the control surface.\n\nMitigation: Bind Appium to loopback, avoid relaxed-security flags, and prefer short-lived one-shot commands unless persistent mode is required.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n- [Publisher profile](https://clawhub.ai/user/openlittlebear)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON command results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands may read screen text, capture screenshots, and control a connected Android device when run by the agent.]\n\n## Skill Version(s):\n\n1.3.4 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.3: 6 files, 20076 bytes\n\nFiles: _meta.json (137b), bridge_daemon.py (25739b), ocr_bridge.py (11024b), skill-card.md (2252b), SKILL.md (11314b), start_bridge.sh (2270b)\n\nFile v1.3.3:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n**Clear the field first** — pasting over existing text concatenates instead of\nreplacing (hit on the PDD search box). `ocr_bridge.py type` clears any focused\nEditText by default (`--no-clear` to skip).\n\n## FLAG_SECURE Pages (payment screens) — a11y Tree as the Eye\n\nPayment pages (e.g. PDD 多多钱包, PayConfirmActivity) set FLAG_SECURE:\n`screencap` returns black/0-byte files. **The accessibility tree still works** —\nread and tap via it:\n\n```bash\n$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree\n```\n\nAlso the authoritative state check for selection chips when OCR is ambiguous:\n`selected=\"true\"` in the tree beats pixel guessing.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# One-shot commands run with a short-lived session by default (safer):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n\n# Persistent mode is opt-in — only if you need low-latency batches:\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n# ...which runs: python3 bridge_daemon.py --daemon\n```\n\nA background daemon is NOT auto-started by single commands; one-shot mode\ncreates a session, executes, and quits. Screenshots and IPC files live in the\nprivate 0700 dir `~/.cache/appium-bridge`. Cannot run simultaneously with\nuiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## 🛡️ Safety & Consent\n\n- **Trigger boundary**: use this skill only when the user explicitly asks to\n  control their phone (a specific booking/purchase/app task). Never touch the\n  device speculatively or from background tasks.\n- **Confirm before irreversible actions**: before submitting an order, a\n  checkout step, or any tap that changes live app state, tell the user what\n  will happen and wait for confirmation. Payment credentials (PIN,\n  fingerprint) are ALWAYS entered by the user — scripts never request or\n  store them.\n- **Screen data**: screenshots/OCR captures can contain personal data. They\n  are stored in a private 0700 dir (`~/.cache/ocr-bridge`, override\n  `OCR_BRIDGE_DIR`); `ocr_bridge.py clean` deletes shots older than 1 hour.\n- **Bridge IPC**: `bridge_daemon.py` keeps its command/response files in a\n  private 0700 dir (`~/.cache/appium-bridge`) and rejects files not owned by\n  the current user. Appium runs WITHOUT `--allow-insecure`/`--relaxed-security`.\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.3.3:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.3\",\n  \"publishedAt\": 1788079622244\n}\n\nFile v1.3.3:skill-card.md\n\n## Description:\n\nEnables agents to read and control Android apps through a uiautomator2 and RapidOCR command loop, with Appium commands as a fallback for native apps.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and agent operators use this skill to inspect Android screen state, tap, scroll, type, and wait for visible UI changes during explicit mobile app tasks such as bookings or purchases.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can read and control a connected Android phone, including screens that may show personal, booking, or payment information.\n\nMitigation: Use it only for explicit phone-control tasks, review actions before orders or payments, never provide PINs or payment secrets to scripts, and clean or inspect the private screenshot cache when sensitive data may be present.\n\nRisk: OCR and accessibility-tree readings can be wrong or stale, which can lead to tapping the wrong element in a live app.\n\nMitigation: Re-read the screen after each action, verify that the UI changed as expected, and require user confirmation before irreversible state-changing steps.\n\nRisk: Persistent device-control sessions increase exposure if left running unnecessarily.\n\nMitigation: Prefer one-shot commands, use the persistent daemon only when low-latency batches are needed, and keep IPC and screenshot files in private per-user directories.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [text, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with shell commands; bridge commands return JSON or text screen data.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [None]\n\n## Skill Version(s):\n\n1.3.3 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.2: 6 files, 19968 bytes\n\nFiles: _meta.json (137b), bridge_daemon.py (25362b), ocr_bridge.py (11024b), skill-card.md (2572b), SKILL.md (10992b), start_bridge.sh (2270b)\n\nFile v1.3.2:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n**Clear the field first** — pasting over existing text concatenates instead of\nreplacing (hit on the PDD search box). `ocr_bridge.py type` clears any focused\nEditText by default (`--no-clear` to skip).\n\n## FLAG_SECURE Pages (payment screens) — a11y Tree as the Eye\n\nPayment pages (e.g. PDD 多多钱包, PayConfirmActivity) set FLAG_SECURE:\n`screencap` returns black/0-byte files. **The accessibility tree still works** —\nread and tap via it:\n\n```bash\n$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree\n```\n\nAlso the authoritative state check for selection chips when OCR is ambiguous:\n`selected=\"true\"` in the tree beats pixel guessing.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# Once per session (~28s):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then all interactions (~1-2s each):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\nCannot run simultaneously with uiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## 🛡️ Safety & Consent\n\n- **Trigger boundary**: use this skill only when the user explicitly asks to\n  control their phone (a specific booking/purchase/app task). Never touch the\n  device speculatively or from background tasks.\n- **Confirm before irreversible actions**: before submitting an order, a\n  checkout step, or any tap that changes live app state, tell the user what\n  will happen and wait for confirmation. Payment credentials (PIN,\n  fingerprint) are ALWAYS entered by the user — scripts never request or\n  store them.\n- **Screen data**: screenshots/OCR captures can contain personal data. They\n  are stored in a private 0700 dir (`~/.cache/ocr-bridge`, override\n  `OCR_BRIDGE_DIR`); `ocr_bridge.py clean` deletes shots older than 1 hour.\n- **Bridge IPC**: `bridge_daemon.py` keeps its command/response files in a\n  private 0700 dir (`~/.cache/appium-bridge`) and rejects files not owned by\n  the current user. Appium runs WITHOUT `--allow-insecure`/`--relaxed-security`.\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.3.2:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.2\",\n  \"publishedAt\": 1788078751549\n}\n\nFile v1.3.2:skill-card.md\n\n## Description:\n\nEnables agents to inspect and control connected Android apps through an OCR-first uiautomator2 workflow, with Appium fallback commands for native app screens.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and automation operators use this skill to let an agent read Android app screens and perform user-directed taps, scrolling, typing, waits, and payment-screen accessibility checks on a connected device.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Live Android device control can perform purchases, order submissions, or account-changing taps.\n\nMitigation: Use only for explicit user-directed tasks, require confirmation before irreversible actions, and have the user enter payment credentials directly.\n\nRisk: Screenshots, OCR text, and accessibility dumps can expose personal or payment-related screen content.\n\nMitigation: Keep captures in private per-user directories where supported, run cleanup after use, avoid entering payment secrets through scripts, and stop or clean the bridge on shared machines.\n\nRisk: Persistent local bridge command files create a sensitive command surface for device-control actions.\n\nMitigation: Use private per-user IPC storage, reject command files not owned by the current user or writable by others, and stop the bridge after the task is complete.\n\nRisk: Appium fallback behavior may fail or become unreliable on locked-down devices or UC WebView app flows.\n\nMitigation: Prefer the OCR/uiautomator2 loop, verify the screen after every action, and fall back to Appium only for native app screens where it is appropriate.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [text, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with shell command examples and JSON command outputs]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands may read screen text, capture screenshots, tap, scroll, type, wait for text, and return structured JSON status.]\n\n## Skill Version(s):\n\n1.3.2 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.1: 8 files, 47331 bytes\n\nFiles: __pycache__/bridge_daemon.cpython-314.pyc (36354b), __pycache__/ocr_bridge.cpython-314.pyc (18639b), _meta.json (137b), bridge_daemon.py (25858b), ocr_bridge.py (11024b), skill-card.md (2187b), SKILL.md (10992b), start_bridge.sh (2270b)\n\nFile v1.3.1:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n**Clear the field first** — pasting over existing text concatenates instead of\nreplacing (hit on the PDD search box). `ocr_bridge.py type` clears any focused\nEditText by default (`--no-clear` to skip).\n\n## FLAG_SECURE Pages (payment screens) — a11y Tree as the Eye\n\nPayment pages (e.g. PDD 多多钱包, PayConfirmActivity) set FLAG_SECURE:\n`screencap` returns black/0-byte files. **The accessibility tree still works** —\nread and tap via it:\n\n```bash\n$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree\n```\n\nAlso the authoritative state check for selection chips when OCR is ambiguous:\n`selected=\"true\"` in the tree beats pixel guessing.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# Once per session (~28s):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then all interactions (~1-2s each):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\nCannot run simultaneously with uiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## 🛡️ Safety & Consent\n\n- **Trigger boundary**: use this skill only when the user explicitly asks to\n  control their phone (a specific booking/purchase/app task). Never touch the\n  device speculatively or from background tasks.\n- **Confirm before irreversible actions**: before submitting an order, a\n  checkout step, or any tap that changes live app state, tell the user what\n  will happen and wait for confirmation. Payment credentials (PIN,\n  fingerprint) are ALWAYS entered by the user — scripts never request or\n  store them.\n- **Screen data**: screenshots/OCR captures can contain personal data. They\n  are stored in a private 0700 dir (`~/.cache/ocr-bridge`, override\n  `OCR_BRIDGE_DIR`); `ocr_bridge.py clean` deletes shots older than 1 hour.\n- **Bridge IPC**: `bridge_daemon.py` keeps its command/response files in a\n  private 0700 dir (`~/.cache/appium-bridge`) and rejects files not owned by\n  the current user. Appium runs WITHOUT `--allow-insecure`/`--relaxed-security`.\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.3.1:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.1\",\n  \"publishedAt\": 1788077543660\n}\n\nFile v1.3.1:skill-card.md\n\n## Description:\n\nRead and control Android apps through an OCR-backed uiautomator2 loop, with Appium support as a fallback for native app interactions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and operators use this skill to inspect and control a connected Android phone for explicit app tasks, including OCR-based reading, tapping, swiping, typing, waiting, and fallback Appium automation.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can give an agent local control of a connected Android phone.\n\nMitigation: Use it only for explicit phone-control tasks, confirm before irreversible actions, and keep payment credentials under direct user control.\n\nRisk: Screenshots and OCR captures can include personal, order, or payment-related screen data.\n\nMitigation: Use private screenshot storage where supported, avoid shared machines, and run the cleanup command or delete temporary screenshots after use.\n\nRisk: Fallback Appium automation can leave screenshots in shared temporary paths and keep local device-control services running.\n\nMitigation: Prefer the OCR loop when appropriate, delete fallback screenshots after use, and stop Appium or daemon processes when the task is complete.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with shell command examples and JSON command or response patterns]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May propose or run local Android device-control commands for explicit connected-phone tasks.]\n\n## Skill Version(s):\n\n1.3.1 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.0: 7 files, 26682 bytes\n\nFiles: __pycache__/ocr_bridge.cpython-314.pyc (16621b), _meta.json (137b), bridge_daemon.py (24553b), ocr_bridge.py (9915b), skill-card.md (1900b), SKILL.md (10000b), start_bridge.sh (2050b)\n\nFile v1.3.0:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n**Clear the field first** — pasting over existing text concatenates instead of\nreplacing (hit on the PDD search box). `ocr_bridge.py type` clears any focused\nEditText by default (`--no-clear` to skip).\n\n## FLAG_SECURE Pages (payment screens) — a11y Tree as the Eye\n\nPayment pages (e.g. PDD 多多钱包, PayConfirmActivity) set FLAG_SECURE:\n`screencap` returns black/0-byte files. **The accessibility tree still works** —\nread and tap via it:\n\n```bash\n$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree\n```\n\nAlso the authoritative state check for selection chips when OCR is ambiguous:\n`selected=\"true\"` in the tree beats pixel guessing.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# Once per session (~28s):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then all interactions (~1-2s each):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\nCannot run simultaneously with uiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.0\",\n  \"publishedAt\": 1788072462074\n}\n\nFile v1.3.0:skill-card.md\n\n## Description:\n\nRead and control Android apps through a uiautomator2 and RapidOCR loop, with Appium bridge commands as a fallback for native apps.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and automation engineers use this skill to inspect Android screens and execute taps, scrolling, typing, and waits through OCR/uiautomator2 workflows, falling back to Appium for native apps when device permissions allow.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can read and control a connected Android phone.\n\nMitigation: Install it only when that control is intentional, and avoid running it while sensitive apps are open.\n\nRisk: The long-running Appium bridge uses relaxed security flags and predictable /tmp command files that other local processes could abuse.\n\nMitigation: Run it in a trusted single-user environment, stop Appium and the daemon when finished, and prefer a version with private authenticated IPC and without relaxed Appium security flags.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration, JSON]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Bridge commands return JSON responses when executed by an agent.]\n\n## Skill Version(s):\n\n1.3.0 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.0: 7 files, 23750 bytes\n\nFiles: __pycache__/ocr_bridge.cpython-314.pyc (12369b), _meta.json (137b), bridge_daemon.py (24553b), ocr_bridge.py (7254b), skill-card.md (2271b), SKILL.md (9163b), start_bridge.sh (2050b)\n\nFile v1.2.0:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down devices. The proven route:\n\n```python\nd.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it\n```\n\n`ocr_bridge.py type 苏州 --x 400 --y 330` sets clipboard and long-presses the field.\n\n## Scrolling a UC WebView Virtual List\n\n- Normal advance: `d.swipe_ext('up', scale=0.35)` (≈2 train cards per scroll on 12306)\n- **List \"skips\" a section** (target train keeps getting jumped over): do `jump` — 3 rapid large swipes (`scale=0.5`, 1.2s apart), then micro-swipes back (`scale=0.15–0.25`, or `d.swipe(540, 1900, 540, 800, duration=0.4)`)\n- Track position with departure-time markers: `deps()` = HH:MM texts at x<250 — you always know which time window is on screen, independent of the DOM\n\n## Option B: bridge_daemon.py (Appium, fallback only)\n\n```bash\n# Once per session (~28s):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then all interactions (~1-2s each):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\nCannot run simultaneously with uiautomator2 (same AccessibilityService).\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use the OCR loop / `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| UC WebView apps (12306, Alipay, many Chinese apps) — everything | **OCR loop** (`ocr_bridge.py`) |\n| Screen state / text reading | `ocr_bridge.py dump` / `markers` / `deps` |\n| Clicking anything visible | `ocr_bridge.py tap-text` / `tap` (u2 click) |\n| Scrolling UC WebView lists | `ocr_bridge.py swipe` / `jump` / `micro` |\n| Chinese text input | `d.set_clipboard` + long-press paste |\n| Native apps with structured dumps / find / wait | bridge_daemon.py (Appium) — if the device allows it |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y≈407 (top) or y≈2255 (bottom), h=6px — DOM lies\n- **The DOM is unreliable**: sometimes renders (usable), mostly collapsed. OCR is the dependable eye.\n\n### What Works on UC WebView\n1. `d.click(x, y)` from uiautomator2 — reliably delivers touches (unlike raw ADB)\n2. Scrolling via `d.swipe_ext()` / `d.swipe()`\n3. OCR + coordinate click (RapidOCR reads Chinese out of the box — no tesseract language packs)\n4. `d.set_clipboard()` + long-press paste for Chinese input\n5. `d.dump_hierarchy()` sometimes gives accurate data — use when it renders, never depend on it\n\n### What Does NOT Work on UC WebView\n1. Raw `adb shell input tap` — filtered by UC WebView (observed 2026-08-30)\n2. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n6. `d.set_input_ime()` / fastinput on Realme — WRITE_SECURE_SETTINGS blocked\n\n## Troubleshooting\n\n**Appium session creation error / \"settings command problem\"**: Device blocks WRITE_SECURE_SETTINGS (Realme etc.). Stop fighting it — use the OCR loop.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first (`pkill -f appium`).\n**OCR finds nothing / misreads**: RapidOCR is noisy on small text — narrow search to a region (x/y bounds) and re-shoot; the screen may still be animating (sleep 2-3s after actions).\n**Train number not found**: DOM text has spaces (`G 7 0 0 4`), but OCR text does not (`G7004`). Match with regex on OCR: `^[GDCK]\\d+`.\n**tesseract missing**: Don't install it — RapidOCR (rapidocr-onnxruntime) needs no language data and read Chinese reliably in production.\n\nFile v1.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.2.0\",\n  \"publishedAt\": 1788063281445\n}\n\nFile v1.2.0:skill-card.md\n\n## Description:\n\nRead and control Android apps through an OCR-first uiautomator2 bridge with an Appium fallback for native apps.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and automation engineers use this skill to inspect Android screens, issue taps, swipes, text entry, screenshots, and waits, and choose between OCR-based uiautomator2 control and an Appium daemon fallback.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can give an agent broad local control over a connected Android device.\n\nMitigation: Install and run it only on a trusted, single-user machine, and avoid use on password, identity, or payment entry screens unless necessary.\n\nRisk: The Appium fallback starts persistent device-control services with relaxed local protections.\n\nMitigation: Stop Appium and the bridge daemon when finished, and prefer the OCR loop when Appium is not required.\n\nRisk: Screenshots and bridge IPC files are written under /tmp.\n\nMitigation: Clear /tmp screenshots and bridge state after use, especially when screens may contain sensitive information.\n\nRisk: Appium setup can fail on devices that block WRITE_SECURE_SETTINGS or IME switching.\n\nMitigation: Use the documented uiautomator2 and RapidOCR path first, and fall back to Appium only for native apps when the device permits it.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Some bridge commands return JSON responses or write screenshots to /tmp for agent inspection.]\n\n## Skill Version(s):\n\n1.2.0 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.2: 6 files, 12967 bytes\n\nFiles: _meta.json (137b), .clawhub/origin.json (235b), bridge_daemon.py (24553b), skill-card.md (2515b), SKILL.md (5985b), start_bridge.sh (1875b)\n\nFile v1.0.2:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands AND direct uiautomator2 Python library support. For UC WebView (Alipay Nebula) apps like 12306, prefer uiautomator2 for scrolling and booking action clicks.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens as structured JSON, executes taps/scrolling/typing. Supports two backends:\n\n| Backend | Best for | Limitations |\n|---------|----------|-------------|\n| **Appium** (bridge_daemon.py) | Native apps, structured dumps, `find`/`wait` | UC WebView virtual list taps fail on collapsed elements |\n| **uiautomator2** (Python lib) | WebView content, scrolling, booking buttons | Conflicts with Appium (same session can't share AccessibilityService) |\n\n## Quick Start\n\n### Option A: bridge_daemon.py (Appium-based)\n\n```bash\n# Once per session (~28s):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then all interactions (~1-2s each):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\n### Option B: uiautomator2 (direct Python)\n\n```bash\npip3 install uiautomator2  # already installed\npython3 -c \"\nimport uiautomator2 as u2\nd = u2.connect()\nd.app_start('com.MobileTicket')\n\"\n```\n\nUse for WebView scroll + booking button clicks. **Cannot run simultaneously with Appium.**\n\n## Commands (bridge_daemon.py)\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n\n### tap — click element by text\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}'\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'\n```\n\n### tap_bounds — click using bounds from dump\n```bash\npython3 bridge_daemon.py tap_bounds '{\"bounds\": \"[870,1988][1008,2075]\"}'\n```\n⚠️ Only works reliably if the element has **proper bounds** (h > 20px). Collapsed virtual list items (h=6px) will NOT respond.\n\n### tap_coords — click at exact coordinates\n```bash\npython3 bridge_daemon.py tap_coords '{\"x\": 540, \"y\": 1200}'\n```\n\n### find — inspect element matches\n```bash\npython3 bridge_daemon.py find '{\"text\": \"7004\"}'\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"micro\"}'\n```\n⚠️ **May not work on UC WebView** (used by 12306, Alipay apps). The WebView filters touch events. For UC WebView scrolling, use uiautomator2's `d.swipe_ext()` instead.\n\n### screenshot — take phone screenshot\n```bash\npython3 bridge_daemon.py screenshot\n# Returns {\"ok\": true, \"path\": \"/tmp/screen.png\"}\n```\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use Which\n\n| Situation | Recommended Tool |\n|-----------|-----------------|\n| Native Android views (date tabs, search buttons, bottom nav) | Either — both work |\n| App dump / text search / element inspection | bridge_daemon.py `dump` + `find` |\n| UC WebView content (train list, booking pages) | **uiautomator2** |\n| Clicking \"预订\" / \"提交订单\" / action buttons | uiautomator2 `d.text('预订').click()` |\n| Scrolling UC WebView lists | uiautomator2 `d.swipe_ext('up', scale=0.3)` |\n| OCR + coordinate tap | ADB `input tap` (works on visible content) |\n| WebView text content (crashes UIAutomator2) | bridge_daemon.py `dump` (via Appium) |\n\n## ⚠️ UC WebView Virtual List — Critical Knowledge\n\nApps using UC WebView (12306, many Chinese apps) use **virtual lists** that collapse most items' accessibility bounds:\n\n- **Visible items**: Have real bounds (h=60-130px), clickable via accessibility service\n- **Off-screen items**: COLLAPSED to y=407 (top) or y=2255 (bottom), h=6px\n- **Action buttons**: \"预订\" buttons ALWAYS have proper bounds (h=87px) even in virtual lists\n\n### What Works on UC WebView\n1. Clicking action buttons like \"预订\", \"提交订单\", \"查询车票\" — they have persistent proper bounds\n2. Scrolling via `d.swipe_ext()` in uiautomator2\n3. OCR + coordinate-based ADB tap (with good image preprocessing)\n4. Element `click()` via uiautomator2 when the element has h > 20px\n\n### What Does NOT Work on UC WebView\n1. Clicking collapsed text elements (train names, times, seat info) — h=6px bounds\n2. ADB `input tap` on WebView content — silently filtered by UC WebView\n3. `mobile: scrollGesture` via Appium — returns False\n4. W3C Actions swipe — touch events filtered\n5. JS injection (`execute_script`) — no WEBVIEW contexts exposed\n\n## Troubleshooting\n\n**Daemon died**: Run `start_bridge.sh` again.\n**uiautomator2 conflict**: \"AccessibilityService already registered\" means Appium is running. Kill Appium first.\n**Appium session error / ANDROID_HOME**: Ensure `export ANDROID_HOME=/usr/lib/android-sdk` before starting Appium.\n**G7004 text not found**: Search with spaces: `G 7 0 0 4`, not `G7004`.\n**\"预订\" not found**: The list may not have loaded yet. Wait and re-dump.\n**OCR not reading Chinese**: Use `lang='chi_sim+eng'` with `--psm 6` config.\n\nFile v1.0.2:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.0.2\",\n  \"publishedAt\": 1780271738866\n}\n\nFile v1.0.2:skill-card.md\n\n## Description: <br>\nRead and control any Android app via Appium or uiautomator2, using a persistent bridge daemon with dump, tap, scroll, type, wait, screenshot, and direct uiautomator2 workflows. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[openlittlebear](https://clawhub.ai/user/openlittlebear) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent operators use this skill to inspect Android app screens and issue controlled Appium, uiautomator2, or ADB actions against a connected Android device. It is especially aimed at native Android views and UC WebView-based apps where structured dumps, coordinate taps, screenshots, and backend-specific scrolling guidance are needed. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can persistently read and control a connected Android device. <br>\nMitigation: Use it only with devices and apps you intend to automate, and stop the bridge when the task is complete. <br>\nRisk: Local IPC files and screenshots under /tmp may expose device state on shared or multi-user machines. <br>\nMitigation: Run on a trusted single-user workstation, clear temporary bridge files and screenshots after use, and avoid sensitive screens. <br>\nRisk: The Appium startup path uses insecure and relaxed security flags. <br>\nMitigation: Review the Appium flags before running, restrict access to localhost, and avoid using the bridge around banking, messaging, password, payment, or account-recovery workflows. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/appium-android-adb) <br>\n- [Publisher profile](https://clawhub.ai/user/openlittlebear) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands and JSON command examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Runtime bridge commands return JSON responses for screen dumps, element matches, taps, scrolls, screenshots, typing, and waits.] <br>\n\n## Skill Version(s): <br>\n1.0.2 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.0.2:.clawhub/origin.json\n\n{\n  \"version\": 1,\n  \"registry\": \"https://clawhub.ai\",\n  \"slug\": \"appium-android-adb\",\n  \"installedVersion\": \"1.0.0\",\n  \"installedAt\": 1779896221918,\n  \"fingerprint\": \"d6e25390ec2c11409a70c1dfd8f3315caf9370b2276622800fc89df79f1aaa8d\"\n}\n\nArchive v1.0.1: 5 files, 8117 bytes\n\nFiles: _meta.json (137b), bridge_daemon.py (11648b), skill-card.md (2331b), SKILL.md (3332b), start_bridge.sh (1879b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands. Use when raw ADB taps don't work (WebView apps, UC WebView) or when you need structured screen reading. Start with start_bridge.sh once, then use bridge_daemon.py for all interactions at ~1-2s per call.\n---\n\n# Appium Android Bridge\n\nGeneric Appium bridge for any Android app. Reads screens as structured JSON, executes taps/scrolling/typing via accessibility service clicks (bypasses WebView touch filtering).\n\n## Quick Start\n\n```bash\n# Once per session (28s, starts Appium + daemon):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then every action (~1-2s each):\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py dump\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py tap '{\"text\": \"查询\"}'\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\n## Commands\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.example.app\",\n  \"activity\": \"...\",\n  \"title\": \"...\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [{\"text\": \"查询\", \"id\": \"btn_search\", \"bounds\": \"[99,750][981,882]\"}],\n  \"trains\": [{\"text\": \"...\", \"bounds\": \"...\", \"clickable\": true}],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n- `buttons[]` — all clickable elements with text, id, bounds\n- `alerts[]` — dialogs/popups needing dismissal\n- `trains[]` — elements containing \"次列车\" (app-agnostic; rename for other apps)\n- `title` — page title if present\n\n### tap — click an element\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'       # by text (substring match)\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}' # first match\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'         # by resource-id\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'               # normal\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"short\"}' # fine\npython3 bridge_daemon.py scroll '{\"direction\": \"up\"}'                 # go back\n```\nUses fast drag (100ms) — works best for WebView content.\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use This\n\nUse `appium-android-adb` when:\n- The app uses WebView (ADB taps are ignored)\n- You need structured screen reading (not screenshot-based)\n- You need reliable element clicking (accessibility service, not raw touch)\n- You're automating a hybrid app (native + WebView)\n\nDo NOT use for:\n- Simple native-only apps where `adb shell input tap` works fine\n- One-off screenshots (use `adb shell screencap`)\n\n## Troubleshooting\n\n**Daemon died**: Run `start_bridge.sh` again to restart.\n**Device not found**: Check USB connection: `adb devices`\n**App not launching**: The daemon attaches to the running app. Cold-start the app manually if needed: `adb shell monkey -p <package> 1`\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1779896733266\n}\n\nFile v1.0.1:skill-card.md\n\n## Description: <br>\nReads Android app screens as structured JSON and controls app interactions through a persistent Appium/ADB bridge. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[openlittlebear](https://clawhub.ai/user/openlittlebear) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and automation engineers use this skill to inspect Android UI state and issue Appium-backed tap, scroll, text-entry, and wait commands when raw ADB input is insufficient. Reviewers should confirm the intended target app because the implementation is hardcoded to the MobileTicket package. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The security evidence reports a mismatch between the generic skill description and hardcoded 12306/MobileTicket targeting. <br>\nMitigation: Install only when intentionally automating that target app, and confirm or change package paths before use. <br>\nRisk: The bridge can read screens and perform real taps or text entry on a connected Android device. <br>\nMitigation: Review command JSON before execution and use trusted devices, test accounts, or non-sensitive app states where possible. <br>\nRisk: Broad Appium security flags and unauthenticated /tmp command files provide weakly scoped local controls. <br>\nMitigation: Run the bridge only on trusted local machines, restrict local user access, and replace shared /tmp IPC or broad Appium flags before production deployment. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/appium-android-adb) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [JSON, Shell commands, Guidance] <br>\n**Output Format:** [JSON command responses and Markdown instructions with shell commands] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a local Android device or emulator, ADB, Appium, and a running bridge daemon.] <br>\n\n## Skill Version(s): <br>\n1.0.1 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.0: 5 files, 7950 bytes\n\nFiles: _meta.json (137b), bridge_daemon.py (11159b), skill-card.md (2492b), SKILL.md (3332b), start_bridge.sh (1647b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands. Use when raw ADB taps don't work (WebView apps, UC WebView) or when you need structured screen reading. Start with start_bridge.sh once, then use bridge_daemon.py for all interactions at ~1-2s per call.\n---\n\n# Appium Android Bridge\n\nGeneric Appium bridge for any Android app. Reads screens as structured JSON, executes taps/scrolling/typing via accessibility service clicks (bypasses WebView touch filtering).\n\n## Quick Start\n\n```bash\n# Once per session (28s, starts Appium + daemon):\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n\n# Then every action (~1-2s each):\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py dump\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py tap '{\"text\": \"查询\"}'\npython3 ~/.openclaw/workspace/skills/appium-android-adb/bridge_daemon.py scroll '{\"direction\": \"down\"}'\n```\n\n## Commands\n\nAll from `~/.openclaw/workspace/skills/appium-android-adb/`. All return JSON.\n\n### dump — read the screen\n```bash\npython3 bridge_daemon.py dump\n```\nReturns:\n```json\n{\n  \"ok\": true,\n  \"package\": \"com.example.app\",\n  \"activity\": \"...\",\n  \"title\": \"...\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [{\"text\": \"查询\", \"id\": \"btn_search\", \"bounds\": \"[99,750][981,882]\"}],\n  \"trains\": [{\"text\": \"...\", \"bounds\": \"...\", \"clickable\": true}],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}\n```\n- `buttons[]` — all clickable elements with text, id, bounds\n- `alerts[]` — dialogs/popups needing dismissal\n- `trains[]` — elements containing \"次列车\" (app-agnostic; rename for other apps)\n- `title` — page title if present\n\n### tap — click an element\n```bash\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'       # by text (substring match)\npython3 bridge_daemon.py tap '{\"text\": \"预订\", \"index\": 0}' # first match\npython3 bridge_daemon.py tap '{\"id\": \"btn_submit\"}'         # by resource-id\n```\n\n### scroll — swipe the screen\n```bash\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'               # normal\npython3 bridge_daemon.py scroll '{\"direction\": \"down\", \"distance\": \"short\"}' # fine\npython3 bridge_daemon.py scroll '{\"direction\": \"up\"}'                 # go back\n```\nUses fast drag (100ms) — works best for WebView content.\n\n### type — input text\n```bash\npython3 bridge_daemon.py type '{\"text\": \"上海\"}'\n```\n\n### wait — poll until element appears\n```bash\npython3 bridge_daemon.py wait '{\"text\": \"提交订单\", \"timeout\": 30}'\n```\n\n## When to Use This\n\nUse `appium-android-adb` when:\n- The app uses WebView (ADB taps are ignored)\n- You need structured screen reading (not screenshot-based)\n- You need reliable element clicking (accessibility service, not raw touch)\n- You're automating a hybrid app (native + WebView)\n\nDo NOT use for:\n- Simple native-only apps where `adb shell input tap` works fine\n- One-off screenshots (use `adb shell screencap`)\n\n## Troubleshooting\n\n**Daemon died**: Run `start_bridge.sh` again to restart.\n**Device not found**: Check USB connection: `adb devices`\n**App not launching**: The daemon attaches to the running app. Cold-start the app manually if needed: `adb shell monkey -p <package> 1`\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1779807445375\n}\n\nFile v1.0.0:skill-card.md\n\n## Description: <br>\nRead and control Android apps through an Appium bridge daemon that returns structured JSON and supports dump, tap, scroll, type, and wait commands. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[openlittlebear](https://clawhub.ai/user/openlittlebear) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and test automation engineers use this skill to inspect and interact with Android apps, especially WebView or hybrid apps where raw ADB taps are unreliable. Use it on trusted local machines with authorized test devices. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The security review found under-disclosed high-impact Android control paths. <br>\nMitigation: Review commands before execution, use only with authorized test devices, and avoid sensitive apps. <br>\nRisk: The skill starts Appium with broad insecure and relaxed-security flags. <br>\nMitigation: Run only on a trusted single-user machine, limit local access to the Appium service, and remove broad insecure flags before broader deployment. <br>\nRisk: The bridge uses shared /tmp files for local command and response exchange. <br>\nMitigation: Avoid multi-user or untrusted local environments and replace shared /tmp IPC with a private authenticated channel for production use. <br>\nRisk: The implementation is partly app-specific despite the generic Android bridge description. <br>\nMitigation: Confirm the target package and behavior before use, or clearly label and configure the bridge for the intended app. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill release](https://clawhub.ai/openlittlebear/appium-android-adb) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, JSON] <br>\n**Output Format:** [Markdown guidance with shell command examples; command responses are JSON.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Requires a local Android device or emulator, ADB, Appium, and a persistent local bridge daemon.] <br>\n\n## Skill Version(s): <br>\n1.0.0 (source: server release metadata and artifact _meta.json) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>","readmeExcerpt":"Skill: Appium Android Adb Owner: openlittlebear Summary: Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A... Tags: android:1.0.0, appium:1.0.0, automation:1.0.0, latest:1.3.4, webview:1.0.0 Version history: v1.3.4 | 2026-08-30T08:56:32.847Z | user Review fixes: screenshots auto-purged after 1h, typed/pasted te","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears"},{"language":"python","snippet":"d.set_clipboard('苏州')          # uiautomator2 clipboard (works where fastinput fails)\nd.long_click(400, 330, duration=1.2)   # long-press the input field\n# → OCR: the 粘贴 (paste) menu item appears → tap it"},{"language":"bash","snippet":"$PY ocr_bridge.py a11y                 # all text nodes + bounds + [SELECTED] flag\n$PY ocr_bridge.py a11y-selected        # nodes with selected=\"true\" (spec chips)\n$PY ocr_bridge.py a11y-tap 直接免拼    # click text found in the a11y tree"},{"language":"bash","snippet":"# One-shot commands run with a short-lived session by default (safer):\npython3 bridge_daemon.py dump\npython3 bridge_daemon.py tap '{\"text\": \"查询车票\"}'\npython3 bridge_daemon.py scroll '{\"direction\": \"down\"}'\n\n# Persistent mode is opt-in — only if you need low-latency batches:\nbash ~/.openclaw/workspace/skills/appium-android-adb/start_bridge.sh\n# ...which runs: python3 bridge_daemon.py --daemon"},{"language":"bash","snippet":"python3 bridge_daemon.py dump"},{"language":"json","snippet":"{\n  \"ok\": true,\n  \"package\": \"com.MobileTicket\",\n  \"activity\": \"com.alipay.mobile.nebulacore.ui.H5Activity\",\n  \"title\": \"上海 <> 苏州\",\n  \"alerts\": [{\"text\": \"温馨提示\"}],\n  \"buttons\": [\n    {\"text\": \"查询车票\", \"id\": \"\", \"bounds\": \"[99,970][981,1102]\", \"x\": 540, \"y\": 1036},\n    {\"text\": \"预订\", \"id\": \"\", \"bounds\": \"[870,1988][1008,2075]\", \"x\": 939, \"y\": 2031}\n  ],\n  \"trains\": [\n    {\"text\": \"G 7 0 0 4次列车...\", \"bounds\": \"[66,1793][291,1919]\", \"clickable\": true, \"x\": 178, \"y\": 1856}\n  ],\n  \"webview_contexts\": [\"NATIVE_APP\"]\n}"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: appium-android-adb\ndescription: Read and control any Android app via Appium or uiautomator2. Primary backend (battle-proven on a real 12306 booking): direct uiautomator2 + RapidOCR via ocr_bridge.py (screenshot→OCR→click/swipe→verify loop). Appium bridge_daemon.py kept as fallback for native apps. For UC WebView (Alipay Nebula) apps like 12306, use the OCR loop for everything.\n---\n\n# Appium Android Bridge\n\nGeneric Android bridge for any app. Reads screens via OCR, executes taps/scrolling/typing. Two backends:\n\n| Backend | Status | Best for | Limitations |\n|---------|--------|----------|-------------|\n| **uiautomator2 + RapidOCR** (`ocr_bridge.py`) | ✅ **Primary** (proven end-to-end on 12306 booking 2026-08-30) | UC WebView apps, scrolling, booking buttons, Chinese input | Needs rapidocr_onnxruntime in a venv |\n| **Appium** (`bridge_daemon.py`) | ⚠️ Fallback | Native apps, structured dumps, `find`/`wait` | **Dead on many consumer devices**: Realme etc. block WRITE_SECURE_SETTINGS, so io.appium.settings and IME switching fail → session never starts |\n\n## ⚠️ Appium Failure Mode (hit this in production)\n\nOn a Realme RMX3350 the Appium path was unusable:\n- shell lacks `WRITE_SECURE_SETTINGS` → `io.appium.settings` commands fail\n- `d.set_input_ime()` blocked → fastinput IME can't be activated → `send_keys` fails\n- Result: Appium session creation error (\"settings command problem\"), bridge daemon useless\n\n**Rule: try the OCR loop FIRST. Only fall back to Appium if the app is fully native and OCR is insufficient.**\n\n## Quick Start (primary — OCR loop)\n\n```bash\n# One-time venv (Python 3.10+):\npython3 -m venv ~/.openclaw/workspace/.venv-12306\n~/.openclaw/workspace/.venv-12306/bin/pip install uiautomator2 rapidocr-onnxruntime opencv-python onnxruntime\n\n# Every interaction is one command:\nPY=~/.openclaw/workspace/.venv-12306/bin/python\n$PY ocr_bridge.py dump                     # OCR whole screen: (text, l, t, r, b)\n$PY ocr_bridge.py markers                  # page-state markers\n$PY ocr_bridge.py tap-text 预订 --idx 0     # click OCR match, then re-OCR verify\n$PY ocr_bridge.py tap 540 1987             # click exact coordinates\n$PY ocr_bridge.py swipe up --scale 0.35    # normal list scroll\n$PY ocr_bridge.py jump --n 3               # 3 rapid swipes (unstuck virtual list)\n$PY ocr_bridge.py wait-text 提交订单        # poll until text appears\n```\n\n`uiautomator2` auto-installs its atx-agent on the phone at first `connect()` — no Appium needed.\n\n## The Proven Loop\n\n1. `shot()`: `adb shell screencap -p /sdcard/s.png` → `adb pull` → RapidOCR → `[(text, l, t, r, b)]`\n2. Decide: page-state via `markers()`, position via `deps()` (HH:MM at x<250)\n3. Act: `d.click(cx, cy)` / `d.swipe_ext('up', scale=0.35)` / `d.swipe(x1,y1,x2,y2,duration=0.4)`\n4. **Always re-OCR after every action and verify the screen actually changed** — this is what makes the loop robust against the virtual list's lies.\n\n## Chinese Input (no IME needed)\n\nIME switching is blocked on locked-down dev"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7dtmyd3zhcg0k08a9fe0gdbn87e4cp\",\n  \"slug\": \"appium-android-adb\",\n  \"version\": \"1.3.4\",\n  \"publishedAt\": 1788080192847\n}"},{"path":"skill-card.md","content":"## Description:\n\nRead and control Android apps through OCR-driven uiautomator2 commands or a fallback Appium bridge.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[openlittlebear](https://clawhub.ai/user/openlittlebear)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and automation agents use this skill to inspect Android screens, identify UI text or accessibility nodes, and issue taps, swipes, waits, typing, screenshots, and Appium bridge commands for user-directed mobile app tasks.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can broadly control a connected Android device.\n\nMitigation: Use it only for explicit user-directed phone-control tasks, prefer one-shot commands, and require confirmation before irreversible actions such as orders or checkout steps.\n\nRisk: Screenshots and OCR output can include personal or sensitive screen data.\n\nMitigation: Use the private screenshot directory, clean screenshots after use, and rely on the documented automatic purge for captures older than one hour.\n\nRisk: Network exposure or persistent bridge behavior could expand the control surface.\n\nMitigation: Bind Appium to loopback, avoid relaxed-security flags, and prefer short-lived one-shot commands unless persistent mode is required.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/openlittlebear/skills/appium-android-adb)\n- [Publisher profile](https://clawhub.ai/user/openlittlebear)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands and JSON command results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands may read screen text, capture screenshots, and control a connected Android device when run by the agent.]\n\n## Skill Version(s):\n\n1.3.4 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A... Skill: Appium Android Adb Owner: openlittlebear Summary: Read and control any Android app via Appium or uiautomator2. Provides a persistent bridge daemon (bridge_daemon.py) with dump/tap/scroll/type/wait commands A... Tags: android:1.0.0, appium:1.0.0, automation:1.0.0, latest:1.3.4, webview:1.0.0 Version history: v1.3.4 | 2026-08-30T08:56:32.847Z | user Review fixes: screenshots auto-purged after 1h, typed/pasted te","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1253,"uniquenessScore":55,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:51:04.816Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:54:56.316Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}