一、问题引发

本来想给自家的智能电视做个 APP,但家里人要看电视,我又没有电脑,全靠 AIDE 在手机上敲代码,运行测试也是。看来踏入 TV 开发的第一步都有困难。而电视与手机的最大区别在于电视用遥控器操作,不能触屏,而手机可以触屏。于是我想到了 Auto.js,可以用它写一个遥控器浮窗脚本,在手机上模拟遥控器操作,如此模拟电视环境运行 APP。

二、初步尝试

由于安卓虚拟机的 Android TV 和 Google 官方的电视棒的遥控器与国内的有极大不同,没有 0-9 数字键,只有开关、方向键、OK 键,所以我只要做一个方向键盘就行了。参考了 Auto.js 给出用例脚本和之前的一个脚本,我写出了初始代码:

var window = floaty.window(
<vertical>
    <text id="text" text="ADJUST" textSize="16sp"/>
    <relative layout_width="match_parent" layout_height="match_parent">
        <button
        id="ok"
        text="OK"
        layout_width="48dp"
        layout_centerInParent="true"/>
        <button id="left"
        text="左"
        layout_toLeftOf="ok"
        layout_width="48dp"
        layout_centerVertical="true"/>
        <button id="right"
        text="右"
        layout_toRightOf="ok"
        layout_width="48dp"
        layout_centerVertical="true"/>
        <button id="up"
        text="上"
        layout_above="ok"
        layout_width="48dp"
        layout_centerHorizontal="true"/>
        <button id="down"
        text="下"
        layout_below="ok"
        layout_width="48dp"
        layout_centerHorizontal="true"/>
    </relative>
    </vertical>
);

window.exitOnClose();

window.text.click(()=>{
    window.setAdjustEnabled(!window.isAdjustEnabled());
});

window.ok.click(()=>{
    KeyCode(23);
});
window.left.click(()=>{
    KeyCode(21);
});

window.right.click(()=>{
    KeyCode(22);
});

window.up.click(()=>{
    KeyCode(19);
});

window.down.click(()=>{
    KeyCode(20);
});
setInterval(()=>{}, 1000);

此处参阅 Auto.js 文档中 KeyCode 的用法:

KeyCode(code)

  • code <number> | 要按下的按键的数字代码或名称。参见下表。 模拟物理按键。例如KeyCode(29)KeyCode("KEYCODE_A")是按下A键。

查阅键表,找到需要的方向键及键值:

名称代码
KEYCODE_DPAD_UP19
KEYCODE_DPAD_DOWN20
KEYCODE_DPAD_LEFT21
KEYCODE_DPAD_RIGHT22
KEYCODE_DPAD_CENTER23

初步测试。。。失败

三、再次尝试

KeyCode(code) 是需要 root 权限的,我有 root,但不论怎么办,都运行失败。于是我想到了可以用 shell() 函数调用 input keyevent <code> 来模拟按键。当然这也需要 root。
而参考文档:

shell(cmd[, root])

  • cmd <string> 要执行的命令
  • root <Boolean> 是否以root权限运行,默认为false。

将所有 KeyCode(code) 换成 shell("input keyevent <code>",true),再次测试。。。失败

四、调用 Java

我发现两次的日志很像,应该是同一个原因,可能 KeyCode(code) 就是对 shell("input keyevent <code>",true) 的一个封装吧。
毕竟 Auto.js 还可以调用 Java,所以改用 Java 的 java.lang.Runtime 来调用 Shell。
最后修改了一下,在原代码之前加了一些:

importClass("java.lang.Runtime");

function key(c){
    try{
        Runtime.getRuntime().exec(["/system/xbin/su","-c","input keyevent "+c]);
    }catch(e){
    }
}

然后把所有 shell() 函数换成 key(),再次测试。。。成功
效果图:
运行结果
果然,Java 才是王道。

五、附加

文件源码:遥控器.js
Auto.js 文档:https://pro.autojs.org/docs/

声明:未经作者允许禁止转载。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐