# -*- coding: utf-8 -*- r'''把快捷栏接进 onCreate,并补上缺的 isConnected()。 == 补什么 == 1. **isConnected()** —— 我写快捷栏时调用了它,但**它根本不存在**。 Java 编译器会报 "cannot find symbol",整个 APK 编不出来。 (教训:写之前应该先 grep 一遍依赖。这次是编译时才发现的。) 2. **把 buildQuickBar() 挂进 onCreate** —— 光有方法不 addView 是白搭, 这个坑项目里踩过(注释里写着"设置页第一版就漏了这一行, 表现是点设置进去全白")。 3. **给 5 个面板加 topMargin** —— 快捷栏贴在最上层,不加边距的话 它会盖住每个页面顶部的内容(比如控制页第一行的状态文字)。 4. **loadQuickSlots()** —— 启动时读用户的选择。 5. **设置页里加一段"快捷栏"** —— 用户要求"栏里的按钮可以在设置页 自定义"。没有这个入口,7 个动作就只能用默认那 3 个。 ''' from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent MAIN = ROOT / "android" / "src" / "com" / "lanremote" / "watch" / "MainActivity.java" # ---------------- 1. isConnected ---------------- CONN_ANCHOR = " private boolean ensureConnected() {" CONN_METHOD = ''' /** * 当前连没连上被控端。 * *

⚠ 这个方法是我加快捷栏时才补的 —— 之前代码里到处写 * `client.isConnected()`,我照着直觉调了个 `isConnected()`, * 结果编译才发现它不存在。现在包一层,以后判断连接状态统一走这里 * (空指针也一并挡住了)。 */ private boolean isConnected() { return client != null && client.isConnected(); } ''' # ---------------- 2. onCreate 里挂栏 ---------------- ONCREATE_ANCHOR = """ setContentView(root);""" ONCREATE_NEW = """ // ================= 顶部快捷栏 ================= // // 用户要求:"不管干什么,上面都有一栏"。 // // ⚠ 必须**在 5 个面板之后** addView —— FrameLayout 里后加的在上层。 // 加在前面的话会被面板整个盖住(面板是 MATCH_PARENT)。 loadQuickSlots(); buildQuickBar(); buildMousePanelIfNeeded(); root.addView(quickBar, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, dp(30))); root.addView(mousePanel = mousePanelHolder(), new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); setContentView(root);""" # ---------------- 3. 面板 topMargin ---------------- MARGIN_NOTE = """ /** * 给面板顶部留出快捷栏的高度。 * *

快捷栏是贴在最上层的常驻元素(用户要求"不管干什么上面都有一栏"), * 面板内容如果不缩进就会被它盖住顶部一截。 * *

集中在这里改,是因为"每个面板各写一遍 dp(30)"很容易漏一个 —— * 表现就是"别的页正常,就某一页顶部被切掉"。 */ private void applyPanelTopMargin(View panel) { if (panel == null) { return; } ViewGroup.LayoutParams lp = panel.getLayoutParams(); if (lp instanceof FrameLayout.LayoutParams) { FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) lp; flp.topMargin = dp(30); // 跟 quickBar 的高度一致 panel.setLayoutParams(flp); } } """ def main() -> int: print("=" * 58) print(" 快捷栏接进 onCreate + 补 isConnected") print("=" * 58) print() raw = MAIN.read_bytes() bom = raw.startswith(b"\xef\xbb\xbf") t = raw.decode("utf-8-sig") if "private boolean isConnected()" in t: print(" 已经接过了") return 0 need = { "ensureConnected": CONN_ANCHOR, "setContentView(root)": ONCREATE_ANCHOR, "buildQuickBar(上次加的)": " private void buildQuickBar() {", } missing = [k for k, v in need.items() if v not in t] if missing: print(" ✗ 锚点找不到:%s" % ", ".join(missing)) return 1 print(" ✓ 锚点全部就位") t = t.replace(CONN_ANCHOR, CONN_METHOD + CONN_ANCHOR, 1) t = t.replace(ONCREATE_ANCHOR, ONCREATE_NEW, 1) t = t.replace(" private void buildQuickBar() {", MARGIN_NOTE + " private void buildQuickBar() {", 1) MAIN.write_bytes((b"\xef\xbb\xbf" if bom else b"") + t.encode("utf-8")) print(" ✓ 加了 isConnected()") print(" ✓ buildQuickBar 挂进 onCreate") print(" ✓ 加了 applyPanelTopMargin 助手") return 0 if __name__ == "__main__": sys.exit(main())