上次,我描述了如何编写一个简单的 Android 应用,并让它在 Linux 上与你的代码交互。所以,当然,我们需要一个例子。由于我最近对宏键盘(macropad)有点着迷,所以我决定编写一个工具包,让你可以使用 App Inventor 和任何你喜欢的 Linux 工具来构建自己的宏键盘。
我提到过有一个服务器。我写了一些非常基本的代码来在 Linux 端与 Android 设备交换数据。协议很简单:
- 所有发送给普通 Linux 的消息都以 > 开头
- 发送到 Android 设备的所有消息都以 < 开头
- 所有消息都以回车符结尾
安全
您可以构建服务器,使其能够执行任意命令。由于某些人肯定会对此感到不满,因此服务器也可以包含一组受限制的编号命令。您也可以允许或禁止这些命令接受参数,但您必须使用您设置的选项重新构建服务器。
通信开始时会进行握手,Android 发送“>.”,服务器响应“<.”,以允许同步和重置操作。发送“>#x”会运行一个带编号的命令(其中 x 为整数),该命令可以带有参数,例如“>#20~/todo.txt”;或者,如果您只想运行命令,则不带参数,发送“>#20”。
如果服务器允许,您也可以使用“>>”发送整个命令行,如:“>>vi ~/todo.txt”来启动 vi 会话。
顶嘴
有时您需要服务器发送一些数据,例如音频静音状态或当前 CPU 温度。您可以使用带编号的命令来实现,但发送数据时请使用“>?”而不是“>#”。服务器将以“<!”作为响应,后跟命令输出的第一行文本。
要定义编号命令,您需要创建一个格式简单的commands.txt
文件。您还可以设置最大编号,超过该编号的任何命令都只会调用服务器,您可以拦截这些命令,并使用自定义的 C 代码进行处理。因此,使用编号较低的命令,您可以使用 bash、Python 甚至单独的 C 程序完成所有操作。使用编号较高的命令,您可以将更高效的命令直接添加到服务器中,如果您不介意用 C 语言编写,这比调用外部程序更高效。
如果您不想编写程序,xdotool、wmctrl 和 dbus-send(或 qdbus)之类的工具可以完成您希望宏键盘完成的大部分功能。您可以将它们插入命令文件或启动 Shell 脚本。您将在示例代码中看到更多相关信息。
现在剩下的就是创建 App Inventor 界面。
一个不那么简单的样本
App Inventor 的设计初衷是创建简单的应用。但由于一些原因,这款应用最终并没有那么简单。最初的想法是,宏面板应该有一个配置对话框和任意数量的屏幕,你可以在其中放置按钮、滑块或其他任何与服务器交互的东西。
第一个问题绝对是使用 App Inventor 的一个怪癖。它允许你拥有多个屏幕,并且你的程序可以在各个屏幕之间移动。问题是,当你切换屏幕时,一切都会改变。所以如果我们使用多个屏幕,你就必须拥有蓝牙客户端、计时器以及其他任何“全局”组件(例如工具栏按钮及其代码)的副本。
这似乎不是一个好主意。相反,我构建了一个简单的系统,只有一个屏幕,其中包含一个工具栏和一个用于表格布局的区域。最初,除了一个布局外,其他所有布局都是隐藏的。当您浏览屏幕时,活动的布局会隐藏,新的布局会显示出来。
听起来不错,但在实际操作中却存在一个严重的问题。当布局可见时,它们并不总是能正确地重新计算大小,而且也没有简洁的方法强制重复布局。这导致在页面之间切换时出现问题。例如,某些按钮的文本会偏离中心,即使在编辑器中看起来正常。
另一个问题是编辑特定页面。设计器中有一个按钮可以显示隐藏的内容。但是,当隐藏的内容很多时,这个按钮就没什么用了。实际上,我通常会隐藏默认布局,然后取消隐藏我想要处理的布局,最后尽量在完成之前记得把内容放回去。如果忘记了,代码会在启动时自动隐藏除活动页面之外的所有内容。
只是浏览
我还添加了一些网页浏览器页面(方便您在工作时查看 Hackaday 或收听 Soma FM)。当浏览器可见时,它会自行设定为 1 像素宽和 1 像素高,这不太实用。为了实现这个功能,我尝试了很多次让内容可见、不可见,然后再重新可见。在某些情况下,计时器会稍微改变字体大小之类的设置,然后在所有内容可见后再改回原值以触发重新计算。
说到浏览器,我不想使用多个包含 Web 浏览器组件的页面,所以系统允许你在列表中多次指定同一个“页面”。页面可以有多个标题,具体取决于其位置,你也可以根据其位置对其进行不同的初始化。相比于如何正确绘制,这相当简单。
其他问题
您可能会认为 500 个块是任何人都愚蠢到能编写的最大的 App Inventor 程序……
还出现了一些其他问题,其中一些不是 Inventor 的错。例如,所有手机都不一样,所以你的程序会根据手机调整大小,这让它很难运行。我只能告诉正在为显示器构建的界面,然后让手机调整大小。我找不到设置自定义屏幕尺寸的方法。
布局控件相当简陋,这也很正常。这应该只是一个简单的工具。例如,它没有空格或内边距,但一些固定大小的小标签就能满足需求。而且,也没有合理的方法让一个元素在布局中跨越多个单元格,这会导致大量的深度嵌套布局。
App Inventor 中的蓝牙超时设置似乎也有点奇怪。有时即使设置了超长的超时时间也会超时。我把它保留在代码中,但如果你把它改成零以外的值,那就祝你好运了。
它是如何工作的?
这可能是你用 App Inventor 能做到的最复杂的事情了。它的块结构非常庞大,不过平心而论,其中很多只是按下按钮时发出的命令。示例板有近 500 个块。我自己手机上使用的个性化版本(见下方视频)有 900 多个块!
当然,这款工具并非为如此规模而设计的,所以请做好应对一些开发问题的准备。超过一定时间后,调试功能将无法正常工作。您只能构建一个 APK,加载它,然后祈祷好运。
您可以在GitHub上找到该演示。我的版本是定制的,可以链接到我的电脑,屏幕尺寸与我的完全相同,并且使用了大量本地脚本,所以我没有将其包含在内,但您可以在下面的视频中看到它的运行情况。
如果你想回顾并进一步了解服务器机制,请参阅上一篇文章。或者,如果你想将旧手机改造成服务器,我们也见过类似的案例。
原文: https://hackaday.com/2025/09/09/the-android-linux-commander/