#!/usr/bin/env python3 """ Termux API 测试 — 验证通知读取、剪贴板、电量等 API 可用性。 在 Ubuntu proot 或 Termux 环境内执行。 注意:Termux API 需要安装 Termux:API 应用(com.termux.api)。 """ import subprocess, json, sys, os REPORT = {"test": "termux_api", "steps": {}, "overall": None} def log_step(name, ok, detail=""): status = "[OK]" if ok else "[FAIL]" print(f" {status} {name}") if detail: print(f" {detail}") REPORT["steps"][name] = {"ok": ok, "detail": detail} return ok def run_termux_api(cmd_args, timeout=10): """Run a termux-api command via termux-api daemon.""" # termux-api commands are typically prefixed with `termux-` # They communicate with the Termux:API app via am broadcast internally termux_prefix = "/data/data/com.termux/files/usr/bin/" full_cmd = [termux_prefix + cmd_args[0]] + cmd_args[1:] try: r = subprocess.run(full_cmd, capture_output=True, text=True, timeout=timeout) return r.returncode == 0, r.stdout, r.stderr except Exception as e: return False, "", str(e) def start_termux_api_service(): """Start Termux:API background service if needed.""" try: subprocess.run( ["/system/bin/am", "startservice", "-n", "com.termux.api/.TermuxApiService"], capture_output=True, timeout=5 ) time.sleep(2) # Wait for service to start except Exception: pass def main(): print("=" * 60) print("Termux API 测试") print("=" * 60) all_ok = True # Step 0: Start Termux API service print("\n[Step 0] 启动 Termux:API 服务") start_termux_api_service() print(" [OK] TermuxApiService started") # Step 1: Check termux-api binary exists print("\n[Step 1] termux-api 命令可用性") termux_bin = "/data/data/com.termux/files/usr/bin/termux-notification-list" has_termux_api = os.path.exists(termux_bin) all_ok &= log_step("termux_api_binary", has_termux_api, f"found={has_termux_api} path={termux_bin}" if has_termux_api else "未找到 termux-api 命令") if not has_termux_api: print("\n [提示] 在 Termux 中安装:") print(" pkg install termux-api") print(" 并安装 Termux:API 应用 (F-Droid 或 GitHub)") save_report() return 1 # Step 2: Battery status print("\n[Step 2] 电量状态") ok, stdout, stderr = run_termux_api(["termux-battery-status"]) if ok: try: battery = json.loads(stdout) detail = f"{battery.get('percentage', '?')}% {battery.get('status', '?')}" except: detail = stdout[:100] else: detail = stderr[:100] all_ok &= log_step("battery_status", ok, detail) # Step 3: Notification list (check if we can read notifications) print("\n[Step 3] 通知列表读取") ok, stdout, stderr = run_termux_api(["termux-notification-list"]) wechat_notifs = [] if ok: try: notifs = json.loads(stdout) wechat_notifs = [n for n in notifs if n.get("pkgName") == "com.tencent.mm"] detail = f"总通知={len(notifs)} 微信通知={len(wechat_notifs)}" if wechat_notifs: for n in wechat_notifs[:3]: print(f" [微信通知] {n.get('title', '?')}: {n.get('content', '?')[:60]}") except Exception as e: detail = f"parse error: {e} raw={stdout[:100]}" else: detail = stderr[:100] # Notification list is optional - may be empty if no WeChat notifications currently all_ok &= log_step("notification_list", ok, detail) if ok and not wechat_notifs: print(" [INFO] 当前通知列表中无微信通知(请让朋友发一条消息后再测试)") # Step 4: Clipboard (optional) print("\n[Step 4] 剪贴板读写 (可选)") test_clip = f"hermes_test_{os.urandom(4).hex()}" ok1, _, err1 = run_termux_api(["termux-clipboard-set", test_clip]) ok2, stdout2, err2 = run_termux_api(["termux-clipboard-get"]) clip_ok = ok1 and ok2 and test_clip in stdout2 if clip_ok: log_step("clipboard", True, f"write={ok1} read={ok2} match={clip_ok}") else: log_step("clipboard", False, f"err={err1 or err2} (optional)") print(" [WARN] 剪贴板非核心功能,跳过") # Step 5: Send a test notification print("\n[Step 5] 发送测试通知") ok, stdout, stderr = run_termux_api([ "termux-notification", "--title", "Hermes WeChat Test", "--content", "Termux API 测试通过", "--priority", "low" ]) all_ok &= log_step("send_notification", ok, "sent test notification" if ok else stderr[:100]) # Summary REPORT["overall"] = "PASS" if all_ok else "FAIL" REPORT["timestamp"] = subprocess.check_output(["date", "-Iseconds"]).decode().strip() save_report() print("\n" + "=" * 60) print(f"结果: {REPORT['overall']}") print("=" * 60) print("\n详细报告: test_report_termux_api.json") return 0 if all_ok else 1 def save_report(): with open("test_report_termux_api.json", "w") as f: json.dump(REPORT, f, indent=2, ensure_ascii=False) if __name__ == "__main__": sys.exit(main())