# -*- coding: utf-8 -*- """让手表的连接错误提示说人话(尤其是证书问题)。 现在: describeNetworkError(IOException) 只认 ETIMEDOUT / ECONNREFUSED / ENETUNREACH 三种,其它原样把英文类名吐出来 —— 用户看到 "SSLHandshakeException: Chain validation failed" 完全不知道 该干嘛。 改后: 先交给 TlsCompat.explain()(它认得证书/时间/解析/超时等常见情况), 再补上"确认被控端在跑""确认同一个 WiFi"这些本场景专属的提示。 参数从 IOException 放宽到 Throwable —— 中转那边的异常可能是包过的。 """ from __future__ import annotations import sys from pathlib import Path MAIN = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\android\src" r"\com\lanremote\watch\MainActivity.java") OLD = ''' private String describeNetworkError(IOException e, String host) { String message = e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage(); if (message.contains("ETIMEDOUT") || message.contains("timed out")) { return "连接超时,检查电脑防火墙或 IP 是否正确"; } if (message.contains("ECONNREFUSED") || message.contains("refused")) { return "电脑拒绝连接,确认被控端程序正在运行"; } if (message.contains("ENETUNREACH") || message.contains("Network is unreachable")) { return "网络不可达,确认手表和电脑在同一个 WiFi"; } return message; }''' NEW = ''' /** * 把连接异常翻译成用户能看懂的话。 * *
手表上原本只会显示一长串英文类名(比如 * {@code SSLHandshakeException: Chain validation failed}), * 用户完全不知道该怎么办。这里按常见情况给出可操作的提示。 * *
证书类问题交给 {@link TlsCompat#explain} 判断 —— * 它会区分"证书链不认识""手表时间不对""被劫持"几种情况。 */ private String describeNetworkError(Throwable e, String host) { String raw = e == null ? "" : String.valueOf(e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage()); String lower = raw.toLowerCase(); // 证书 / 时间 / 解析 / 超时 等通用情况 String friendly = TlsCompat.explain(e); boolean generic = friendly != null && !friendly.equals(raw) && friendly.length() > 0; // TlsCompat 认不出来时会原样返回,那就继续往下走本场景的判断 boolean recognized = generic && ( friendly.contains("证书") || friendly.contains("时间") || friendly.contains("超时") || friendly.contains("解析") || friendly.contains("拒绝") || friendly.contains("联网") || friendly.contains("中断")); if (recognized) { return friendly; } if (lower.contains("etimedout") || lower.contains("timed out") || lower.contains("timeout")) { return "连接超时(网络慢或被防火墙挡了)"; } if (lower.contains("econnrefused") || lower.contains("refused")) { return "电脑拒绝连接 —— 确认电脑上 ykxmz 正在运行"; } if (lower.contains("enetunreach") || lower.contains("network is unreachable")) { return "网络不可达 —— 确认手表和电脑在同一个 WiFi"; } if (lower.contains("ehostunreach") || lower.contains("no route")) { return "找不到电脑 —— 检查 IP,或先用「局域网连接」搜一下"; } if (lower.contains("unable to resolve host") || lower.contains("unknownhost")) { return "域名解析不了 —— 检查手表能不能上网"; } // 中转那边的错误信息一般是中文的,直接透传 if (raw.length() > 120) { return raw.substring(0, 120); } return raw; }''' def main() -> int: text = MAIN.read_text(encoding="utf-8") if "TlsCompat.explain" in text: print(" 已经改过") return 0 if OLD not in text: print(" [失败] 锚点没找到") return 1 text = text.replace(OLD, NEW, 1) # 把 catch 放宽到 Exception,别漏掉包过的异常 old_catch = ''' } catch (final IOException e) { error = describeNetworkError(e, host); }''' new_catch = ''' } catch (final Exception e) { // 放宽到 Exception:中转那边的异常可能是包过的, // 只 catch IOException 会漏掉(甚至闪退)。 error = describeNetworkError(e, host); }''' if old_catch in text: text = text.replace(old_catch, new_catch, 1) print(" catch 从 IOException 放宽到 Exception") else: print(" [提示] catch 锚点没找到(可能已经在别处)") MAIN.write_text(text, encoding="utf-8", newline="\n") print(" describeNetworkError 已接上 TlsCompat.explain") return 0 if __name__ == "__main__": sys.exit(main())