# -*- coding: utf-8 -*- """手表端接上电脑功能注册表。 新增「功能」分页:显示 / 音量 / 系统 / 查看 / 效率 / 文件 六个分组, 点进去是这一组的功能列表,按 kind 决定怎么执行: toggle 直接切换 value 弹档位选择(亮度 10~100 分 5 档) input 弹输入框(有的要两个字段) action 直接执行;删除类先确认 """ 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") # ---- 1. 加一个「功能」分页 ---- TAB_OLD = ''' new TabDef("系统", new Act[]{''' TAB_NEW = ''' new TabDef("功能", new Act[]{ act("显示", new Runnable() { public void run() { pickFeatureGroup("显示"); } }), act("音量", new Runnable() { public void run() { pickFeatureGroup("音量"); } }), act("系统", new Runnable() { public void run() { pickFeatureGroup("系统"); } }), act("查看", new Runnable() { public void run() { pickFeatureGroup("查看"); } }), act("效率", new Runnable() { public void run() { pickFeatureGroup("效率"); } }), act("文件", new Runnable() { public void run() { pickFeatureGroup("文件"); } }), }), new TabDef("系统", new Act[]{''' # ---- 2. 方法 ---- ANCHOR = " private Button bigButton(String text, int color, float sizeSp) {" METHODS = ''' // ================================================================== // 电脑功能(由电脑端声明,这里只负责拉列表和调用) // ================================================================== private List> featureCache = null; /** 按分组列出电脑端的功能。 */ private void pickFeatureGroup(final String group) { appendLog("正在获取「" + group + "」功能…"); io.execute(new Runnable() { @Override public void run() { try { if (featureCache == null) { Map reply = client.call(Json.obj("cmd", "feature_list"), 20000); featureCache = mapList(reply, "features"); } final List> items = new ArrayList>(); List labels = new ArrayList(); for (Map item : featureCache) { if (!group.equals(Json.str(item, "group", ""))) { continue; } items.add(item); labels.add(Json.str(item, "label", "?")); } final List finalLabels = labels; ui.post(new Runnable() { @Override public void run() { if (finalLabels.isEmpty()) { toast("这一组暂时没有功能"); return; } showChooser("电脑功能 · " + group, finalLabels, new Chooser() { @Override public void onPick(int index) { dispatchFeature(items.get(index)); } }); } }); } catch (final IOException e) { featureCache = null; postError("获取功能列表", e); } } }); } /** 按功能类型决定怎么执行。 */ private void dispatchFeature(final Map feature) { final String name = Json.str(feature, "name", ""); final String label = Json.str(feature, "label", name); final String kind = Json.str(feature, "kind", "action"); if (name.isEmpty()) { toast("功能名不对"); return; } if ("toggle".equals(kind)) { boolean on = Json.bool(feature, "on", false); runFeature(name, Json.obj("on", !on), (on ? "关闭 " : "开启 ") + label); return; } if ("value".equals(kind)) { int min = Json.integer(feature, "min", 0); int max = Json.integer(feature, "max", 100); final List labels = new ArrayList(); final List values = new ArrayList(); for (int step = 1; step <= 5; step++) { int value = min + (max - min) * step / 5; values.add(value); labels.add(String.valueOf(value)); } showChooser(label, labels, new Chooser() { @Override public void onPick(int index) { runFeature(name, Json.obj("value", values.get(index)), label + " = " + values.get(index)); } }); return; } if ("input".equals(kind)) { String hint = Json.str(feature, "hint", "输入"); final String key = Json.str(feature, "key", "text"); String hint2 = Json.str(feature, "hint2", ""); final String key2 = Json.str(feature, "key2", ""); if (!key2.isEmpty() && !hint2.isEmpty()) { promptTwo(label, hint, hint2, new TwoHandler() { @Override public void onInput(String first, String second) { Map params = Json.obj(key, first); params.put(key2, second); runFeature(name, params, label); } }); return; } promptInput(label, hint, "", new InputHandler() { @Override public void onInput(String text) { if (!text.isEmpty()) { runFeature(name, Json.obj(key, text), label); } } }); return; } // action:删除类的先确认 if (name.startsWith("delete_") || name.equals("empty_recycle") || name.equals("clear_clip") || name.equals("restart_explorer")) { new AlertDialog.Builder(this) .setTitle(label) .setMessage("确定要执行「" + label + "」吗?") .setPositiveButton("执行", new android.content.DialogInterface.OnClickListener() { @Override public void onClick(android.content.DialogInterface d, int w) { runFeature(name, Json.obj(), label); } }) .setNegativeButton("取消", null) .show(); return; } runFeature(name, Json.obj(), label); } private void runFeature(final String name, final Map params, final String label) { appendLog("执行:" + label); io.execute(new Runnable() { @Override public void run() { try { Map request = Json.obj("cmd", "feature_run", "name", name); request.put("params", params); final Map reply = client.call(request, 30000); final boolean ok = Json.bool(reply, "ok", false); final String note = ok ? Json.str(reply, "note", "已执行") : Json.str(reply, "error", "执行失败"); ui.post(new Runnable() { @Override public void run() { appendLog(label + ":" + firstLine(note)); // 查看类的结果比较长,用对话框显示 if (note.length() > 40 || note.contains("\\n")) { new AlertDialog.Builder(MainActivity.this) .setTitle(label) .setMessage(note) .setPositiveButton("知道了", null) .show(); } else { toast(note); } } }); } catch (final IOException e) { postError(label, e); } } }); } private static String firstLine(String text) { int cut = text.indexOf('\\n'); return cut > 0 ? text.substring(0, cut) : text; } /** 两个输入框的对话框。 */ private interface TwoHandler { void onInput(String first, String second); } private void promptTwo(String title, String hint1, String hint2, final TwoHandler handler) { LinearLayout box = new LinearLayout(this); box.setOrientation(LinearLayout.VERTICAL); box.setPadding(dp(14), dp(8), dp(14), 0); final EditText first = new EditText(this); first.setHint(hint1); first.setSingleLine(true); box.addView(first); final EditText second = new EditText(this); second.setHint(hint2); second.setSingleLine(true); box.addView(second); new AlertDialog.Builder(this) .setTitle(title) .setView(box) .setPositiveButton("确定", new android.content.DialogInterface.OnClickListener() { @Override public void onClick(android.content.DialogInterface d, int w) { handler.onInput(first.getText().toString().trim(), second.getText().toString().trim()); } }) .setNegativeButton("取消", null) .show(); } /** 把回复里的对象数组取出来。 */ @SuppressWarnings("unchecked") private static List> mapList(Map reply, String key) { List> out = new ArrayList>(); try { Object raw = reply == null ? null : reply.get(key); if (raw instanceof List) { for (Object item : (List) raw) { if (item instanceof Map) { out.add((Map) item); } } } } catch (Exception ignored) { // 结构不对就返回空 } return out; } private Button bigButton(String text, int color, float sizeSp) {''' def main() -> int: text = MAIN.read_text(encoding="utf-8") ok = True for old, new, tag in ((TAB_OLD, TAB_NEW, "功能分页"), (ANCHOR, METHODS, "功能方法")): if old not in text: print(f" [失败] {tag} 锚点未匹配") ok = False else: text = text.replace(old, new, 1) print(f" {tag}: OK") if ok: MAIN.write_text(text, encoding="utf-8") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())