# -*- coding: utf-8 -*- """手表端剩余改动(前面两条已应用,这里只做还没做的)。 每条都是严格的 4 元组:(文件, 原文, 新文, 说明)。 """ from __future__ import annotations import sys from pathlib import Path SRC = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\android\src" r"\com\lanremote\watch") MAIN = SRC / "MainActivity.java" FIXES = [ # 首页按钮:点它打开设备诊断(而不是让电脑弹窗口) (MAIN, """ selfCheck.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { requestPcSelfCheck(); } });""", """ selfCheck.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { openDiagPanel(); } });""", "首页按钮 → 打开设备诊断"), # 标签页里去掉「设备诊断」,换成电脑时间 (MAIN, """ act("设备诊断", new Runnable() { public void run() { openDiagPanel(); } }),""", """ act("电脑时间", new Runnable() { public void run() { sendCommand(Json.obj("cmd", "feature_run", "name", "world_clock", "params", Json.obj()), "电脑时间"); } }),""", "标签页去掉设备诊断"), # 显示电脑回传的结论 (MAIN, """ final String answer = Discovery.requestSelfCheck(MainActivity.this, 5000); runOnUiThread(new Runnable() { @Override public void run() { if (answer != null) { statusView.setText("电脑 " + answer + " 已打开网络自检"); toast("电脑 " + answer + " 已打开自检窗口"); appendLog("电脑 " + answer + " 已打开网络自检"); } else { statusView.setText("没收到电脑回应"); toast("没收到回应:广播可能也没通"); appendLog("自检请求无回应 —— 广播没到电脑"); } } });""", """ final String answer = Discovery.requestSelfCheck(MainActivity.this, 5000); runOnUiThread(new Runnable() { @Override public void run() { if (answer == null) { statusView.setText("没收到电脑回应"); toast("没收到回应:广播可能也没通"); appendLog("自检请求无回应 —— 广播没到电脑"); return; } // 电脑会把诊断结论一起回过来(它自己不弹窗口) String name = answer; String note = ""; int cut = answer.indexOf('\\n'); if (cut > 0) { name = answer.substring(0, cut); note = answer.substring(cut + 1); } if (note.length() == 0) { statusView.setText("电脑收到了请求,但没给结论"); toast("电脑收到了,但没给结论"); return; } appendLog("电脑 " + name + " 的结论:" + note); statusView.setText("电脑 " + name + " 的诊断结论已收到"); new AlertDialog.Builder(MainActivity.this) .setTitle("电脑的诊断结论") .setMessage(note) .setPositiveButton("知道了", null) .setNeutralButton("复制", new android.content.DialogInterface.OnClickListener() { public void onClick(android.content.DialogInterface d, int w) { copyToWatchClipboard(answer); toast("已复制"); } }) .show(); } });""", "显示电脑回传的结论"), # onCreate 装崩溃兜底 (MAIN, """ ui = new Handler(Looper.getMainLooper()); store = new DeviceStore(this); client = new RemoteClient();""", """ ui = new Handler(Looper.getMainLooper()); installCrashGuard(); store = new DeviceStore(this); client = new RemoteClient();""", "onCreate 装崩溃兜底"), # 兜底方法本体 (MAIN, " private void refreshDeviceList() {", """ /** * 兜底:任何线程抛出未捕获异常都不让它把整个 App 干掉。 * * 用户的要求是「不管干嘛,程序都要开着」—— * 后台线程一个 NPE 就闪退,看起来就像"程序自己关了"。 */ private void installCrashGuard() { Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, final Throwable error) { try { final String detail = String.valueOf(error); ui.post(new Runnable() { @Override public void run() { try { appendLog("已拦截内部错误:" + detail); toast("出了点小问题,程序继续运行"); } catch (Throwable ignored) { // 兜底里再出错就彻底放弃提示 } } }); } catch (Throwable ignored) { // 忽略 } // 故意不交给默认处理器:交给它系统就按崩溃处理了 } }); } private void refreshDeviceList() {""", "兜底方法本体"), ] def main() -> int: ok = True for path, old, new, tag in FIXES: text = path.read_text(encoding="utf-8") if old not in text: print(f" [跳过] {tag} —— 锚点没找到") ok = False continue path.write_text(text.replace(old, new, 1), encoding="utf-8") print(f" {tag}: OK") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())